Add descriptor-aware PROTO/ENUM formatting plugins#151
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the protofmt package, which provides opt-in, descriptor-aware formatting plugins for Spanner PROTO and ENUM values. Feedback focuses on improving GoDoc link resolution on pkg.go.dev by using fully qualified paths and receiver types, as well as optimizing lookup performance on the hot path by filtering out nil resolvers during construction in ComposeProtoEnumResolvers to avoid reflection overhead.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
apstndb
left a comment
There was a problem hiding this comment.
Reviewed against the issue #149 acceptance criteria, with the branch checked out locally (go test ./protofmt/, make lint both pass).
This is a clean, well-scoped implementation. Highlights:
protofmtsubpackage keepsdynamicpb/protodescout of the root import graph for users who don't need descriptor-aware display.- Resolver-first API;
ProtoEnumResolveris satisfied by both*dynamicpb.Typesand*protoregistry.Types, and is directly assignable toproto.UnmarshalOptions.Resolver/prototext.MarshalOptions.Resolver(verified by compile-timevar _assertions). - The prototext-instability concern is handled correctly: docs say output is not byte-stable, and the dynamic-message test uses unmarshal +
proto.Equalround-trip rather than string comparison. ComposeProtoEnumResolverssemantics (exact-NotFoundto continue, wrapped errors surfaced, exactNotFoundwhen all miss) match the spec and are well covered.- Defensive details are good: int32 enum-range guard, typed-nil resolver detection,
stringWirevalue-kind validation.
I separately verified that dynamicpb.Types and protoregistry.GlobalTypes both return the exact protoregistry.NotFound sentinel (not wrapped) for all five lookup methods, so the == comparison in isExactNotFound is correct in practice.
A few minor/optional comments inline; none are blocking.
apstndb
left a comment
There was a problem hiding this comment.
Reviewed the PR against issue #149 and the existing review threads. The implementation is generally clean and go test ./protofmt, make lint, and make check pass locally. I left two non-blocking inline comments: one coverage gap around proving resolver wiring through Any/extensions, and one API-surface question for enum-only custom resolvers.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the protofmt package, which provides descriptor-aware PROTO and ENUM formatting plugins for spanvalue format configs, along with corresponding documentation and tests. The review feedback focuses on performance optimizations: pre-configuring marshal/unmarshal options and performing reflection-based nil resolver checks at construction time rather than repeatedly during cell formatting in FormatProtoTextValue and FormatEnumNameValue, and returning the single active resolver directly in ComposeProtoEnumResolvers to avoid delegation overhead.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the protofmt package, which provides descriptor-aware PROTO and ENUM formatting plugins for spanvalue format configurations, along with comprehensive unit tests. The reviewer feedback highlights opportunities to improve robustness by adding defensive nil checks for resolved message and enum types to prevent panics from buggy resolvers, and suggests an optimization in ComposeProtoEnumResolvers when no active resolvers are provided.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a new package protofmt which provides opt-in, descriptor-aware PROTO and ENUM formatting plugins for spanvalue format configurations. It includes interfaces and implementations for resolving protobuf message and enum types, formatting functions (FormatProtoTextValue and FormatEnumNameValue), helper functions to compose resolvers, and comprehensive unit tests. Documentation and README files have been updated accordingly. There are no review comments, and I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the protofmt package, which provides opt-in, descriptor-aware PROTO and ENUM formatting plugins for spanvalue format configurations. It includes implementation files, comprehensive unit tests, and updates to the project's documentation (README.md and doc.go) to describe the new package and its usage. I have no feedback to provide as there are no review comments to assess.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
apstndb
left a comment
There was a problem hiding this comment.
Re-review of the updated branch (HEAD c22c151). Checked out locally; make lint -> 0 issues, go test ./protofmt/ -> ok.
All four of my earlier comments are resolved, and the follow-up performance/hardening pass is solid:
- Resolver wiring proven, not just asserted.
TestFormatProtoTextValue_usesMarshalResolverForAnyExpansionnow demonstratesmarshal.Resolveractually drivesgoogle.protobuf.Anyexpansion via a dynamicEnvelope{ Any }descriptor. Nice — this is much stronger than the original round-trip-only coverage. - GlobalTypes missing-type path now has explicit
ErrFallthroughcases for both PROTO and ENUM, closing the coverage gap I flagged. I independently re-confirmeddynamicpb.Typesandprotoregistry.GlobalTypesreturn the exactprotoregistry.NotFoundsentinel for all five lookups, soisExactNotFound's==remains correct. - Hot-path refactor is clean. Hoisting
isNilResolver+unmarshal/marshal.Resolversetup to construction time (two-closure split) removes per-value reflection and option copies without changing behavior. ThemessageType == nil/enumType == nilguards plus their tests are good defense against contract-violating custom resolvers. - Compose filtering nil resolvers at construction, returning the single active resolver directly, and the empty-
compositeResolverNotFound fallback are all well covered. EnumResolversegregation, docGlobalTypes/blank-import note, and the README multiline-newline caveat all landed.
No blocking issues. One optional follow-up inline; otherwise this LGTM from my side. (Gemini's two most recent reviews also report no remaining feedback.)
Nit (optional, not worth a separate change on its own): the typed-NULL guard preamble (code != X -> fallthrough, IsNull -> GetNullString) is now duplicated across the nil-resolver and active closures in both plugins (4 copies). If it ever grows, a small shared guard helper would prevent drift.
Summary
protofmtpackage with opt-in descriptor-aware PROTO and ENUM formatting plugins.ProtoEnumResolversupport remains available for PROTO, extension lookup,Anyexpansion, and resolver composition.protoregistry.GlobalTypes, resolver semantics, malformed wire payloads, enum fallback, protobuf option resolver wiring, and nested ARRAY/STRUCT dispatch.Fixes #149.
Testing
go test ./protofmtgo test ./...make check