ast

package
v0.14.2-0...-cd7c3c1 Latest Latest
Warning

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

Go to latest
Published: Jun 5, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package ast is a high-performance implementation of a Protobuf IDL abstract syntax tree. It is intended to be end-all, be-all AST for the following use-cases:

1. Parse target for a Protobuf compiler.

2. Incremental, fault-tolerant parsing for a Protobuf language server.

3. In-place rewriting of the AST to implement refactoring tools.

4. Formatting, even of partially-invalid code.

"High-performance" means that the AST is optimized to minimize resident memory use, pointer nesting (to minimize GC pause contribution), and maximize locality. This AST is suitable for hydrating large Buf modules in a long-lived process without exhausting memory or introducing unreasonable GC latency.

In general, if an API tradeoff is necessary for satisfying any of the above goals, we make the tradeoff, but we attempt to maintain a high degree of ease of use.

Node Types

Most types in this package represent AST nodes of some kind. Each such type contains a grammar for the lenient extension of the Protobuf grammar that it represents. The grammar is notated using regular expression syntax, with the following modifications:

  1. Whitespace is ignored.
  2. Literal strings (except in character classes) are represented with Go strings.
  3. Unquoted names refer to other productions.

Productions that represent a type from this package, a token.Kind, or a production used by a different type, are in PascalCase; all other productions are in camelCase and are scoped to that type.

The parser (and other parts of the compiler) will diagnose invalid Protobuf syntax, but this AST is able to represent the extended syntax it documents.

These grammars are provided for illustration only: the complete grammar is ambiguous in the absence of greediness decisions, which, except where otherwise noted, neither affect the parsing of correct Protobuf files, nor are they specified and are subject to change.

AST Context

Virtually all operations in this package involve a [Context] (no, not a context.Context). This struct acts as an arena that enables the highly compressed, memory-friendly representation this package uses for the AST.

Using a [Context], you can create new tokens and new AST nodes. Types that represent AST nodes, such as [DeclMessage], are thin wrappers over a pointer to a [Context] and index into one of its tables. They are intended to be passed by value, because they are essentially pointers (and, in fact, expose a IsZero function for checking if they refer to a nil Context pointer).

Pointer-like Types

Virtually all AST nodes in this library are "pointer-like" types, in that although they are not Go pointers, they do refer to something stored in a [Context] somewhere. Internally, they contain a pointer to a [Context] and a pointer to the compressed node representation inside the [Context]. This is done so that we can avoid spending an extra eight or twelve bytes per node-at-rest, and to minimize GC churn by avoiding pointer cycles in the in-memory representation of the AST.

All pointer-like types have a bool-returning IsZero method, which checks for the zero value. Pointer-like types should generally be passed by value, not by pointer; all of them have value receivers.

In some places, the zero value of a pointer-like type is (incorrectly) referred to as nil. This is a documentation bug; instead, it should say zero.

Coming Soon

This library will replace the existing github.com/bufbuild/protocompile/ast library. Outside of this file, documentation is written assuming this has already happened.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Commas

type Commas[T any] interface {
	seq.Inserter[T]

	// Comma is like [seq.Indexer.At] but returns the comma that follows the nth
	// element.
	//
	// May be [token.Zero], either because it's the last element
	// (a common situation where there is no comma) or it was added with
	// Insert() rather than InsertComma().
	Comma(n int) token.Token

	// AppendComma is like [seq.Append], but includes an explicit comma.
	AppendComma(value T, comma token.Token)

	// InsertComma is like [seq.Inserter.Insert], but includes an explicit comma.
	InsertComma(n int, value T, comma token.Token)

	// SetComma sets the comma that follows the nth element.
	SetComma(n int, comma token.Token)
}

Commas is like [Slice], but it's for a comma-delimited list of some kind.

This makes it easy to work with the list as though it's a slice, while also allowing access to the commas.

type CompactOptions

type CompactOptions id.Node[CompactOptions, *File, *rawCompactOptions]

CompactOptions represents the collection of options attached to a DeclAny, contained within square brackets.

Grammar

CompactOptions := `[` (option `,`?)? `]`
option         := Path [:=]? Expr?

func (CompactOptions) Brackets

func (o CompactOptions) Brackets() token.Token

Brackets returns the token tree corresponding to the whole [...].

func (CompactOptions) Entries

func (o CompactOptions) Entries() Commas[Option]

Entries returns the sequence of options in this CompactOptions.

func (CompactOptions) Span

func (o CompactOptions) Span() source.Span

Span implements source.Spanner.

type DeclAny

type DeclAny id.DynNode[DeclAny, DeclKind, *File]

DeclAny is any Decl* type in this package.

Values of this type can be obtained by calling an AsAny method on a Decl* type, such as DeclSyntax.AsAny. It can be type-asserted back to any of the concrete Decl* types using its own As* methods.

This type is used in lieu of a putative Decl interface type to avoid heap allocations in functions that would return one of many different Decl* types.

Grammar

DeclAny := DeclEmpty | DeclSyntax | DeclPackage | DeclImport | DeclDef | DeclBody | DeclRange

Note that this grammar is highly ambiguous. TODO: document the rules under which parse DeclSyntax, DeclPackage, DeclImport, and DeclRange.

func (DeclAny) AsBody

func (d DeclAny) AsBody() DeclBody

AsBody converts a DeclAny into a DeclBody, if that is the declaration it contains.

Otherwise, returns zero.

func (DeclAny) AsDef

func (d DeclAny) AsDef() DeclDef

AsDef converts a DeclAny into a DeclDef, if that is the declaration it contains.

Otherwise, returns zero.

func (DeclAny) AsEmpty

func (d DeclAny) AsEmpty() DeclEmpty

AsEmpty converts a DeclAny into a DeclEmpty, if that is the declaration it contains.

Otherwise, returns zero.

func (DeclAny) AsImport

func (d DeclAny) AsImport() DeclImport

AsImport converts a DeclAny into a DeclImport, if that is the declaration it contains.

Otherwise, returns zero.

func (DeclAny) AsPackage

func (d DeclAny) AsPackage() DeclPackage

AsPackage converts a DeclAny into a DeclPackage, if that is the declaration it contains.

Otherwise, returns zero.

func (DeclAny) AsRange

func (d DeclAny) AsRange() DeclRange

AsRange converts a DeclAny into a DeclRange, if that is the declaration it contains.

Otherwise, returns zero.

func (DeclAny) AsSyntax

func (d DeclAny) AsSyntax() DeclSyntax

AsSyntax converts a DeclAny into a DeclSyntax, if that is the declaration it contains.

Otherwise, returns zero.

func (DeclAny) Span

func (d DeclAny) Span() source.Span

Span implements source.Spanner.

type DeclBody

type DeclBody id.Node[DeclBody, *File, *rawDeclBody]

DeclBody is the body of a DeclBody, or the whole contents of a File. The protocompile AST is very lenient, and allows any declaration to exist anywhere, for the benefit of rich diagnostics and refactorings. For example, it is possible to represent an "orphaned" field or oneof outside of a message, or an RPC method inside of an enum, and so on.

Grammar

DeclBody := `{` DeclAny* `}`

Note that a File is simply a DeclBody that is delimited by the bounds of the source file, rather than braces.

func (DeclBody) AsAny

func (d DeclBody) AsAny() DeclAny

AsAny type-erases this declaration value.

See DeclAny for more information.

func (DeclBody) Body

func (d DeclBody) Body() DeclBody

Body implements HasBody.

func (DeclBody) Braces

func (d DeclBody) Braces() token.Token

Braces returns this body's surrounding braces, if it has any.

func (DeclBody) Decls

func (d DeclBody) Decls() seq.Inserter[DeclAny]

Decls returns a seq.Inserter over the declarations in this body.

func (DeclBody) Options

func (d DeclBody) Options() iter.Seq[DefOption]

Options returns an iterator over the option definitions in this body.

