pxf

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: May 13, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package pxf implements the PXF text format codec for protobuf messages.

PXF (Protocol-buffer eXchange Format) is a human-editable, comment-aware text encoding for protobuf messages. The format spec, grammar, and canonical fixtures live in the sibling repository trendvidia/protowire; this package is the Go reference implementation.

Choosing a code path

Three top-level entry points serve different needs:

  • Unmarshal / Marshal — fast path. A fused single-pass lexer+decoder writes directly into the google.golang.org/protobuf/proto.Message with zero-copy token strings and no AST allocations. Use this in hot paths or when you do not need the source comments.
  • UnmarshalFull — like Unmarshal but returns a Result tracking which fields were set, null, or absent, validating required fields, and applying defaults from (pxf.required) / (pxf.default) annotations.
  • Parse / FormatDocument — AST path. Produces a Document with comments attached to entries. Use when you need to round-trip a PXF document while preserving its formatting and comments.

Concurrency

The package-level functions (Unmarshal, Marshal, Parse, FormatDocument) are safe for concurrent use — they do not share mutable state. The MarshalOptions and UnmarshalOptions value types are also safe to share, provided the TypeResolver embedded in them is concurrency-safe (the registry-client resolver from trendvidia/protoregistry is).

A Result returned from UnmarshalFull is not safe for concurrent modification, but read-only access from multiple goroutines is fine.

Index

Constants

View Source
const MaxNestingDepth = 100

MaxNestingDepth caps PXF block / list nesting and PB submessage nesting, per protowire/docs/HARDENING.md § Recursion. The limit applies to the recursive-descent decoders for both formats; iterative skip routines (skipBraced/skipBracketed) use the same cap implicitly because they only run on already-bounded inputs.

Variables

View Source
var ErrNoDataset = errors.New("pxf: no @dataset directive in stream")

ErrNoDataset is returned by NewDatasetReader when the input contains no @dataset directive before EOF. Inspect with errors.Is.

Functions

func ApplyDefault added in v0.71.0

func ApplyDefault(msg protoreflect.Message, fd protoreflect.FieldDescriptor, def string) error

ApplyDefault parses a (pxf.default) value string and sets it on the given message field. The string is the same PXF literal form the annotation accepts: `42` for ints, `true`/`false` for bools, `"hello"` for strings, base64 for bytes, RFC3339 for timestamps inside their inner fields, etc.

Exported for layered-config consumers (e.g. chameleon) that run a post-merge defaults pass with [UnmarshalOptions.SkipPostDecode]. In-tree callers (postDecode) use the lowercase alias.

func BindRow added in v0.75.0

func BindRow(msg proto.Message, columns []string, row DatasetRow) error

BindRow binds row.Cells to the fields of msg by column name. The columns slice MUST have the same length as row.Cells; mismatch is a programmer error and panics.

Exported so callers iterating the materializing path's Result.Datasets()[i].Rows can reuse the same logic. Same cell-state semantics as DatasetReader.Scan.

func Default added in v0.71.0

func Default(fd protoreflect.FieldDescriptor) (string, bool)

Default returns the (pxf.default) value string if set. The string is a PXF literal (e.g. `42`, `true`, `"hello"`); callers parse it with ApplyDefault or their own logic. Exported for layered-config consumers running post-merge defaults passes.

func FormatDocument

func FormatDocument(doc *Document) []byte

FormatDocument pretty-prints an AST Document, preserving comments. Unlike Marshal (which works from a proto.Message and loses comments), this formats directly from the parsed AST.

func IsRequired added in v0.71.0

func IsRequired(fd protoreflect.FieldDescriptor) bool

IsRequired reports whether the field has (pxf.required) = true. Exported for layered-config consumers (e.g. chameleon) that run their own post-merge required-validation pass with SkipPostDecode.

func Marshal

func Marshal(msg proto.Message) ([]byte, error)

Marshal formats msg as PXF text with default options.

func Unmarshal

func Unmarshal(data []byte, msg proto.Message) error

Unmarshal parses PXF data into msg with default options.

func UnmarshalDescriptor

