pxf: @entry directive + zero-or-more named-directive prefix list - #16
Merged
Conversation
Enum value, message field, and oneof names that are case-sensitively equal to `null`, `true`, or `false` lex as PXF value keywords, making them unreachable from PXF surface syntax — `field = null` always resolves to the null-literal branch, and an enum value literally named `null` can never be selected by name. Protobuf does not reserve these identifiers, so today the trap is silent. Spec: new draft §3.13 "Schema Constraints" with MUST-language; ABNF `directive-name` widened to exclude `null`/`true`/`false` alongside `type`; grammar.ebnf gets a matching Schema Constraints notes block. Tooling: a single shared `internal/pxfschema` package exposes `ValidateReflect` (protoreflect) and `ValidateProto` (descriptorpb) so every binary in this repo inherits the check at descriptor-bind. `protoc-gen-pxf-java-meta` rejects in `generateFile`; `protowire` gains a `lint` subcommand for standalone use. Fixtures under `testdata/lint/` confirm protocompile accepts these names (i.e. the trap is real) and that the case-sensitive rule correctly accepts uppercase variants like `NULL`/`True`/`FALSE`. IETF draft pagination downstream of §3.13 has drifted; re-paginate before submission. Companion port PRs (protowire-go first) must add the equivalent check at their bind layer.
Generalizes `named_directive` from one optional prefix identifier to zero-or-more, then registers `@entry` as the first in-spec-defined named directive — the canonical PXF shape for bundling heterogeneous typed sub-messages alongside (or in place of) a document body. Four shapes are permitted: @entry { ... } ; anonymous, typeless @entry name { ... } ; labeled, typeless @entry some.pkg.Type { ... } ; typed only (dotted ident) @entry name some.pkg.Type { ... } ; labeled and typed The fourth disambiguates from the second by the presence of "." in the prefix identifier: dotted = type, undotted = label. Wire format unchanged. Strictly additive — any v0.72.0-valid named directive still parses. Ports MUST relax `named_directive` to accept zero-or-more prefix identifiers and MUST enforce `@entry`'s cardinality (0–2 prefix identifiers) at the consumer layer. Spec: grammar.ebnf `named_directive` uses `{ identifier }`; draft ABNF uses `*( 1*WSP identifier )`. New §3.4.3 ("The @entry Directive") defines the four shapes, the dot-disambiguation rule, order preservation, and inherits §3.13's reserved-name constraint. §3.4.2 rewritten to describe per-directive prefix-list semantics and the registered-vs-unrecognized cardinality split. Editor: VS Code TM grammar grows a `named-directive` pattern that highlights `@<name>` plus prefix identifiers (dotted → type; bare → tag). JetBrains bundle regenerated via sync script. Testdata: example-entries.pxf demonstrates all four shapes. Stacked on PR #15 (pxf-reserved-names) — depends on §3.13 for the reserved-name cross-reference in the new §3.4.3.
7 tasks
trendvidia
added a commit
that referenced
this pull request
May 11, 2026
New top-level directive form for representing many instances of a single message type in a single PXF document: @table <type> ( <col1>, <col2>, ... ) ( <val1>, <val2>, ... ) ( <val1>, <val2>, ... ) Each row binds positionally to the header column list. The three cell states map onto the existing pxf.required / pxf.default semantics (§6.1) without any new annotation: - empty cell (between two commas) → field absent - `null` literal → field present-but-null - any value literal → field present with value v1 restrictions: - cells are scalar-shaped (no list `[…]`, no block `{…}`) - column entries are unqualified field names (no dotted paths) - strict row arity: row arity MUST equal column count - standalone: a @table document carries neither @type nor body field-entries; the @table header IS the type declaration @table is consumer-interpreted (same side-channel pattern as @Header / @entry). Rows are accessed via a parser API distinct from the body's schema layer. The spec does NOT mandate a canonical "decode-as-`repeated <type>`" semantics. Wire format unchanged. Strictly additive: the new productions occupy fresh top-level surface; any prior-version-valid PXF document remains valid. Spec changes: grammar.ebnf adds table_directive / column_list / row / row_cell / row_value productions and extends directive_name to exclude 'table'. Draft §3.3 ABNF matches. New §3.4.4 defines syntax + semantics + conformance + the cell-grammar / column / arity / standalone restrictions normatively. Editor: VS Code TM grammar adds a `table-directive` pattern mirroring `type-directive`, plus paren punctuation rules. JetBrains bundle regenerated via sync_jetbrains_grammar.py. Testdata: example-table.pxf demonstrates the three cell states over test.v1.AllTypes; testdata/table/ contains seven adversarial fixtures (short/long arity, @type collision, body collision, list cell, block cell, dotted column) plus empty-rows acceptance. Conformance-harness wiring deferred (cross_security_check.sh is decode-corpus shaped; @table fixtures need a new tier). Stacked on PR #16 (pxf-entry-directive); also folds a forward-fix to PR #16's grammar.ebnf comment, which referenced "Section 3.4.4" for @entry instead of §3.4.3.
trendvidia
added a commit
that referenced
this pull request
May 11, 2026
New top-level directive form for representing many instances of a single message type in a single PXF document: @table <type> ( <col1>, <col2>, ... ) ( <val1>, <val2>, ... ) ( <val1>, <val2>, ... ) Each row binds positionally to the header column list. The three cell states map onto the existing pxf.required / pxf.default semantics (§6.1) without any new annotation: - empty cell (between two commas) → field absent - `null` literal → field present-but-null - any value literal → field present with value v1 restrictions: - cells are scalar-shaped (no list `[…]`, no block `{…}`) - column entries are unqualified field names (no dotted paths) - strict row arity: row arity MUST equal column count - standalone: a @table document carries neither @type nor body field-entries; the @table header IS the type declaration @table is consumer-interpreted (same side-channel pattern as @Header / @entry). Rows are accessed via a parser API distinct from the body's schema layer. The spec does NOT mandate a canonical "decode-as-`repeated <type>`" semantics. Wire format unchanged. Strictly additive: the new productions occupy fresh top-level surface; any prior-version-valid PXF document remains valid. Spec changes: grammar.ebnf adds table_directive / column_list / row / row_cell / row_value productions and extends directive_name to exclude 'table'. Draft §3.3 ABNF matches. New §3.4.4 defines syntax + semantics + conformance + the cell-grammar / column / arity / standalone restrictions normatively. Editor: VS Code TM grammar adds a `table-directive` pattern mirroring `type-directive`, plus paren punctuation rules. JetBrains bundle regenerated via sync_jetbrains_grammar.py. Testdata: example-table.pxf demonstrates the three cell states over test.v1.AllTypes; testdata/table/ contains seven adversarial fixtures (short/long arity, @type collision, body collision, list cell, block cell, dotted column) plus empty-rows acceptance. Conformance-harness wiring deferred (cross_security_check.sh is decode-corpus shaped; @table fixtures need a new tier). Stacked on PR #16 (pxf-entry-directive); also folds a forward-fix to PR #16's grammar.ebnf comment, which referenced "Section 3.4.4" for @entry instead of §3.4.3.
trendvidia
added a commit
that referenced
this pull request
May 11, 2026
Promote [Unreleased] entries to [0.73.0] – 2026-05-11 in advance of tagging v0.73.0 on this repo. Bundles three additive PXF text-format changes that landed via #15 / #16 / #17: - schema-level reserved-name rule (§3.13) - @entry bundle directive + zero-or-more prefix list (§3.4.3) - @table bulk-rows directive (§3.4.4) Wire format unchanged across all three. Spec-side counterpart to protowire-go v0.73.0 (companion release); ports adopting these features bump in lockstep to v0.73.0.
This was referenced May 12, 2026
trendvidia
added a commit
that referenced
this pull request
Jul 16, 2026
) Resolves spec issue #16 (GH #65) — the M4 blocker. - proto/schema/v1/report.proto: Report, EnrichedViolation, Violation, structured FieldPath (typed map-key subscripts), typed Value oneof. Runtime artifact emitted by engines; allocates no extension numbers. - google.protobuf.Value deliberately not used: folds int64 into double, cannot carry bytes, erases the set/null/absent distinction. - RuleKind values carry the RULE_KIND_ prefix: EntryKind.TYPE_REFINEMENT in descriptor.proto already claims the bare name in package enum scope. - RFC-001 §7 rewritten against the pinned shapes; §13 row 7 resolved. - testdata/schema-extensions/07_report_golden.textproto: golden Report for the §5.3 worked example, verified with stock protoc (parse + --encode/--decode round-trip).
trendvidia
added a commit
that referenced
this pull request
Jul 16, 2026
trendvidia
added a commit
that referenced
this pull request
Jul 16, 2026
trendvidia
added a commit
that referenced
this pull request
Jul 16, 2026
trendvidia
added a commit
that referenced
this pull request
Jul 16, 2026
trendvidia
added a commit
that referenced
this pull request
Jul 16, 2026
trendvidia
added a commit
that referenced
this pull request
Jul 16, 2026
* spec: finalize Literal carrier shape (RFC-001 §8.1) Resolves spec issue #15 (GH #64). In-place revision of the unreleased carrier — the deliberate pre-freeze window for wire-shape changes. - EnumLiteral {enum_type, value_name, number}: enum references lower RESOLVED; consumers never re-resolve bare names against a pool (replaces string enum_name). - ListLiteral becomes repeated LiteralValue: elements are values, not arguments — no names, no expressions representable; homogeneous kind required (same enum_type for enum elements); nesting legal. - Message literals stay google.protobuf.Any, with the explicit-typing rule pinned: type from the param declaration or an explicit use-site type name, never inferred from value shape; source spelling deferred to the IETF draft (#3). - RFC-001 §8.1 excerpt + lowering rules prose; §13 row 6 resolved; CHANGELOG notes the protocompile descriptor.pb.go re-vendor follow-up. - Fixtures: 10_literal_args.proto (schema-text: enum ref + list on any-typed params) and 11_literal_carrier_golden.textproto (lowered AnnotationList, all three kinds, protoc encode/decode-verified). * docs: record S1 resolutions (#11–#16) in RFC-001-issues.md Ticks the six open-question boxes and adds a resolution record to each section — GH #60–#65, PR train #94–#99 — with pointers to the follow-up trackers (protocompile#67/#68, GH #102/#103) and the fixtures 07–11.
trendvidia
added a commit
that referenced
this pull request
Jul 16, 2026
* spec: ratify RFC-001 (issue #56) Status Draft → Ratified (2026-07-16). §13 rows 13/14 now cite their tracking issues (GH #111, #112) — with those filed, every open question is either resolved in the RFC (S1: #11–#16; S2: #15 source grammar, #21 sensitivity, #35 path scheme; S3: #22 engine-expression scope, #23 no dual-emission) or tracked as a separate issue (GH #59, #66–#69, #103, #111, #112). All v1.2 surface is strictly additive; no locked decision blocks an existing port's roadmap (per-port adoption is M9+, gated on the conformance corpus). * docs: record #2 ratification (GH #56, PR #113)
trendvidia
added a commit
that referenced
this pull request
Jul 23, 2026
trendvidia
added a commit
that referenced
this pull request
Jul 23, 2026
… value violations (#125) (#126) * spec: EnrichedViolation.for_key — flag map-key violations (#125) A subscripted FieldPath map segment addresses the entry's *value*, so a map-key violation (e.g. a length rule on map<string, V> keys) and a value violation on the same entry serialized to identical paths, with neither RuleKind nor Violation.code required to disambiguate. Appending a pseudo-segment for the entry's synthetic key = 1 field would collide with a genuine 'key' field on message-typed map values. - proto/schema/v1/report.proto: bool for_key = 8 on EnrichedViolation; subscript comment notes value-addressing - RFC-001 §7: snippet + normative prose (engine MUST set for_key) - IETF draft -01: enrichment-table row + prose, wire-shape summary; date bumped, txt/xml regenerated - CHANGELOG: Unreleased entry Golden 07_report_golden.textproto unchanged: the §5.3 worked example has no map field; behavioral coverage lives in protocheck (trendvidia/protocheck#24). * docs: RFC-001-issues.md — record #125 resolution under #16 (PR #126)
This was referenced Jul 23, 2026
This was referenced Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
named_directivefrom[ identifier ]to{ identifier }(zero-or-more prefix identifiers). Any v0.72.0-valid named directive still parses; the change is strictly additive.@entry(new draft §3.4.3) as the canonical PXF shape for bundling heterogeneous typed sub-messages — four permitted shapes covering anonymous/labeled × typed/typeless. Dot-disambiguation rule: dotted prefix → type; bare → label.named-directivepattern (dotted = type, bare = tag); JetBrains bundle regenerated.Stacking
Based on
pxf-reserved-names(PR #15). The new §3.4.3 cross-references §3.13 (reserved-name constraint), so this lands after PR #15 merges. GitHub auto-rebases the base on merge.Tradeoffs / open items
named_directivefrom "accept one optional identifier" to "loop accepting identifiers until{or end-of-directive" — ~1 LoC in most ports. Plus consumer-layer enforcement of@entry's 0–2 cardinality cap. First-port companion PR lands onprotowire-go.@entry "" some.Type) — is uglier. Worth re-litigating only if real users hit edge cases (e.g. wanting a dotted label).@entryspecifically at two. That's a deliberate two-layer split — the grammar generalizes, individual registrations constrain. Documented in §3.4.2 conformance bullets.Test plan
go build ./...— cleantestdata/example-entries.pxfexercises all four@entryshapessync_jetbrains_grammar.pywhich round-trips through plistlib)testdata/example-entries.pxfin VS Code with the local extension and verify highlighting on@entry, the optional label, and the dotted typeprotowire-pxf.jarrefresh sequenced into release-cut PR)