func (DeclBody) Span

func (d DeclBody) Span() source.Span

Span implements source.Spanner.

type DeclDef

type DeclDef id.Node[DeclDef, *File, *rawDeclDef]

DeclDef is a general Protobuf definition.

This [Decl] represents the union of several similar AST nodes, to aid in permissive parsing and precise diagnostics.

This node represents messages, enums, services, extend blocks, fields, enum values, oneofs, groups, service methods, and options. It also permits nonsensical syntax, such as a message with a tag number.

Generally, you should not need to work with DeclDef directly; instead, use the As* methods to access the correct concrete syntax production a DeclDef represents.

Grammar

DeclDef := (Type Path | Type | Ident) followers* (`;` | DeclBody)?

followers := inputs | outputs | value | CompactOptions
inputs    := `(` (Type `,`?)* `)`
outputs   := `returns` (Type | inputs)?
value     := (`=` Expr) | ExprPath | ExprLiteral | ExprRange | ExprField

Note that this type will only record the first appearance of any follower.

func (DeclDef) AsAny

func (d DeclDef) AsAny() DeclAny

AsAny type-erases this declaration value.

See DeclAny for more information.

func (DeclDef) AsEnum

func (d DeclDef) AsEnum() DefEnum

AsEnum extracts the fields from this definition relevant to interpreting it as an enum.

The return value's fields may be zero if they are not present (in particular, Name will be zero if d.Name() is not an identifier).

See DeclDef.Classify.

func (DeclDef) AsEnumValue

func (d DeclDef) AsEnumValue() DefEnumValue

AsEnumValue extracts the fields from this definition relevant to interpreting it as an enum value.

The return value's fields may be zero if they are not present (in particular, Name will be zero if d.Name() is not an identifier).

See DeclDef.Classify.

func (DeclDef) AsExtend

func (d DeclDef) AsExtend() DefExtend

AsExtend extracts the fields from this definition relevant to interpreting it as a service.

The return value's fields may be zero if they are not present.

See DeclDef.Classify.

func (DeclDef) AsField

func (d DeclDef) AsField() DefField

AsField extracts the fields from this definition relevant to interpreting it as a message field.

The return value's fields may be zero if they are not present (in particular, Name will be zero if d.Name() is not an identifier).

See DeclDef.Classify.

func (DeclDef) AsGroup

func (d DeclDef) AsGroup() DefGroup

AsGroup extracts the fields from this definition relevant to interpreting it as a group.

The return value's fields may be zero if they are not present (in particular, Name will be zero if d.Name() is not an identifier).

See DeclDef.Classify.

func (DeclDef) AsMessage

func (d DeclDef) AsMessage() DefMessage

AsMessage extracts the fields from this definition relevant to interpreting it as a message.

The return value's fields may be zero if they are not present (in particular, Name will be zero if d.Name() is not an identifier).

See DeclDef.Classify.

func (DeclDef) AsMethod

func (d DeclDef) AsMethod() DefMethod

AsMethod extracts the fields from this definition relevant to interpreting it as a service method.

The return value's fields may be zero if they are not present (in particular, Name will be zero if d.Name() is not an identifier).

See DeclDef.Classify.

func (DeclDef) AsOneof

func (d DeclDef) AsOneof() DefOneof

AsOneof extracts the fields from this definition relevant to interpreting it as a oneof.

The return value's fields may be zero if they are not present (in particular, Name will be zero if d.Name() is not an identifier).

See DeclDef.Classify.

func (DeclDef) AsOption

func (d DeclDef) AsOption() DefOption

AsMethod extracts the fields from this definition relevant to interpreting it as an option.

The return value's fields may be zero if they are not present.

See DeclDef.Classify.

func (DeclDef) AsService

func (d DeclDef) AsService() DefService

AsService extracts the fields from this definition relevant to interpreting it as a service.

The return value's fields may be zero if they are not present (in particular, Name will be zero if d.Name() is not an identifier).

See DeclDef.Classify.

func (DeclDef) Body

func (d DeclDef) Body() DeclBody

Body returns this definition's body, if it has one.

func (DeclDef) Classify

func (d DeclDef) Classify() DefKind

Classify looks at all the fields in this definition and decides what kind of definition it's supposed to represent.

To select which definition this probably is, this function looks at DeclDef.KeywordToken. If there is no keyword or it isn't something that it recognizes, it is classified as either an enum value or a field, depending on whether this definition has a type.

The correct way to use this function is as the input value for a switch. The cases of the switch should then use the As* methods, such as DeclDef.AsMessage, to extract the relevant fields.

func (DeclDef) Equals

func (d DeclDef) Equals() token.Token

Equals returns this definitions = token, before the value. May be zero.

func (DeclDef) IsCorrupt

func (d DeclDef) IsCorrupt() bool

IsCorrupt reports whether or not some part of the parser decided that this definition is not interpretable as any specific kind of definition.

func (DeclDef) Keyword

func (d DeclDef) Keyword() keyword.Keyword

KeywordToken returns the introducing keyword for this definition, if there is one.

See DeclDef.Type for details on where this keyword comes from.

func (DeclDef) KeywordToken

func (d DeclDef) KeywordToken() token.Token

KeywordToken returns the introducing keyword token for this definition, if there is one.

See DeclDef.Type for details on where this keyword comes from.

func (DeclDef) MarkCorrupt

func (d DeclDef) MarkCorrupt()

the compiler to ignore it. See DeclDef.IsCorrupt.

func (DeclDef) Name

func (d DeclDef) Name() Path

Name returns this definition's declared name.

func (DeclDef) Options

func (d DeclDef) Options() CompactOptions

Options returns the compact options list for this definition.

func (DeclDef) Prefixes

func (d DeclDef) Prefixes() iter.Seq[TypePrefixed]

Prefixes returns an iterator over the modifiers on this def, expressed as TypePrefixed nodes.

func (DeclDef) Semicolon

func (d DeclDef) Semicolon() token.Token

Semicolon returns the ending semicolon token for this definition. May be zero.

func (DeclDef) SetBody

func (d DeclDef) SetBody(b DeclBody)

SetBody sets the body for this definition.

func (DeclDef) SetOptions

func (d DeclDef) SetOptions(opts CompactOptions)

SetOptions sets the compact options list for this definition.

Setting it to a zero Options clears it.

func (DeclDef) SetType

func (d DeclDef) SetType(ty TypeAny)

SetType sets the "prefix" type of this definition.

func (DeclDef) SetValue

func (d DeclDef) SetValue(expr ExprAny)

SetValue sets the value of this definition.

See DeclDef.Value.

func (DeclDef) Signature

func (d DeclDef) Signature() Signature

Signature returns this definition's type signature, if it has one.

Note that this is distinct from the type returned by DeclDef.Type, which is the "prefix" type for the definition (such as for a field). This is a signature for e.g. a method.

Not all defs have a signature, so this function may return a zero Signature.q If you want to add one, use DeclDef.WithSignature.

func (DeclDef) Span

func (d DeclDef) Span() source.Span

Span implements source.Spanner.

func (DeclDef) Stem

func (d DeclDef) Stem() source.Span

Stem returns a span that contains both this definition's type and name.

For e.g. a message, this is the "message Foo" part.

func (DeclDef) Type

func (d DeclDef) Type() TypeAny

Type returns the "prefix" type of this definition.

This type may coexist with a Signature in this definition.

May be zero, such as for enum values. For messages and other productions introduced by a special keyword, this will be a TypePath whose single identifier is that keyword.

See DeclDef.KeywordToken.

func (DeclDef) Value

func (d DeclDef) Value() ExprAny

Value returns this definition's value. For a field, this will be the tag number, while for an option, this will be the complex expression representing its value.

func (DeclDef) WithSignature

func (d DeclDef) WithSignature() Signature

WithSignature is like Signature, but it adds an empty signature if it would return zero.

type DeclDefArgs