func UnmarshalDescriptor(data []byte, desc protoreflect.MessageDescriptor) (*dynamicpb.Message, error)

UnmarshalDescriptor parses PXF data using the given message descriptor.

Types

type Assignment

type Assignment struct {
	Pos             Position
	Key             string
	Value           Value
	LeadingComments []Comment // comments on lines before this entry
	TrailingComment string    // inline comment after value on same line
}

Assignment represents "key = value" (field assignment in message context).

type Block

type Block struct {
	Pos             Position
	Name            string
	Entries         []Entry
	LeadingComments []Comment
}

Block represents "name { entries }" (nested message).

type BlockVal

type BlockVal struct {
	Pos     Position
	Entries []Entry
}

BlockVal is an anonymous block value: { entries }. Used for maps (key: value pairs) and inline messages in lists.

type BoolVal

type BoolVal struct {
	Pos   Position
	Value bool
}

BoolVal is a boolean literal (true / false).

type BytesVal

type BytesVal struct {
	Pos   Position
	Value []byte
}

BytesVal is a base64-encoded bytes literal (b"...").

type Comment

type Comment struct {
	Pos  Position
	Text string // raw text including the comment prefix (# or // or /* */)
}

Comment represents a comment in source text.

type DatasetDirective added in v1.0.0

type DatasetDirective struct {
	Pos             Position
	Type            string       // row message type, e.g. "trades.v1.Trade"; empty if bound to a preceding anonymous @proto
	Columns         []string     // top-level field names on Type; len(Columns) >= 1
	Rows            []DatasetRow // zero or more rows
	LeadingComments []Comment
}

DatasetDirective is a `@dataset <type> ( col1, col2, ... ) row*` entry at document root (draft §3.4.4). It carries many instances of one message type in a single document — the protowire-native CSV.

Cells are scalar-shaped in v1: list ('[ ... ]') and block ('{ ... }') values are not permitted in cells. An empty cell (no value between commas) denotes an absent field; a `null` literal denotes a present- but-null field; any other value denotes a present field with that value. See DatasetRow for cell representation.

A document with any DatasetDirective MUST NOT have a @type directive or any top-level field entries: the @dataset header IS the document's type declaration. Decoders enforce this in Parse.

Type MAY be empty when an anonymous @proto directive (draft §3.4.5) precedes the @dataset in document order; the anonymous schema is consumed as the row message type.

type DatasetReader added in v1.0.0

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

DatasetReader streams rows of a single `@dataset` directive from an io.Reader (draft §3.4.4 "Streaming consumption"). Use it for datasets too large to materialize via Parse / UnmarshalFull.

A DatasetReader is positioned at the first row after NewDatasetReader returns. Call DatasetReader.Next in a loop until it returns io.EOF; the table's row sequence is exhausted at that point.

For documents containing multiple `@dataset` directives, call NewDatasetReader again on the same underlying io.Reader to read the next table — the previous reader leaves the underlying reader positioned just past its last row.

A DatasetReader is NOT safe for concurrent use.

func NewDatasetReader added in v1.0.0

func NewDatasetReader(r io.Reader) (*DatasetReader, error)

NewDatasetReader consumes any leading directives (`@type`, `@<name>`, etc.) and the `@dataset TYPE ( cols )` header, returning a reader positioned at the first row.

Returns ErrNoDataset if the input ends before any `@dataset` directive is seen. Returns a wrapped parse/IO error otherwise.

The header (everything from the start of the input up through and including the `)` of the column list) must fit in 64 KiB. This is a fail-fast bound — real headers are tiny.

func (*DatasetReader) Columns added in v1.0.0

func (tr *DatasetReader) Columns() []string

Columns returns the column field names declared by the @dataset header, in source order.

func (*DatasetReader) Directives added in v1.0.0

func (tr *DatasetReader) Directives() []Directive

Directives returns the side-channel directives (`@<name>` / `@entry` / etc., NOT `@type` or `@dataset`) that appeared before the `@dataset` header. The slice is stable for the lifetime of the reader. Useful for consumers that attach per-table metadata via a preceding directive.

