genmonarch

package
v3.24.89 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package genmonarch builds Monaco language definitions for the expression languages gomplate runs, from the grammars and registries gomplate itself uses -- so the editor cannot drift from the evaluator.

Index

Constants

View Source
const CELLanguageID = "cel"

CELLanguageID is the Monaco language id for CEL expressions.

View Source
const GoTemplateLanguageID = "gomplate"

GoTemplateLanguageID is the Monaco language id for a bare gomplate template.

View Source
const JSONPathLanguageID = "jsonpath"

JSONPathLanguageID is the Monaco language id for JSONPath expressions.

Variables

This section is empty.

Functions

func BuildCEL

func BuildCEL(g *grammar.CELGrammar, spec CELSpec) (Language, Configuration)

BuildCEL assembles the CEL tokenizer from the lexical grammar and the live function catalogue.

func BuildEmbedded

func BuildEmbedded(h Host, spec GoTemplateSpec, d Delimiters) (Language, Configuration, error)

BuildEmbedded assembles a host language whose every state can open a template action.

Monarch cannot delegate to another *registered* language mid-state, so the host tokenizer is inlined here rather than composed at runtime. It is deliberately light: enough structure to read a config file, with the template actions -- the part gomplate owns -- fully tokenized by the shared states.

func BuildGoTemplate

func BuildGoTemplate(spec GoTemplateSpec, d Delimiters) (Language, Configuration, error)

BuildGoTemplate assembles the bare gomplate language: literal text with `{{ ... }}` actions embedded in it.

func BuildJSONPath

func BuildJSONPath() (Language, Configuration)

BuildJSONPath assembles the JSONPath tokenizer.

func EmbeddedLanguageID

func EmbeddedLanguageID(h Host) string

EmbeddedLanguageID is the Monaco language id for a host with templates in it.

func Render

func Render(b *Bundle) (map[string][]byte, error)

Render turns a bundle into the files the npm package ships, keyed by filename. JSON is indented and newline-terminated so a regenerated tree produces a reviewable diff.

func ValidateCorpus

func ValidateCorpus(cases []ConformanceCase) error

ValidateCorpus parses every non-CEL snippet with the parser that actually evaluates it, so the corpus cannot drift into asserting behaviour for input gomplate would reject.

CEL snippets are validated as they are built: celTokenBoundaries fails on any lexical error.

Types

type Action

type Action struct {
	// Token is the single token class to emit.
	Token string
	// Tokens is one token class per capture group; mutually exclusive with Token.
	Tokens []string
	// Next is the state to enter: a state name, `@pop`, or `@push`.
	Next string
	// Cases selects between actions by testing the match against word lists.
	Cases *Cases
}

Action is what a rule does when its pattern matches.

func (Action) MarshalJSON

func (a Action) MarshalJSON() ([]byte, error)

type Bracket

type Bracket struct {
	Open  string `json:"open"`
	Close string `json:"close"`
	Token string `json:"token"`
}

Bracket is a bracket pair Monaco should match and colour.

type Bundle

type Bundle struct {
	Spec           Spec
	Languages      map[string]Language
	Configurations map[string]Configuration
	Conformance    []ConformanceCase
	// Order lists the language ids deterministically, for stable file output.
	Order []string
}

Bundle is everything the npm package ships: one Monarch definition and one language configuration per language id, plus the shared function catalogue and the conformance corpus.

func Build

func Build(docs map[string]string, extraCEL ...cel.EnvOption) (*Bundle, error)

Build assembles every language from gomplate's own grammars and registries. docs supplies the Markdown references the conformance corpus draws snippets from, keyed by filename. extraCEL layers a host's own CEL options in, so a binary that registers extra functions can generate a bundle that knows them.

type CELSpec

type CELSpec struct {
	// Namespaces are the dotted prefixes in use: k8s, math, time, ...
	Namespaces []string `json:"namespaces"`
	// Keywords are CEL's reserved words.
	Keywords []string `json:"keywords"`
	// Types are the built-in type names usable as identifiers.
	Types []string `json:"types"`
	// Variables are the identifiers the base environment declares.
	Variables []string   `json:"variables,omitempty"`
	Macros    []Macro    `json:"macros"`
	Functions []Function `json:"functions"`
}

CELSpec is the CEL surface, read from a live cel.Env.

func ExtractCEL

func ExtractCEL(extra ...cel.EnvOption) (CELSpec, error)

ExtractCEL reads the CEL surface out of a live environment built from the same options RunExpression compiles against, so the catalogue is whatever gomplate actually registers -- not a list maintained alongside it.

extra layers a caller's own options on top. Because this reads a live cel.Env rather than a maintained list, a host that registers `cel.Function("catalog.query", cel.Overload(...))` gets it back here with its typed overloads, and the editor can highlight and complete it without any change to the grammar.