type DeclDefArgs struct {
	// If both Keyword and Type are set, Type will be prioritized.
	Keyword token.Token
	Type    TypeAny
	Name    Path

	// NOTE: the values for the type signature are not provided at
	// construction time, and should be added by mutating through
	// DeclDef.Signature.
	Returns token.Token

	Equals token.Token
	Value  ExprAny

	Options CompactOptions

	Body      DeclBody
	Semicolon token.Token
}

DeclDefArgs is arguments for creating a DeclDef with [Context.NewDeclDef].

type DeclEmpty

type DeclEmpty id.Node[DeclEmpty, *File, *rawDeclEmpty]

DeclEmpty is an empty declaration, a lone ;.

Grammar

DeclEmpty := `;`

func (DeclEmpty) AsAny

func (d DeclEmpty) AsAny() DeclAny

AsAny type-erases this declaration value.

See DeclAny for more information.

func (DeclEmpty) Semicolon

func (d DeclEmpty) Semicolon() token.Token

Semicolon returns this field's ending semicolon.

May be token.Zero, if not present.

func (DeclEmpty) Span

func (d DeclEmpty) Span() source.Span

Span implements source.Spanner.

type DeclImport

type DeclImport id.Node[DeclImport, *File, *rawDeclImport]

DeclImport is an import declaration within a file.

Grammar

DeclImport := `import` (`weak` | `public`)? Expr? CompactOptions? `;`?

Note: options are not permitted on import declarations in Protobuf, but we parse them for diagnosis.

func (DeclImport) AsAny

func (d DeclImport) AsAny() DeclAny

AsAny type-erases this declaration value.

See DeclAny for more information.

func (DeclImport) ImportPath

func (d DeclImport) ImportPath() ExprAny

ImportPath returns the file path for this import as a string.

May be zero, if the user forgot it.

func (DeclImport) IsOption

func (d DeclImport) IsOption() bool

IsOption checks whether this is an "import option".

func (DeclImport) IsPublic

func (d DeclImport) IsPublic() bool

IsPublic checks whether this is an "import public".

func (DeclImport) IsWeak

func (d DeclImport) IsWeak() bool

IsWeak checks whether this is an "import weak".

func (DeclImport) Keyword

func (d DeclImport) Keyword() keyword.Keyword

Keyword returns the keyword for this declaration.

func (DeclImport) KeywordToken

func (d DeclImport) KeywordToken() token.Token

KeywordToken returns the "import" keyword for this declaration.

func (DeclImport) ModifierTokens

func (d DeclImport) ModifierTokens() seq.Inserter[token.Token]

ModifierTokens returns the modifier tokens for this declaration.

func (DeclImport) Modifiers

func (d DeclImport) Modifiers() seq.Indexer[keyword.Keyword]

Modifiers returns the modifiers for this declaration.

func (DeclImport) Options

func (d DeclImport) Options() CompactOptions

Options returns the compact options list for this declaration.

Imports cannot have options, but we parse them anyways.

func (DeclImport) Semicolon

func (d DeclImport) Semicolon() token.Token

Semicolon returns this import's ending semicolon.

May be zero, if the user forgot it.

func (DeclImport) SetImportPath

func (d DeclImport) SetImportPath(expr ExprAny)

SetValue sets the expression for this import's file path.

If passed zero, this clears the path expression.

func (DeclImport) SetOptions

func (d DeclImport) SetOptions(opts CompactOptions)

SetOptions sets the compact options list for this declaration.

Setting it to a zero Options clears it.

func (DeclImport) Span

func (d DeclImport) Span() source.Span

source.Span implements source.Spanner.

type DeclImportArgs

type DeclImportArgs struct {
	Keyword    token.Token
	Modifiers  []token.Token
	ImportPath ExprAny
	Options    CompactOptions
	Semicolon  token.Token
}

DeclImportArgs is arguments for [Context.NewDeclImport].

type DeclKind

type DeclKind int8

DeclKind is a kind of declaration. There is one value of DeclKind for each Decl* type in this package.

const (
	DeclKindInvalid DeclKind = iota
	DeclKindEmpty
	DeclKindSyntax
	DeclKindPackage
	DeclKindImport
	DeclKindDef
	DeclKindBody
	DeclKindRange
)

func (DeclKind) DecodeDynID

func (DeclKind) DecodeDynID(lo, _ int32) DeclKind

func (DeclKind) EncodeDynID

func (k DeclKind) EncodeDynID(value int32) (int32, int32, bool)

func (DeclKind) GoString

func (v DeclKind) GoString() string

GoString implements fmt.GoStringer.

func (DeclKind) String

func (v DeclKind) String() string

String implements fmt.Stringer.

type DeclPackage

type DeclPackage id.Node[DeclPackage, *File, *rawDeclPackage]

DeclPackage is the package declaration for a file.

Grammar

DeclPackage := `package` Path? CompactOptions? `;`?

Note: options are not permitted on package declarations in Protobuf, but we parse them for diagnosis.

func (DeclPackage) AsAny

func (d DeclPackage) AsAny() DeclAny

AsAny type-erases this declaration value.

See DeclAny for more information.

func (DeclPackage) Keyword

func (d DeclPackage) Keyword() keyword.Keyword

Keyword returns the keyword for this declaration.

func (DeclPackage) KeywordToken

func (d DeclPackage) KeywordToken() token.Token

KeywordToken returns the "package" token for this declaration.

func (DeclPackage) Options

func (d DeclPackage) Options() CompactOptions

Options returns the compact options list for this declaration.

Package declarations cannot have options, but we parse them anyways.

func (DeclPackage) Path

func (d DeclPackage) Path() Path

Path returns this package's path.

May be zero, if the user wrote something like package;.

func (DeclPackage) Semicolon

func (d DeclPackage) Semicolon() token.Token

Semicolon returns this package's ending semicolon.

May be zero, if the user forgot it.

func (DeclPackage) SetOptions

func (d DeclPackage) SetOptions(opts CompactOptions)

SetOptions sets the compact options list for this declaration.

Setting it to a zero Options clears it.

func (DeclPackage) Span

func (d DeclPackage) Span() source.Span

source.Span implements source.Spanner.

type DeclPackageArgs

type DeclPackageArgs struct {
	Keyword   token.Token
	Path      Path
	Options   CompactOptions
	Semicolon token.Token
}

DeclPackageArgs is arguments for [Context.NewDeclPackage].

type DeclRange

type DeclRange id.Node[DeclRange, *File, *rawDeclRange]

DeclRange represents an extension or reserved range declaration. They are almost identical syntactically so they use the same AST node.

Grammar

DeclRange := (`extensions` | `reserved`) (Expr `,`)* Expr? CompactOptions? `;`?

func (DeclRange) AsAny

func (d DeclRange) AsAny() DeclAny

AsAny type-erases this declaration value.

See DeclAny for more information.

func (DeclRange) IsExtensions

func (d DeclRange) IsExtensions() bool

IsExtensions checks whether this is an extension range.

func (DeclRange) IsReserved

func (d DeclRange) IsReserved() bool

IsReserved checks whether this is a reserved range.

func (DeclRange) Keyword

func (d DeclRange) Keyword() keyword.Keyword

Keyword returns the keyword for this range.

func (DeclRange) KeywordToken

func (d DeclRange) KeywordToken() token.Token

KeywordToken returns the keyword token for this range.

func (DeclRange) Options

func (d DeclRange) Options() CompactOptions

Options returns the compact options list for this range.

func (DeclRange) Ranges

func (d DeclRange) Ranges() Commas[ExprAny]

Ranges returns the sequence of expressions denoting the ranges in this range declaration.

func (DeclRange) Semicolon

func (d DeclRange) Semicolon() token.Token

Semicolon returns this range's ending semicolon.

May be nil, if not present.

func (DeclRange) SetOptions

func (d DeclRange) SetOptions(opts CompactOptions)

SetOptions sets the compact options list for this definition.

Setting it to a nil Options clears it.

func (DeclRange) Span

func (d DeclRange) Span() source.Span

Span implements source.Spanner.

type DeclRangeArgs

type DeclRangeArgs struct {
	Keyword   token.Token
	Options   CompactOptions
	Semicolon token.Token
}

DeclRangeArgs is arguments for [Context.NewDeclRange].

type DeclSyntax

type DeclSyntax id.Node[DeclSyntax, *File, *rawDeclSyntax]

DeclSyntax represents a language declaration, such as the syntax or edition keywords.

Grammar

DeclSyntax := (`syntax` | `edition`) (`=`? Expr)? CompactOptions? `;`?

Note: options are not permitted on syntax declarations in Protobuf, but we parse them for diagnosis.

func (DeclSyntax) AsAny

func (d DeclSyntax) AsAny() DeclAny

AsAny type-erases this declaration value.

See DeclAny for more information.

func (DeclSyntax) Equals

func (d DeclSyntax) Equals() token.Token

Equals returns the equals sign after the keyword.

May be zero, if the user wrote something like syntax "proto2";.

func (DeclSyntax) IsEdition

func (d DeclSyntax) IsEdition() bool

IsEdition checks whether this is a new-style edition declaration.

func (DeclSyntax) IsSyntax

func (d DeclSyntax) IsSyntax() bool

IsSyntax checks whether this is an OG syntax declaration.

func (DeclSyntax) Keyword

func (d DeclSyntax) Keyword() keyword.Keyword

Keyword returns the keyword for this declaration.

func (DeclSyntax) KeywordToken

func (d DeclSyntax) KeywordToken() token.Token

KeywordToken returns the keyword token for this declaration.

func (DeclSyntax) Options

func (d DeclSyntax) Options() CompactOptions

Options returns the compact options list for this declaration.

Syntax declarations cannot have options, but we parse them anyways.

func (DeclSyntax) Semicolon

func (d DeclSyntax) Semicolon() token.Token

Semicolon returns this declaration's ending semicolon.

May be zero, if the user forgot it.

func (DeclSyntax) SetOptions

func (d DeclSyntax) SetOptions(opts CompactOptions)

SetOptions sets the compact options list for this declaration.

Setting it to a zero Options clears it.

func (DeclSyntax) SetValue

func (d DeclSyntax) SetValue(expr ExprAny)

SetValue sets the expression for this declaration's value.

If passed zero, this clears the value (e.g., for syntax = ;).

func (DeclSyntax) Span

func (d DeclSyntax) Span() source.Span

source.Span implements source.Spanner.

func (DeclSyntax) Value

func (d DeclSyntax) Value() ExprAny

Value returns the value expression of this declaration.

May be zero, if the user wrote something like syntax;. It can also be a number or an identifier, for cases like edition = 2024; or syntax = proto2;.

type DeclSyntaxArgs

type DeclSyntaxArgs struct {
	// Must be "syntax" or "edition".
	Keyword   token.Token
	Equals    token.Token
	Value     ExprAny
	Options   CompactOptions
	Semicolon token.Token
}

DeclSyntaxArgs is arguments for [Context.NewDeclSyntax].

type Def

type Def interface {
	source.Spanner
	// contains filtered or unexported methods
}

Def is the return type of DeclDef.Classify.

This interface is implemented by all the Def* types in this package, and can be type-asserted to any of them, usually in a type switch.

A DeclDef can't be mutated through a Def; instead, you will need to mutate the general structure instead.

type DefEnum

type DefEnum struct {
	Keyword token.Token
	Name    token.Token
	Body    DeclBody

	Decl DeclDef
}

DefEnum is a DeclDef projected into an enum definition.

See DeclDef.Classify.

func (DefEnum) Context

func (d DefEnum) Context() *File

func (DefEnum) Span

func (d DefEnum) Span() source.Span

type DefEnumValue

type DefEnumValue struct {
	Name      token.Token
	Equals    token.Token
	Tag       ExprAny
	Options   CompactOptions
	Semicolon token.Token

	Decl DeclDef
}

DefEnumValue is a DeclDef projected into an enum value definition.

See DeclDef.Classify.

func (DefEnumValue) Context

func (d DefEnumValue) Context() *File

func (DefEnumValue) Span

func (d DefEnumValue) Span() source.Span

type DefExtend

type DefExtend struct {
	Keyword  token.Token
	Extendee Path
	Body     DeclBody

	Decl DeclDef
}

DefExtend is a DeclDef projected into an extension definition.

See DeclDef.Classify.

func (DefExtend) Context

func (d DefExtend) Context() *File

func (DefExtend) Span

func (d DefExtend) Span() source.Span

type DefField

type DefField struct {
	Type      TypeAny
	Name      token.Token
	Equals    token.Token
	Tag       ExprAny
	Options   CompactOptions
	Semicolon token.Token

	Decl DeclDef
}

DefField is a DeclDef projected into a field definition.

See DeclDef.Classify.

func (DefField) Context

func (d DefField) Context() *File

func (DefField) Span

func (d DefField) Span() source.Span

type DefGroup

type DefGroup struct {
	Keyword token.Token
	Name    token.Token
	Equals  token.Token
	Tag     ExprAny
	Options CompactOptions
	Body    DeclBody

	Decl DeclDef
}

DefGroup is a DeclDef projected into a group definition.

See DeclDef.Classify.

func (DefGroup) Context

func (d DefGroup) Context() *File

func (DefGroup) Span

func (d DefGroup) Span() source.Span

type DefKind

type DefKind int8

DefKind is the kind of definition a DeclDef contains.

See DeclDef.Classify.

const (
	DefKindInvalid DefKind = iota
	DefKindMessage
	DefKindEnum
	DefKindService
	DefKindExtend
	DefKindField
	DefKindOneof
	DefKindGroup
	DefKindEnumValue
	DefKindMethod
	DefKindOption
)

func (DefKind) GoString

func (v DefKind) GoString() string

GoString implements fmt.GoStringer.

func (DefKind) String

func (v DefKind) String() string

String implements fmt.Stringer.

type DefMessage

type DefMessage struct {
	Keyword token.Token
	Name    token.Token
	Body    DeclBody

	Decl DeclDef
}

DefMessage is a DeclDef projected into a message definition.

See DeclDef.Classify.

func (DefMessage) Context

func (d DefMessage) Context() *File

func (DefMessage) Span

func (d DefMessage) Span() source.Span

type DefMethod

type DefMethod struct {
	Keyword   token.Token
	Name      token.Token
	Signature Signature
	Body      DeclBody

	Decl DeclDef
}

DefMethod is a DeclDef projected into a method definition.

See DeclDef.Classify.

func (DefMethod) Context

func (d DefMethod) Context() *File

func (DefMethod) Span

func (d DefMethod) Span() source.Span

type DefOneof

type DefOneof struct {
	Keyword token.Token
	Name    token.Token
	Body    DeclBody

	Decl DeclDef
}

DefEnumValue is a DeclDef projected into a oneof definition.

See DeclDef.Classify.

func (DefOneof) Context

func (d DefOneof) Context() *File

func (DefOneof) Span

func (d DefOneof) Span() source.Span

type DefOption

type DefOption struct {
	Option

	Keyword   token.Token
	Semicolon token.Token

	Decl DeclDef
}

DefOption is a DeclDef projected into a method definition.

Yes, an option is technically not defining anything, just setting a value. However, it's syntactically analogous to a definition!

See DeclDef.Classify.

func (DefOption) Context

func (d DefOption) Context() *File

func (DefOption) Span

func (d DefOption) Span() source.Span

type DefService

type DefService struct {
	Keyword token.Token
	Name    token.Token
	Body    DeclBody

	Decl DeclDef
}

DefService is a DeclDef projected into a service definition.

See DeclDef.Classify.

func (DefService) Context

func (d DefService) Context() *File

func (DefService) Span

func (d DefService) Span() source.Span

type ExprAny

type ExprAny id.DynNode[ExprAny, ExprKind, *File]

ExprAny is any ExprAny* type in this package.

Values of this type can be obtained by calling an AsAny method on a ExprAny* type, such as ExprPath.AsAny. It can be type-asserted back to any of the concrete ExprAny* types using its own As* methods.

This type is used in lieu of a putative ExprAny interface type to avoid heap allocations in functions that would return one of many different ExprAny* types.

Grammar

In addition to the Expr type, we define some exported productions for handling operator precedence.

Expr      := ExprField | ExprOp
ExprJuxta := ExprFieldWithColon | ExprOp
ExprOp    := ExprRange | ExprPrefix | ExprSolo
ExprSolo  := ExprLiteral | ExprPath | ExprArray | ExprDict

Note: ExprJuxta is the expression production that is unambiguous when expressions are juxtaposed with each other; i.e., ExprJuxta* does not make e.g. "foo {}" ambiguous between an ExprField or an ExprPath followed by an ExprDict.

func (ExprAny) AsArray

func (e ExprAny) AsArray() ExprArray

AsArray converts a ExprAny into a ExprArray, if that is the type it contains.

Otherwise, returns zero.

func (ExprAny) AsDict

func (e ExprAny) AsDict() ExprDict

AsDict converts a ExprAny into a ExprDict, if that is the type it contains.

Otherwise, returns zero.

func (ExprAny) AsError

func (e ExprAny) AsError() ExprError

AsError converts a ExprAny into a ExprError, if that is the type it contains.

Otherwise, returns nil.

func (ExprAny) AsField

func (e ExprAny) AsField() ExprField

AsField converts a ExprAny into a ExprKV, if that is the type it contains.

Otherwise, returns zero.

func (ExprAny) AsLiteral

func (e ExprAny) AsLiteral() ExprLiteral

AsLiteral converts a ExprAny into a ExprLiteral, if that is the type it contains.

Otherwise, returns zero.

func (ExprAny) AsPath

func (e ExprAny) AsPath() ExprPath

AsPath converts a ExprAny into a ExprPath, if that is the type it contains.

Otherwise, returns zero.

func (ExprAny) AsPrefixed

func (e ExprAny) AsPrefixed() ExprPrefixed

AsPrefixed converts a ExprAny into a ExprPrefixed, if that is the type it contains.

Otherwise, returns zero.

func (ExprAny) AsRange

func (e ExprAny) AsRange() ExprRange

AsRange converts a ExprAny into a ExprRange, if that is the type it contains.

Otherwise, returns zero.

func (ExprAny) Span

func (e ExprAny) Span() source.Span

Span implements source.Spanner.

type ExprArray

type ExprArray id.Node[ExprArray, *File, *rawExprArray]

ExprArray represents an array of expressions between square brackets.

Grammar

ExprArray := `[` (ExprJuxta `,`?)*`]`

func (ExprArray) AsAny

func (e ExprArray) AsAny() ExprAny

AsAny type-erases this expression value.

See ExprAny for more information.

func (ExprArray) Brackets

func (e ExprArray) Brackets() token.Token

Brackets returns the token tree corresponding to the whole [...].

May be missing for a synthetic expression.

func (ExprArray) Elements

func (e ExprArray) Elements() Commas[ExprAny]

Elements returns the sequence of expressions in this array.

func (ExprArray) Span

func (e ExprArray) Span() source.Span

Span implements source.Spanner.

type ExprDict

type ExprDict id.Node[ExprDict, *File, *rawExprDict]

ExprDict represents a an array of message fields between curly braces.

Grammar

ExprDict := `{` fields `}` | `<` fields `>`
fields := (Expr (`,` | `;`)?)*

Note that if a non-ExprField occurs as a field of a dict, the parser will rewrite it into an ExprField with a missing key.

func (ExprDict) AsAny

func (e ExprDict) AsAny() ExprAny

AsAny type-erases this expression value.

See ExprAny for more information.

func (ExprDict) Braces

func (e ExprDict) Braces() token.Token

Braces returns the token tree corresponding to the whole {...}.

May be missing for a synthetic expression.

func (ExprDict) Elements

func (e ExprDict) Elements() Commas[ExprField]

Elements returns the sequence of expressions in this array.

func (ExprDict) Span

func (e ExprDict) Span() source.Span

Span implements source.Spanner.

type ExprError

type ExprError id.Node[ExprError, *File, *rawExprError]

ExprError represents an unrecoverable parsing error in an expression context.

func (ExprError) AsAny

func (e ExprError) AsAny() ExprAny

AsAny type-erases this expression value.

See ExprAny for more information.

func (ExprError) Span

func (e ExprError) Span() source.Span

Span implements source.Spanner.

type ExprField

type ExprField id.Node[ExprField, *File, *rawExprField]

ExprField is a key-value pair within an ExprDict.

It implements ExprAny, since it can appear inside of e.g. an array if the user incorrectly writes [foo: bar].

Grammar

ExprField := ExprFieldWithColon | Expr (ExprDict | ExprArray)
ExprFieldWithColon := Expr (`:` | `=`) Expr

Note: ExprFieldWithColon appears in ExprJuxta, the expression production that is unambiguous when expressions are juxtaposed with each other.

func (ExprField) AsAny

func (e ExprField) AsAny() ExprAny

AsAny type-erases this expression value.

See ExprAny for more information.

func (ExprField) Colon

func (e ExprField) Colon() token.Token

Colon returns the colon between Key() and Value().

May be zero: it is valid for a field name to be immediately followed by its value and be syntactically valid (unlike most "optional" punctuation, this is permitted by Protobuf, not just our permissive AST).

func (ExprField) Key

func (e ExprField) Key() ExprAny

Key returns the key for this field.

May be zero if the parser encounters a message expression with a missing field, e.g. {foo, bar: baz}.

func (ExprField) SetKey

func (e ExprField) SetKey(expr ExprAny)

SetKey sets the key for this field.

If passed zero, this clears the key.

func (ExprField) SetValue

func (e ExprField) SetValue(expr ExprAny)

SetValue sets the value for this field.

If passed zero, this clears the expression.

func (ExprField) Span

func (e ExprField) Span() source.Span

Span implements source.Spanner.

func (ExprField) Value

func (e ExprField) Value() ExprAny

Value returns the value for this field.

type ExprFieldArgs

type ExprFieldArgs struct {
	Key   ExprAny
	Colon token.Token
	Value ExprAny
}

ExprFieldArgs is arguments for [Context.NewExprKV].

type ExprKind

type ExprKind int8

ExprKind is a kind of expression. There is one value of ExprKind for each Expr* type in this package.

const (
	ExprKindInvalid ExprKind = iota
	ExprKindError
	ExprKindLiteral
	ExprKindPrefixed
	ExprKindPath
	ExprKindRange
	ExprKindArray
	ExprKindDict
	ExprKindField
)

func (ExprKind) DecodeDynID

func (ExprKind) DecodeDynID(lo, hi int32) ExprKind

func (ExprKind) EncodeDynID

func (k ExprKind) EncodeDynID(value int32) (int32, int32, bool)

func (ExprKind) GoString

func (v ExprKind) GoString() string

GoString implements fmt.GoStringer.

func (ExprKind) String

func (v ExprKind) String() string

String implements fmt.Stringer.

type ExprLiteral

type ExprLiteral struct {
	File *File
	// The token backing this expression. Must be [token.String] or [token.Number].
	token.Token
}

ExprLiteral is an expression corresponding to a string or number literal.

Grammar

ExprLiteral := token.Number | token.String

func (ExprLiteral) AsAny

func (e ExprLiteral) AsAny() ExprAny

AsAny type-erases this type value.

See TypeAny for more information.

func (ExprLiteral) Context

func (e ExprLiteral) Context() *File

Context returns this literal's context.

This returns a File rather than a token.Stream, which would otherwise be returned because ExprLiteral embeds token.Token.

type ExprPath

type ExprPath struct {
	// The path backing this expression.
	Path
}

ExprPath is a simple path reference in expression position.

Grammar

ExprPath := Path

func (ExprPath) AsAny

func (e ExprPath) AsAny() ExprAny

AsAny type-erases this type value.

See TypeAny for more information.

type ExprPrefixed

type ExprPrefixed id.Node[ExprPrefixed, *File, *rawExprPrefixed]

ExprPrefixed is an expression prefixed with an operator.

Grammar

ExprPrefix := `-` ExprSolo

func (ExprPrefixed) AsAny

func (e ExprPrefixed) AsAny() ExprAny

AsAny type-erases this expression value.

See ExprAny for more information.

func (ExprPrefixed) Expr

func (e ExprPrefixed) Expr() ExprAny

Expr returns the expression the prefix is applied to.

func (ExprPrefixed) Prefix

func (e ExprPrefixed) Prefix() keyword.Keyword

Prefix returns this expression's prefix.

Returns keyword.Unknown if TypePrefixed.PrefixToken does not contain a known prefix.

func (ExprPrefixed) PrefixToken

func (e ExprPrefixed) PrefixToken() token.Token

PrefixToken returns the token representing this expression's prefix.

func (ExprPrefixed) SetExpr

func (e ExprPrefixed) SetExpr(expr ExprAny)

SetExpr sets the expression that the prefix is applied to.

If passed zero, this clears the expression.

func (ExprPrefixed) Span

func (e ExprPrefixed) Span() source.Span

source.Span implements source.Spanner.

type ExprPrefixedArgs

type ExprPrefixedArgs struct {
	Prefix token.Token
	Expr   ExprAny
}

ExprPrefixedArgs is arguments for [Context.NewExprPrefixed].

type ExprRange

type ExprRange id.Node[ExprRange, *File, *rawExprRange]

ExprRange represents a range of values, such as 1 to 4 or 5 to max.

Note that max is not special syntax; it will appear as an ExprPath with the name "max".

Grammar

ExprRange := ExprPrefixed `to` ExprOp

func (ExprRange) AsAny

func (e ExprRange) AsAny() ExprAny

AsAny type-erases this expression value.

See ExprAny for more information.

func (ExprRange) Bounds

func (e ExprRange) Bounds() (start, end ExprAny)

Bounds returns this range's bounds. These are inclusive bounds.

func (ExprRange) Keyword

func (e ExprRange) Keyword() token.Token

Keyword returns the "to" keyword for this range.

func (ExprRange) SetBounds

func (e ExprRange) SetBounds(start, end ExprAny)

SetBounds set the expressions for this range's bounds.

Clears the respective expressions when passed a zero expression.

func (ExprRange) Span

func (e ExprRange) Span() source.Span

Span implements source.Spanner.

type ExprRangeArgs

type ExprRangeArgs struct {
	Start ExprAny
	To    token.Token
	End   ExprAny
}

ExprRangeArgs is arguments for [Context.NewExprRange].

type File

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

File is the top-level AST node for a Protobuf file.

A file is a list of declarations (in other words, it is a DeclBody). The File type provides convenience functions for extracting salient elements, such as the DeclSyntax and the DeclPackage.

Grammar

File := DeclAny*

func New

func New(path string, stream *token.Stream) *File

New creates a fresh context for a file.

path is the semantic import path of this file, which may not be the same as file.Path, which is used for diagnostics.

func (*File) Decls

func (f *File) Decls() seq.Inserter[DeclAny]

Decls returns all of the top-level declarations in this file.

func (*File) FromID

func (f *File) FromID(id uint64, want any) any

FromID implements id.Context.

func (*File) Imports

func (f *File) Imports() iter.Seq[DeclImport]

Imports returns an iterator over this file's import declarations.

func (*File) Nodes

func (f *File) Nodes() *Nodes

Nodes returns the node arena for this file, which can be used to allocate new AST nodes.

func (*File) Options

func (f *File) Options() iter.Seq[DefOption]

Options returns an iterator over this file's option definitions.

func (*File) Package

func (f *File) Package() DeclPackage

Package returns this file's package declaration, if it has one.

func (*File) Path

func (f *File) Path() string

Path returns the semantic import path of this file.

func (*File) Span

func (f *File) Span() source.Span

Span returns the span for this file.

func (*File) Stream

func (f *File) Stream() *token.Stream

Stream returns the underlying token stream.

func (*File) Syntax

func (f *File) Syntax() DeclSyntax

Syntax returns this file's declaration, if it has one.

type HasBody

type HasBody interface {
	source.Spanner

	Body() DeclBody
}

HasBody is an AST node that contains a [Body].

File, DeclBody, and DeclDef all implement this interface.

type Nodes

type Nodes File

Nodes provides storage for the various AST node types, and can be used to construct new ones.

func (*Nodes) File

func (n *Nodes) File() *File

File returns the File that this Nodes adds nodes to.

func (*Nodes) NewCompactOptions

func (n *Nodes) NewCompactOptions(brackets token.Token) CompactOptions

NewCompactOptions creates a new CompactOptions node.

func (*Nodes) NewDeclBody

func (n *Nodes) NewDeclBody(braces token.Token) DeclBody

NewDeclBody creates a new DeclBody node.

To add declarations to the returned body, use [DeclBody.Append].

func (*Nodes) NewDeclDef

func (n *Nodes) NewDeclDef(args DeclDefArgs) DeclDef

NewDeclDef creates a new DeclDef node.

func (*Nodes) NewDeclEmpty

func (n *Nodes) NewDeclEmpty(semicolon token.Token) DeclEmpty

NewDeclEmpty creates a new DeclEmpty node.

func (*Nodes) NewDeclImport

func (n *Nodes) NewDeclImport(args DeclImportArgs) DeclImport

NewDeclImport creates a new DeclImport node.

func (*Nodes) NewDeclPackage

func (n *Nodes) NewDeclPackage(args DeclPackageArgs) DeclPackage

NewDeclPackage creates a new DeclPackage node.

func (*Nodes) NewDeclRange

func (n *Nodes) NewDeclRange(args DeclRangeArgs) DeclRange

NewDeclRange creates a new DeclRange node.

To add ranges to the returned declaration, use [DeclRange.Append].

func (*Nodes) NewDeclSyntax

func (n *Nodes) NewDeclSyntax(args DeclSyntaxArgs) DeclSyntax

NewDeclSyntax creates a new DeclSyntax node.

func (*Nodes) NewExprArray

func (n *Nodes) NewExprArray(brackets token.Token) ExprArray

NewExprArray creates a new ExprArray node.

To add elements to the returned expression, use [ExprArray.Append].

func (*Nodes) NewExprDict

func (n *Nodes) NewExprDict(braces token.Token) ExprDict

NewExprDict creates a new ExprDict node.

To add elements to the returned expression, use [ExprDict.Append].

func (*Nodes) NewExprField

func (n *Nodes) NewExprField(args ExprFieldArgs) ExprField

NewExprField creates a new ExprPrefixed node.

func (*Nodes) NewExprPrefixed

func (n *Nodes) NewExprPrefixed(args ExprPrefixedArgs) ExprPrefixed

NewExprPrefixed creates a new ExprPrefixed node.

func (*Nodes) NewExprRange

func (n *Nodes) NewExprRange(args ExprRangeArgs) ExprRange

NewExprRange creates a new ExprRange node.

func (*Nodes) NewExtensionComponent

func (n *Nodes) NewExtensionComponent(separator token.Token, path Path) PathComponent

NewExtensionComponent returns a new extension path component containing the given path.

func (*Nodes) NewPath

func (n *Nodes) NewPath(components ...PathComponent) Path

NewPath creates a new synthetic Path.

func (*Nodes) NewPathComponent

func (n *Nodes) NewPathComponent(separator, name token.Token) PathComponent

NewPathComponent returns a new path component with the given separator and name.

sep must be a token.Keyword whose value is either '.' or '/'. name must be a token.Ident. This function will panic if either condition does not hold.

To create a path component with an extension value, see Nodes.NewExtensionComponent.

func (*Nodes) NewTypeGeneric

func (n *Nodes) NewTypeGeneric(args TypeGenericArgs) TypeGeneric

NewTypeGeneric creates a new TypeGeneric node.

To add arguments to the returned type, use [TypeGeneric.Append].

func (*Nodes) NewTypePrefixed

func (n *Nodes) NewTypePrefixed(args TypePrefixedArgs) TypePrefixed

NewTypePrefixed creates a new TypePrefixed node.

type Option

type Option struct {
	Path   Path
	Equals token.Token
	Value  ExprAny
}

Option is a key-value pair inside of a CompactOptions or a DefOption.

func (Option) Span

func (o Option) Span() source.Span

Span implements source.Spanner.

type Path

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

Path represents a multi-part identifier.

This includes single identifiers like foo, references like foo.bar, and fully-qualified names like .foo.bar.

Grammar

Path      := `.`? component (sep component)*

component := token.Ident | `(` Path `)`
sep       := `.` | `/`

func (Path) Absolute

func (p Path) Absolute() bool

Absolute returns whether this path starts with a dot.

func (Path) AsIdent

func (p Path) AsIdent() token.Token

AsIdent returns the single identifier that comprises this path, or the zero token.

func (Path) AsKeyword

func (p Path) AsKeyword() keyword.Keyword

AsKeyword returns the keyword.Keyword that this path represents.

If this path does not represent a builtin, returns keyword.Unknown.

func (Path) AsPredeclared

func (p Path) AsPredeclared() predeclared.Name

AsPredeclared returns the predeclared.Name that this path represents.

If this path does not represent a builtin, returns predeclared.Unknown.

func (Path) Canonicalized

func (p Path) Canonicalized() string

Canonicalized returns a string containing this path's value after canonicalization.

Canonicalization converts a path into something that can be used for name resolution. This includes removing extra separators and deleting whitespace and comments.

func (Path) Components

func (p Path) Components() iter.Seq[PathComponent]

Components is an iter.Seq that ranges over each component in this path. Specifically, it yields the (possibly zero) dot that precedes the component, and the identifier token.

func (Path) ID

func (p Path) ID() PathID

ID returns this path's ID.

func (Path) IsIdents

func (p Path) IsIdents(idents ...string) bool

IsIdents returns whether p is a sequence of exactly the given identifiers.

func (Path) IsSynthetic

func (p Path) IsSynthetic() bool

IsSynthetic returns whether this path was created with Nodes.NewPath.

func (Path) Span

func (p Path) Span() source.Span

source.Span implements source.Spanner.

func (Path) Split

func (p Path) Split(n int) (prefix, suffix Path)

Split splits a path at the given path component index, producing two new paths where the first contains the first n components and the second contains the rest. If n is negative or greater than the number of components in p, both returned paths will be zero.

The suffix will be absolute, except in the following cases: 1. n == 0 and p is not absolute (prefix will be zero and suffix will be p). 2. n is equal to the length of p (suffix will be zero and prefix will be p).

This operation runs in O(n) time.

func (Path) ToRelative

func (p Path) ToRelative() Path

ToRelative converts this path into a relative path, by deleting all leading separators. In particular, the path "..foo", which contains empty components, will be converted into "foo".

If called on zero or a relative path, returns p.

type PathComponent

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

PathComponent is a piece of a path. This is either an identifier or a nested path (for an extension name).

func (PathComponent) AsExtension

func (p PathComponent) AsExtension() Path

AsExtension returns the Path inside of this path component, if it is an extension path component, i.e. (a.b.c).

This is unrelated to the foo.bar/my.Type URL-like Any paths that appear in some expressions. Those are represented by allowing / as an alternative separator to . in paths.

func (PathComponent) AsIdent

func (p PathComponent) AsIdent() token.Token

AsIdent returns the single identifier that makes up this path component, if it is not an extension path component.

May be zero, in the case of e.g. the second component of foo..bar.

func (PathComponent) IsEmpty

func (p PathComponent) IsEmpty() bool

Returns whether this is an empty path component. Such components are not allowed in the grammar but may occur in invalid inputs nonetheless.

func (PathComponent) IsFirst

func (p PathComponent) IsFirst() bool

IsFirst returns whether this is the first component of its path.

func (PathComponent) IsLast

func (p PathComponent) IsLast() bool

IsLast returns whether this is the last component of its path.

func (PathComponent) Name

func (p PathComponent) Name() token.Token

Name is the token that represents this component's name. THis is either an identifier or a (...) token containing a path.

func (PathComponent) Next

func (p PathComponent) Next() PathComponent

Next returns the next path component after this one, if there is one.

func (PathComponent) Path

func (p PathComponent) Path() Path

Path returns the path that this component is part of.

func (PathComponent) Separator

func (p PathComponent) Separator() token.Token

Separator is the token that separates this component from the previous one, if any. This may be a dot or a slash.

func (PathComponent) Span

func (p PathComponent) Span() source.Span

Span implements source.Spanner.

func (PathComponent) SplitAfter

func (p PathComponent) SplitAfter() (before, after Path)

SplitAfter splits the path that this component came from around the component boundary after this component.

before's last component will be this component.

func (PathComponent) SplitBefore

func (p PathComponent) SplitBefore() (before, after Path)

SplitBefore splits the path that this component came from around the component boundary before this component.

after's first component will be this component.

Not currently implemented for synthetic paths.

type PathID

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

PathID identifies a Path in a [Context].

func (PathID) In

func (p PathID) In(f *File) Path

In wraps this ID with a context.

type Signature

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

Signature is a type signature of the form (types) returns (types).

Signatures may have multiple inputs and outputs.

func (Signature) Inputs

func (s Signature) Inputs() TypeList

Inputs returns the input argument list for this signature.

func (Signature) Outputs

func (s Signature) Outputs() TypeList

Outputs returns the output argument list for this signature.

func (Signature) Returns

func (s Signature) Returns() token.Token

Returns returns (lol) the "returns" token that separates the input and output type lists.

func (Signature) Span

func (s Signature) Span() source.Span

Span implemented source.Spanner.

type TypeAny

type TypeAny id.DynNode[TypeAny, TypeKind, *File]

TypeAny is any Type* type in this package.

Values of this type can be obtained by calling an AsAny method on a Type* type, such as TypePath.AsAny. It can be type-asserted back to any of the concrete Type* types using its own As* methods.

This type is used in lieu of a putative Type interface type to avoid heap allocations in functions that would return one of many different Type* types.

Grammar

Type := TypePath | TypePrefixed | TypeGeneric

Note that parsing a type cannot always be greedy. Consider that, if parsed as a type, "optional optional foo" could be parsed as:

TypePrefix{Optional, TypePrefix{Optional, TypePath("foo")}}

However, if we want to parse a type followed by a Path, it needs to parse as follows:

TypePrefix{Optional, TypePath("optional")}, Path("foo")

Thus, parsing a type is greedy except when the containing production contains "Type Path?" or similar, in which case parsing must be greedy up to the last Path it would otherwise consume.

func (TypeAny) AsError

func (t TypeAny) AsError() TypeError

AsError converts a TypeAny into a TypeError, if that is the type it contains.

Otherwise, returns nil.

func (TypeAny) AsGeneric

func (t TypeAny) AsGeneric() TypeGeneric

AsGeneric converts a TypeAny into a TypePrefix, if that is the type it contains.

Otherwise, returns zero.

func (TypeAny) AsPath

func (t TypeAny) AsPath() TypePath

AsPath converts a TypeAny into a TypePath, if that is the type it contains.

Otherwise, returns zero.

func (TypeAny) AsPrefixed

func (t TypeAny) AsPrefixed() TypePrefixed

AsPrefixed converts a TypeAny into a TypePrefix, if that is the type it contains.

Otherwise, returns zero.

func (TypeAny) Prefixes

func (t TypeAny) Prefixes() iter.Seq[TypePrefixed]

Prefixes is an iterator over all [TypePrefix]es wrapping this type.

func (TypeAny) RemovePrefixes

func (t TypeAny) RemovePrefixes() TypeAny

RemovePrefixes removes all [TypePrefix] values wrapping this type.

func (TypeAny) Span

func (t TypeAny) Span() source.Span

source.Span implements source.Spanner.

type TypeError

type TypeError id.Node[TypeError, *File, *rawTypeError]

TypeError represents an unrecoverable parsing error in a type context.

This type is so named to adhere to package ast's naming convention. It does not represent a "type error" as in "type-checking failure".

func (TypeError) AsAny

func (t TypeError) AsAny() TypeAny

AsAny type-erases this type value.

See TypeAny for more information.

func (TypeError) Span

func (t TypeError) Span() source.Span

Span implements source.Spanner.

type TypeGeneric

type TypeGeneric id.Node[TypeGeneric, *File, *rawTypeGeneric]

TypeGeneric is a type with generic arguments.

Protobuf does not have generics... mostly. It has the map<K, V> production, which looks like something that generalizes, but doesn't. It is useful to parse when users mistakenly think this generalizes or provide the incorrect number of arguments.

You will usually want to immediately call [TypeGeneric.Map] to codify the assumption that all generic types understood by your code are maps.

TypeGeneric implements [Commas[TypeAny]] for accessing its arguments.

Grammar

TypeGeneric := TypePath `<` (Type `,`?`)* `>`

func (TypeGeneric) Args

func (t TypeGeneric) Args() TypeList

Args returns the argument list for this generic type.

func (TypeGeneric) AsAny

func (t TypeGeneric) AsAny() TypeAny

AsAny type-erases this type value.

See TypeAny for more information.

func (TypeGeneric) AsMap

func (t TypeGeneric) AsMap() (key, value TypeAny)

AsMap extracts the key/value types out of this generic type, checking that it's actually a map<K, V>. This is intended for asserting the extremely common case of "the only generic type is map".

Returns zeros if this is not a map, or it has the wrong number of generic arguments.

func (TypeGeneric) Path

func (t TypeGeneric) Path() Path

Path returns the path of the "type constructor". For example, for my.Map<K, V>, this would return the path my.Map.

func (TypeGeneric) Span

func (t TypeGeneric) Span() source.Span

Span implements source.Spanner.

type TypeGenericArgs

type TypeGenericArgs struct {
	Path          Path
	AngleBrackets token.Token
}

TypeGenericArgs is the arguments for [Context.NewTypeGeneric].

Generic arguments should be added after construction with [TypeGeneric.AppendComma].

type TypeKind

type TypeKind int8

TypeKind is a kind of type. There is one value of TypeKind for each Type* type in this package.

const (
	TypeKindInvalid TypeKind = iota
	TypeKindError
	TypeKindPath
	TypeKindPrefixed
	TypeKindGeneric
)

func (TypeKind) DecodeDynID

func (TypeKind) DecodeDynID(lo, hi int32) TypeKind

func (TypeKind) EncodeDynID

func (k TypeKind) EncodeDynID(value int32) (int32, int32, bool)

func (TypeKind) GoString

func (v TypeKind) GoString() string

GoString implements fmt.GoStringer.

func (TypeKind) String

func (v TypeKind) String() string

String implements fmt.Stringer.

type TypeList

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

TypeList is a Commas over a list of types surrounded by some kind of brackets.

Despite the name, TypeList does not implement TypeAny because it is not a type.

func (TypeList) AppendComma

func (d TypeList) AppendComma(value TypeAny, comma token.Token)

AppendComma implements Commas.

func (TypeList) At

func (d TypeList) At(n int) TypeAny

At implements seq.Indexer.

func (TypeList) Brackets

func (d TypeList) Brackets() token.Token

Brackets returns the token tree for the brackets wrapping the argument list.

May be zero, if the user forgot to include brackets.

func (TypeList) Comma

func (d TypeList) Comma(n int) token.Token

Comma implements Commas.

func (TypeList) Delete

func (d TypeList) Delete(n int)

Delete implements seq.Inserter.

func (TypeList) Insert

func (d TypeList) Insert(n int, ty TypeAny)

Insert implements seq.Inserter.

func (TypeList) InsertComma

func (d TypeList) InsertComma(n int, ty TypeAny, comma token.Token)

InsertComma implements Commas.

func (TypeList) Len

func (d TypeList) Len() int

Len implements seq.Indexer.

func (TypeList) SetAt

func (d TypeList) SetAt(n int, ty TypeAny)

SetAt implements seq.Setter.

func (TypeList) SetBrackets

func (d TypeList) SetBrackets(brackets token.Token)

SetBrackets sets the token tree for the brackets wrapping the argument list.

func (TypeList) SetComma

func (d TypeList) SetComma(n int, comma token.Token)

SetComma implements Commas.

func (TypeList) Span

func (d TypeList) Span() source.Span

Span implements source.Spanner.

type TypePath

type TypePath struct {
	// The path that refers to this type.
	Path
}

TypePath is a simple path reference as a type.

Grammar

TypePath := Path

func (TypePath) AsAny

func (t TypePath) AsAny() TypeAny

AsAny type-erases this type value.

See TypeAny for more information.

type TypePrefixed

type TypePrefixed id.Node[TypePrefixed, *File, *rawTypePrefixed]

TypePrefixed is a type with a [TypePrefix].

Unlike in ordinary Protobuf, the Protocompile AST permits arbitrary nesting of modifiers.

Grammar

TypePrefixed := (`optional` | `repeated` | `required` | `stream`) Type

Note that there are ambiguities when Type is an absolute TypePath. The source "optional .foo" names the type "optional.foo" only when inside of a TypeGeneric's brackets or a Signature's method parameters.

Also, the `stream` prefix may only occur inside of a Signature.

func (TypePrefixed) AsAny

func (t TypePrefixed) AsAny() TypeAny

AsAny type-erases this type value.

See TypeAny for more information.

func (TypePrefixed) Prefix

func (t TypePrefixed) Prefix() keyword.Keyword

Prefix extracts the modifier out of this type.

Returns keyword.Unknown if TypePrefixed.PrefixToken does not contain a known prefix.

func (TypePrefixed) PrefixToken

func (t TypePrefixed) PrefixToken() token.Token

PrefixToken returns the token representing this type's prefix.

func (TypePrefixed) SetType

func (t TypePrefixed) SetType(ty TypeAny)

SetType sets the expression that is being prefixed.

If passed zero, this clears the type.

func (TypePrefixed) Span

func (t TypePrefixed) Span() source.Span

Span implements source.Spanner.

func (TypePrefixed) Type

func (t TypePrefixed) Type() TypeAny

Type returns the type that is being prefixed.

type TypePrefixedArgs

type TypePrefixedArgs struct {
	Prefix token.Token
	Type   TypeAny
}

TypePrefixedArgs is the arguments for [Context.NewTypePrefixed].

Directories

Path Synopsis
Package edit applies declaration-level mutations to a Protobuf AST before it is rendered.
Package edit applies declaration-level mutations to a Protobuf AST before it is rendered.
Package predeclared provides all of the identifiers with a special meaning in Protobuf.
Package predeclared provides all of the identifiers with a special meaning in Protobuf.
Package printer renders an ast.File (or an individual ast.DeclAny) back to protobuf source text.
Package printer renders an ast.File (or an individual ast.DeclAny) back to protobuf source text.
Package syntax specifies all of the syntax pragmas (including editions) that Protocompile understands.
Package syntax specifies all of the syntax pragmas (including editions) that Protocompile understands.

Jump to

Keyboard shortcuts

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