func (*DatasetReader) Next added in v1.0.0

func (tr *DatasetReader) Next() (DatasetRow, error)

Next reads the next row. Returns io.EOF when the table's row sequence is exhausted. After EOF (or any other error), all subsequent calls return the same error.

The returned DatasetRow's Cells slice is freshly allocated and owned by the caller; reading the next row does not invalidate it.

func (*DatasetReader) Scan added in v1.0.0

func (tr *DatasetReader) Scan(msg proto.Message) error

Scan reads the next row and binds its cells to the matching fields of msg by column name. Returns io.EOF when the row sequence is exhausted; returns the same sticky error as DatasetReader.Next on any read or parse failure.

msg's descriptor MUST resolve the field names this reader's Columns() list refers to. Type compatibility against the @dataset header's declared type is the caller's responsibility — a row whose columns don't match msg's fields surfaces as a per-field "field not found" or type-mismatch error from the underlying Unmarshal call.

Cell-state semantics (mirrors draft §3.4.4):

  • nil Value (empty cell) — field absent. (pxf.default) is applied if declared on the field; (pxf.required) errors if neither default nor value is present.
  • *NullVal — field cleared, per §3.9 (clears optional / wrapper / oneof; rejects on non-nullable scalars).
  • any other Value — field set to that value.

func (*DatasetReader) Tail added in v1.0.0

func (tr *DatasetReader) Tail() io.Reader

Tail returns an io.Reader that yields the bytes the DatasetReader has buffered but not consumed, followed by any remaining bytes from the underlying source. Use it to chain a second NewDatasetReader call for documents containing multiple `@dataset` directives:

tr1, err := pxf.NewDatasetReader(src)
// ... iterate tr1.Next() to io.EOF ...
tr2, err := pxf.NewDatasetReader(tr1.Tail())

Tail MUST only be called after Next has returned io.EOF. Calling it earlier returns bytes the current reader still intends to consume, which will desync the next reader. The returned io.Reader is unbuffered; consumers needing bufio semantics should wrap it themselves.

func (*DatasetReader) Type added in v1.0.0

func (tr *DatasetReader) Type() string

Type returns the row message type declared by the @dataset header (e.g. "trades.v1.Trade").

type DatasetRow added in v1.0.0

type DatasetRow struct {
	Pos   Position
	Cells []Value // nil entries denote absent fields; len == len(dataset.Columns)
}

DatasetRow is one parenthesized cell tuple in a @dataset directive. Cells is the same length as the containing DatasetDirective.Columns. A nil Value in Cells denotes an absent field (the "empty cell" between two commas); a *NullVal denotes a present-but-null field; any other Value denotes a present field with that value.

type Directive added in v0.72.0

type Directive struct {
	Pos      Position
	Name     string   // e.g. "header"; never "type" (those go to Document.TypeURL)
	Prefixes []string // identifiers between @<name> and the optional `{ ... }`, in source order
	// Type is preserved for v0.72.0-era consumers: when exactly one
	// prefix identifier was supplied, Type holds it (matching the
	// previous single-Type field's behavior). For zero or two-plus
	// prefixes, Type is empty and callers MUST read Prefixes directly.
	// New code should use Prefixes; Type is retained to avoid churning
	// downstream consumers that haven't migrated.
	Type            string
	Body            []byte // raw inner bytes of the block; nil if the directive has no `{ ... }`
	LeadingComments []Comment
}

Directive is a top-of-document `@<name> *(<prefix-id>) [{ ... }]` entry. The canonical use is side-channel metadata that sits alongside the schema-typed body — e.g. chameleon's `@header chameleon.v1.LayerHeader { id = "x" }` — but the grammar is open-ended: any name except `type` is accepted, followed by zero-or-more prefix identifiers and an optional inline block.

Prefix identifiers are positional and per-directive. The two registrations defined by the protowire spec:

  • One prefix identifier (v0.72.0 conventional shape) — the identifier names the inner block's message type, dotted. Used by `@header` and similar.
  • `@entry` (draft §3.4.3) — zero, one, or two prefix identifiers (label, type); a single prefix is disambiguated by the presence of a `.` (dotted ⇒ type; bare ⇒ label).

Body holds the RAW bytes between the opening `{` and matching `}` (both exclusive), suitable for handing back to UnmarshalFull / Unmarshal against the consumer's chosen message. Body is nil when the directive has no inline block.

type Document

type Document struct {
	TypeURL         string             // from @type directive, may be empty
	Directives      []Directive        // @<name> *(prefix) [{ ... }] entries before the body, in source order; excludes spec-defined directives
	Datasets        []DatasetDirective // @dataset directives in source order; per draft §3.4.4 a document with any @dataset MUST NOT have @type or body entries
	Protos          []ProtoDirective   // @proto directives in source order (draft §3.4.5)
	BodyOffset      int                // byte offset in the input where the schema-typed body begins (after all leading directives)
	Entries         []Entry
	LeadingComments []Comment // comments before the first entry (or after @type)
}

Document is the root AST node of a PXF file.

func Parse

func Parse(input []byte) (*Document, error)

Parse parses PXF source into an AST Document with comments attached.

type DurationVal

type DurationVal struct {
	Pos   Position
	Value time.Duration
	Raw   string
}

DurationVal is a Go-style duration literal (e.g. 30s, 1h30m).

type Entry

type Entry interface {
	// contains filtered or unexported methods
}

Entry is a node that can appear in a message or map body.

type Error

type Error struct {
	Pos Position
	Msg string
}

Error represents a parse or decode error with source position.

func (*Error) Error

func (e *Error) Error() string

type FloatVal

type FloatVal struct {
	Pos Position
	Raw string
}

FloatVal is a floating-point literal.

type IdentVal

type IdentVal struct {
	Pos  Position
	Name string
}

IdentVal is an unquoted identifier used as a value (enum names).

type IntVal

type IntVal struct {
	Pos Position
	Raw string
}

IntVal is an integer literal (raw text, decoded later by schema).

type ListVal

type ListVal struct {
	Pos      Position
	Elements []Value
}

ListVal is a list value: [elem, elem, ...].

type MapEntry

type MapEntry struct {
	Pos             Position
	Key             string
	Value           Value
	LeadingComments []Comment
	TrailingComment string
}

MapEntry represents "key: value" (entry in map context).

type MarshalOptions

type MarshalOptions struct {
	Indent       string       // indentation per level, default "  "
	EmitDefaults bool         // emit fields with zero values
	TypeURL      string       // emit @type directive if non-empty
	TypeResolver TypeResolver // resolve Any type URLs for sugar encoding
	NullFields   *Result      // emit null fields from a Result (for messages without null_mask)
}

MarshalOptions configures PXF encoding.

func (MarshalOptions) Marshal

func (o MarshalOptions) Marshal(msg proto.Message) ([]byte, error)

Marshal formats msg as PXF text.

type NullVal

type NullVal struct {
	Pos Position
}

NullVal represents an explicit null literal.

type Position

type Position struct {
	Line   int
	Column int
	Offset int
}

Position represents a location in source text.

Offset is the byte index into the input where the token starts. It is populated by the lexer and used by callers that need to slice the original byte stream (e.g. directive body extraction).

func (Position) String

func (p Position) String() string

type ProtoDirective added in v1.0.0

type ProtoDirective struct {
	Pos             Position
	Shape           ProtoShape
	TypeName        string // dotted message type name; non-empty only when Shape == ProtoNamed
	Body            []byte
	LeadingComments []Comment
}

ProtoDirective is a `@proto <body>` entry at document root (draft §3.4.5). It carries an embedded protobuf schema, making the PXF document self-describing.

The Shape field distinguishes the four lexically-determined body forms (anonymous, named, source, descriptor). Body holds the raw bytes of the body, interpreted per Shape:

  • ProtoAnonymous, ProtoNamed: the bytes between the opening `{` and matching `}` (both exclusive). The bytes are protobuf message-body source (field declarations and nested types) and must be compiled by a downstream consumer.
  • ProtoSource: the contents of the triple-quoted string (with leading-LF stripping and common-prefix dedent already applied). The bytes are a complete .proto source file.
  • ProtoDescriptor: the base64-decoded bytes of the bytes literal. The bytes are a serialised google.protobuf.FileDescriptorSet.

type ProtoShape added in v1.0.0

type ProtoShape int

ProtoShape distinguishes the four body shapes of a @proto directive (draft §3.4.5).

const (
	// ProtoAnonymous is `@proto { <message-body> }` — defines an
	// unnamed message used by the next typed directive in document
	// order that does not carry an explicit type name.
	ProtoAnonymous ProtoShape = iota
	// ProtoNamed is `@proto <dotted-name> { <message-body> }` — sugar
	// for a single named message; TypeName carries the dotted name.
	ProtoNamed
	// ProtoSource is `@proto """<proto-source>"""` — a complete
	// Protocol Buffers source file.
	ProtoSource
	// ProtoDescriptor is `@proto b"<base64-FileDescriptorSet>"` —
	// a base64-encoded google.protobuf.FileDescriptorSet.
	ProtoDescriptor
)

func (ProtoShape) String added in v1.0.0

func (s ProtoShape) String() string

type Result

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

Result captures field-level presence metadata from PXF decoding. It tracks which fields were explicitly set, which were set to null, and which were absent from the input. Fields are identified by dotted paths (e.g., "name", "nested.value").

func UnmarshalFull

func UnmarshalFull(data []byte, msg proto.Message) (*Result, error)

UnmarshalFull decodes PXF data into msg and returns field presence metadata. Unlike Unmarshal, it tracks which fields are set, null, or absent, validates required fields, and applies default values.

func UnmarshalFullDescriptor

func UnmarshalFullDescriptor(data []byte, desc protoreflect.MessageDescriptor) (*dynamicpb.Message, *Result, error)

UnmarshalFullDescriptor parses PXF data using the given message descriptor and returns field presence metadata. It validates required fields and applies defaults.

func (*Result) Datasets added in v1.0.0

func (r *Result) Datasets() []DatasetDirective

Datasets returns the `@dataset` directives the decoder saw at the document root, in source order. Each DatasetDirective carries a row message type, a column list, and a sequence of row tuples. See draft §3.4.4 for cell-state semantics.

A document that uses `@dataset` will have an empty body — the rows are the document's payload, not the bound message. Callers walk each DatasetDirective.Rows and bind each row's cells to a fresh instance of DatasetDirective.Type via the consumer-supplied schema.

func (*Result) Directives added in v0.72.0

func (r *Result) Directives() []Directive

Directives returns the `@<name> *(prefix) [{ ... }]` blocks the decoder saw at the document root, in source order. Excludes the spec-defined directives (`@type`, `@dataset`, `@proto`, `@entry`), which have their own accessors. Callers typically iterate and call UnmarshalFull on each Directive.Body against their chosen message.

func (*Result) IsAbsent

func (r *Result) IsAbsent(path string) bool

IsAbsent reports whether the field at the given path was not mentioned in the input.

func (*Result) IsNull

func (r *Result) IsNull(path string) bool

IsNull reports whether the field at the given path was explicitly set to null. Use dotted paths for nested fields: "nested.value".

func (*Result) IsSet

func (r *Result) IsSet(path string) bool

IsSet reports whether the field at the given path was set to a concrete (non-null) value.

func (*Result) NullFields

func (r *Result) NullFields() []string

NullFields returns the paths of all fields explicitly set to null.

func (*Result) PresentFields added in v0.71.0

func (r *Result) PresentFields() []string

PresentFields returns the paths of all fields encountered during parsing — both fields set to a concrete value and fields set to null. Equivalent to the union of Result.IsSet and Result.IsNull paths.

Useful for layered-config systems (chameleon) that union per-layer presence into a merged-result presence set, then run defaults / required-validation against that union.

func (*Result) Protos added in v1.0.0

func (r *Result) Protos() []ProtoDirective

Protos returns the `@proto` directives the decoder saw at the document root, in source order. Each ProtoDirective carries one of four body shapes (anonymous, named, source, descriptor) per draft §3.4.5; callers inspect Shape and decode Body accordingly.

type StringVal

type StringVal struct {
	Pos   Position
	Value string
}

StringVal is a quoted string literal.

type TimestampVal

type TimestampVal struct {
	Pos   Position
	Value time.Time
	Raw   string
}

TimestampVal is an RFC 3339 timestamp literal.

type Token

type Token struct {
	Kind  TokenKind
	Value string
	Pos   Position
}

Token is a lexical token with its kind, raw value, and source position.

type TokenKind

type TokenKind int

TokenKind represents the type of a lexical token.

const (
	EOF     TokenKind = iota
	ILLEGAL           // invalid token
	NEWLINE           // \n
	COMMENT           // # or // or /* */

	IDENT     // field_name, EnumValue, package.Name
	STRING    // "hello" or """multi-line"""
	INT       // 123, -456
	FLOAT     // 1.23, -4.5
	BOOL      // true, false
	NULL      // null
	BYTES     // b"base64..."
	TIMESTAMP // 2024-01-15T10:30:00Z
	DURATION  // 30s, 1h30m

	LBRACE   // {
	RBRACE   // }
	LBRACKET // [
	RBRACKET // ]
	LPAREN   // (   used by @dataset column list and row tuples
	RPAREN   // )
	EQUALS   // =
	COLON    // :
	COMMA    // ,

	AT_TYPE      // @type — body's message type, no inline block
	AT_DATASET   // @dataset — row-oriented bulk-data directive (draft §3.4.4)
	AT_PROTO     // @proto — embedded protobuf schema (draft §3.4.5)
	AT_DIRECTIVE // @<name> for any non-reserved name — Value holds the name (without @)
)

func (TokenKind) String

func (k TokenKind) String() string

type TypeResolver

type TypeResolver interface {
	FindMessageByURL(url string) (protoreflect.MessageDescriptor, error)
}

TypeResolver resolves protobuf type URLs to message descriptors. Required for encoding/decoding google.protobuf.Any fields with sugar syntax.

type UnmarshalOptions

type UnmarshalOptions struct {
	// TypeResolver resolves type URLs for google.protobuf.Any fields.
	// When set, Any fields use sugar syntax: @type = "..." + inline fields.
	// When nil, Any fields decode as regular messages (type_url + value).
	TypeResolver TypeResolver

	// DiscardUnknown silently skips fields not found in the schema
	// instead of returning an error.
	DiscardUnknown bool

	// SkipPostDecode disables the per-parse pass that applies
	// (pxf.default) values to absent fields and validates
	// (pxf.required) fields. Layered configuration systems (e.g.
	// chameleon) need defaults + required to apply on the MERGED
	// result, not per-layer — a base layer may legitimately omit a
	// required field that a higher layer provides, and per-layer
	// defaults silently get clobbered by merge's "absent → fall
	// through" rule. With SkipPostDecode = true, callers get raw
	// presence tracking and run their own post-merge passes via
	// [IsRequired] and [Default].
	SkipPostDecode bool

	// SkipValidate disables the per-call schema reserved-name check
	// (draft §3.13). The default behavior — running the check on every
	// decode call — is the safe one because the check catches schemas
	// that would silently produce unreachable enum values or fields.
	// Callers that have already validated their descriptors out-of-band
	// (e.g. a registry-load step that pre-screens schemas before
	// caching their descriptors) may set this to bypass the per-call
	// recheck. Validate explicitly via [ValidateDescriptor] when
	// pre-screening.
	SkipValidate bool

	// OnSecretField, if non-nil, is called for each pxf.Secret-typed
	// field whose value is supplied via scalar shorthand (the common
	// form: `pw = "x"`, list element `["a", "b"]`, map value
	// `{ "acme": "k" }`). The hook receives the dotted field path and
	// the value string. When the hook returns nil, the decoder skips
	// the standard assignment to the inner `value` field on the Secret
	// message — the caller is responsible for routing the value to
	// whatever destination honors its own memory-management contract
	// (e.g. a memguard Enclave). Presence tracking on `value` is still
	// updated so Result.IsSet reports the field as set.
	//
	// Path scheme:
	//
	//   pw = "x"                           → "pw"
	//   db { password = "x" }              → "db.password"
	//   backup_keys = ["a", "b"]           → "backup_keys[0]", "backup_keys[1]"
	//   tenant_keys = { "acme": "k" }      → "tenant_keys[acme]"
	//
	// Block-form Secrets — `pw { value = "x", hint = "h" }` — are NOT
	// routed through this hook in this release; their value still lands
	// on Secret.Value via the standard string-field path. Callers that
	// need a closed memory window for block-form secrets should
	// post-process the message (e.g. chameleon's parse.Move walker) or
	// normalize their PXF to scalar shorthand. Hint and fingerprint
	// metadata are always assigned to the proto message; they are
	// diagnostic, not sensitive.
	//
	// Errors from the hook abort the decode and propagate.
	OnSecretField func(path, value string) error
}