func (CELSpec) GlobalNames

func (s CELSpec) GlobalNames() []string

GlobalNames returns the names callable in global position, namespace included.

func (CELSpec) MemberNames

func (s CELSpec) MemberNames() []string

MemberNames returns the names callable only in member position.

type Cases

type Cases struct {
	// contains filtered or unexported fields
}

Cases is an ordered set of guarded actions. Monarch evaluates the guards in order, so `@default` belongs last and a more specific guard must precede a broader one.

func NewCases

func NewCases() *Cases

NewCases returns an empty, ordered case set.

func (*Cases) Default

func (c *Cases) Default(action Action) *Cases

Default appends the fallback, which must be added last.

func (*Cases) Groups

func (c *Cases) Groups(guard string, tokens ...string) *Cases

Groups appends a guard emitting one token class per capture group.

func (*Cases) MarshalJSON

func (c *Cases) MarshalJSON() ([]byte, error)

func (*Cases) Token

func (c *Cases) Token(guard, token string) *Cases

Token appends a guard emitting a single token class.

func (*Cases) When

func (c *Cases) When(guard string, action Action) *Cases

When appends a guard, e.g. `@keywords` or `$1@namespaces`.

type Comments

type Comments struct {
	LineComment  string    `json:"lineComment,omitempty"`
	BlockComment [2]string `json:"blockComment,omitempty"`
}

Comments declares how comments are written.

type Configuration

type Configuration struct {
	Comments         *Comments   `json:"comments,omitempty"`
	Brackets         [][2]string `json:"brackets,omitempty"`
	AutoClosingPairs []Pair      `json:"autoClosingPairs,omitempty"`
	SurroundingPairs []Pair      `json:"surroundingPairs,omitempty"`
	// WordPattern decides what counts as one word for completion. Dotted names
	// such as `k8s.isHealthy` must match as a single word or completing them
	// inserts a duplicated namespace.
	WordPattern string `json:"wordPattern,omitempty"`
}

Configuration is a Monaco language configuration: the editor behaviours that are not tokenization.

type ConformanceCase

type ConformanceCase struct {
	Language string `json:"language"`
	Source   string `json:"source"`
	// Boundaries are 0-based offsets where a token starts, excluding
	// whitespace, in ascending order.
	Boundaries []int `json:"boundaries"`
	// Origin records where the snippet came from, so a failure is traceable.
	Origin string `json:"origin"`
}

ConformanceCase is one snippet with the token boundaries the language's real lexer produces.

The generator sits next to the parsers gomplate evaluates with, so it can produce the oracle rather than a snapshot of the tokenizer's own output. The browser test replays these through Monaco and asserts the boundaries agree.

Boundaries, not token classes: Monarch says `namespace` and `function` where the lexer only says IDENTIFIER, so the classes are not comparable. The boundaries are, and they are where the subtle bugs live -- a triple-quoted string cut short, `0x1f` truncated to `0`, `123u` split into a number and an identifier.

func BuildConformance

func BuildConformance(docs map[string]string) ([]ConformanceCase, error)

BuildConformance assembles the corpus. docs maps a filename to its contents; the caller reads them so this stays testable without touching the disk.

type Delimiters

type Delimiters struct {
	Left  string `json:"left"`
	Right string `json:"right"`
	// LeftComment and RightComment open and close a comment *inside* an action.
	LeftComment  string `json:"leftComment"`
	RightComment string `json:"rightComment"`
	// TrimMarker abuts a delimiter to trim surrounding whitespace.
	TrimMarker string `json:"trimMarker"`
}

Delimiters is an action-delimiter pair.

type Function

type Function struct {
	Name      string `json:"name"`
	Namespace string `json:"namespace,omitempty"`
	// MemberOnly marks a function callable only as `x.f()`, never as `f(x)`.
	// The tokenizer uses this to colour `x.sum()` without colouring a bare
	// `sum`, which in CEL is just an identifier.
	MemberOnly bool   `json:"memberOnly,omitempty"`
	Doc        string `json:"doc,omitempty"`
	// Signature is the Go signature, for go-template functions.
	Signature string     `json:"signature,omitempty"`
	Overloads []Overload `json:"overloads,omitempty"`
	Examples  []string   `json:"examples,omitempty"`
}

Function is one callable name, with every registered overload.

type GoTemplateSpec

type GoTemplateSpec struct {
	// Namespaces are the dotted prefixes: strings, coll, conv, ...
	Namespaces []string `json:"namespaces"`
	// Keywords are text/template's action keywords.
	Keywords []string `json:"keywords"`
	// Builtins are the functions text/template provides itself.
	Builtins []string `json:"builtins"`
	// Delimiters are text/template's defaults.
	Delimiters Delimiters `json:"delimiters"`
	Functions  []Function `json:"functions"`
}