UnmarshalOptions configures PXF decoding.

func (UnmarshalOptions) Unmarshal

func (o UnmarshalOptions) Unmarshal(data []byte, msg proto.Message) error

Unmarshal parses PXF data into msg.

func (UnmarshalOptions) UnmarshalDescriptor

func (o UnmarshalOptions) UnmarshalDescriptor(data []byte, desc protoreflect.MessageDescriptor) (*dynamicpb.Message, error)

UnmarshalDescriptor parses PXF data using the given message descriptor.

func (UnmarshalOptions) UnmarshalFull

func (o UnmarshalOptions) UnmarshalFull(data []byte, msg proto.Message) (*Result, error)

UnmarshalFull decodes PXF data into msg and returns field presence metadata.

func (UnmarshalOptions) UnmarshalFullDescriptor

func (o UnmarshalOptions) UnmarshalFullDescriptor(data []byte, desc protoreflect.MessageDescriptor) (*dynamicpb.Message, *Result, error)

UnmarshalFullDescriptor parses PXF data using the given message descriptor and returns field presence metadata.

type Value

type Value interface {
	// contains filtered or unexported methods
}

Value is an expression on the right side of = or :.

type Violation added in v0.75.0

type Violation struct {
	// File is the .proto file path the offending element is declared in.
	File string
	// Element is the fully-qualified protobuf name of the element
	// (e.g. "trades.v1.Side.null").
	Element string
	// Name is the bare reserved identifier ("null" / "true" / "false").
	Name string
	// Kind is the kind of element that collided.
	Kind ViolationKind
}

Violation describes one schema element whose name collides with a reserved PXF keyword. Returned by ValidateDescriptor.

func ValidateDescriptor added in v0.75.0

func ValidateDescriptor(desc protoreflect.MessageDescriptor) []Violation

ValidateDescriptor walks the file containing desc and returns every reserved-name collision among messages, oneofs, and enum values reachable from that file. The returned slice is sorted by element fully-qualified name for stable output. A nil/empty slice means the schema is conformant.

The check is case-sensitive: identifiers such as "NULL" or "True" lex as ordinary identifiers and are accepted.

func ValidateFile added in v0.75.0

func ValidateFile(fd protoreflect.FileDescriptor) []Violation

ValidateFile walks fd and returns every reserved-name collision in the file. See ValidateDescriptor for the rule and semantics.

func (Violation) String added in v0.75.0

func (v Violation) String() string

String renders a one-line human-readable description of v.

type ViolationKind added in v0.75.0

type ViolationKind int

ViolationKind identifies which kind of schema element collides with a reserved PXF value keyword.

const (
	// ViolationField is a message field whose name is reserved.
	ViolationField ViolationKind = iota + 1
	// ViolationOneof is a oneof declaration whose name is reserved.
	ViolationOneof
	// ViolationEnumValue is an enum value whose name is reserved.
	ViolationEnumValue
)

func (ViolationKind) String added in v0.75.0

func (k ViolationKind) String() string

Jump to

Keyboard shortcuts

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