GoTemplateSpec is the Go text/template surface.

func ExtractGoTemplate

func ExtractGoTemplate() (GoTemplateSpec, error)

ExtractGoTemplate reads the go-template surface from the FuncMap gomplate actually installs, plus the vocabulary of text/template itself.

Namespaces are registered as a zero-argument function returning a shared `*XFuncs` value (`f["strings"] = func() any { return ns }`), so the namespaced names are the exported methods of whatever that call returns.

type Host

type Host string

Host is a language that gomplate templates are embedded in. Real Mission Control configuration is YAML with `{{ }}` actions inside it, and neither half is readable when the editor only understands the other.

const (
	HostYAML Host = "yaml"
	HostJSON Host = "json"
	HostText Host = "text"
)

type Language

type Language struct {
	ID           string    `json:"-"`
	DefaultToken string    `json:"defaultToken"`
	TokenPostfix string    `json:"tokenPostfix"`
	Start        string    `json:"start,omitempty"`
	Brackets     []Bracket `json:"brackets,omitempty"`
	// Attributes are the named word lists a rule refers to as `@name`. Order
	// within a list is irrelevant; the lists are sorted for a stable diff.
	Attributes map[string][]string `json:"-"`
	// Tokenizer holds the states. `root` is the entry state.
	Tokenizer *States `json:"tokenizer"`
}

Language is a Monaco Monarch language definition. It marshals to the shape monaco.languages.setMonarchTokensProvider expects.

func (Language) MarshalJSON

func (l Language) MarshalJSON() ([]byte, error)

MarshalJSON flattens Attributes alongside the fixed fields, which is how Monarch expects word lists to appear.

type Macro

type Macro struct {
	Name          string   `json:"name"`
	ArgCount      int      `json:"argCount"`
	ReceiverStyle bool     `json:"receiverStyle"`
	Doc           string   `json:"doc,omitempty"`
	Examples      []string `json:"examples,omitempty"`
}

Macro is a CEL macro -- expanded at parse time, so it is never a Function.

type Overload

type Overload struct {
	ID     string   `json:"id"`
	Args   []string `json:"args"`
	Result string   `json:"result"`
	Member bool     `json:"member,omitempty"`
}

Overload is one typed signature of a CEL function.

type Pair

type Pair struct {
	Open  string `json:"open"`
	Close string `json:"close"`
}

Pair is a pair of strings the editor closes or surrounds a selection with.

type Rule

type Rule struct {
	// Regex is JS regex source, without delimiters.
	Regex string
	// Action fires when Regex matches.
	Action Action
	// Include names a state to splice in, e.g. `@whitespace`. When set, the
	// rest of the rule is ignored.
	Include string
}

Rule is one tokenizer rule: a pattern with an action, or an include of another state.

func Include

func Include(state string) Rule

Include splices another state's rules in at this position.

func Match

func Match(regex, token string) Rule

Match builds a rule that emits a single token.

func MatchGroups

func MatchGroups(regex string, tokens ...string) Rule

MatchGroups builds a rule that emits one token per capture group.

func Pop

func Pop(regex, token string) Rule

Pop builds a rule that emits a token and returns to the previous state.

func Push

func Push(regex, token, next string) Rule

Push builds a rule that emits a token and enters another state.

func (Rule) MarshalJSON

func (r Rule) MarshalJSON() ([]byte, error)

type Spec

type Spec struct {
	CEL        CELSpec        `json:"cel"`
	GoTemplate GoTemplateSpec `json:"gotemplate"`
}

Spec is the machine-readable catalogue of everything gomplate exposes to an author. It drives the generated tokenizers, the completion and hover providers, and the playground's function browser.

type States

type States struct {
	// contains filtered or unexported fields
}

States is an ordered set of tokenizer states. Both the state order and the rule order inside a state are significant: Monarch takes the first rule that matches, so a shorter pattern declared first silently shadows a longer one.

func NewStates

func NewStates() *States

NewStates returns an empty, ordered state set.

func (*States) Add

func (s *States) Add(name string, rules ...Rule) *States

Add appends a state. Adding the same name twice appends to it.

func (*States) MarshalJSON

func (s *States) MarshalJSON() ([]byte, error)

func (*States) Names

func (s *States) Names() []string

Names lists the states in declaration order.

func (*States) Rules

func (s *States) Rules(name string) []Rule

Rules returns the rules of a state.

Directories

Path Synopsis
Package grammar extracts lexical vocabulary from the grammars of the parsers gomplate actually runs, so the editor tokenizers stay in step with them instead of being transcribed by hand.
Package grammar extracts lexical vocabulary from the grammars of the parsers gomplate actually runs, so the editor tokenizers stay in step with them instead of being transcribed by hand.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL