feat: field metadata option + cross-language registry generators (supersedes #905)#952
Draft
jamesarich wants to merge 1 commit into
Draft
feat: field metadata option + cross-language registry generators (supersedes #905)#952jamesarich wants to merge 1 commit into
jamesarich wants to merge 1 commit into
Conversation
|
The latest Buf updates on your PR. Results from workflow pull-request / build (pull_request).
|
13cb74f to
c52ced6
Compare
Contributor
Author
|
Heads-up on the red |
Introduces a structured (meshtastic.field_metadata) custom field option and build-time generators that expose it as reflection-free static accessors in every consumer language: KMP/Wire (Wire SchemaHandler in packages/kmp/buildSrc) and C/Python/TypeScript/Rust/Swift (the tools/protoc-gen-fieldmeta plugin). The TS target is wired into buf.gen.yaml and re-exported from mod.ts as FieldMeta. Generalizes the #905 experiment: one extensible FieldMetadata message carried in a single FieldOptions extension, so adding an attribute is a schema-only change (scalar-only, enforced at generation time) with no new extension number and no generator changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
c52ced6 to
007d7b2
Compare
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.
What & why
Some schema fields carry app/UI-relevant metadata — e.g. GPIO pins that only matter on DIY hardware, which apps want to hide on pre-assembled boards. This adds a first-class, structured way to declare that metadata in the schema and consume it from every client, with no reflection and no runtime cost.
Supersedes #905 (@jp-bennett's experiment). That PR proved the idea with a scalar
(meshtastic.diy_only)option; this generalizes it into one extensibleFieldMetadatamessage carried in a singleFieldOptionsextension, plus the generators that actually expose it to consumers.How it works
meshtastic/field_metadata.proto: a structuredFieldMetadatamessage (diy_only,admin_only,min/max_value,unit) carried in oneextend google.protobuf.FieldOptions { field_metadata = 51001 }.config.proto'srx_gpio/tx_gpioare annotated{ diy_only: true }.google.api.field_behavior).SchemaHandlerinpackages/kmp/buildSrcemits aFieldMetadataRegistryinto the published artifact.tools/protoc-gen-fieldmeta, aprotoc/bufplugin (reads the option dynamically; generic overFieldMetadata's fields).get(type, tag)fallback. Where the language can extend the real generated message type it does (Kotlin companion extension, Swift type extension); TS/Python use a namespace, Rust a module, C a lookup table.Accessing it (example:
rx_gpio→diy_only)Config.PositionConfig.rx_gpio.diy_onlyConfig.PositionConfig.rxGpio.diyOnlyFieldMeta.Config.PositionConfig.rxGpio.diyOnlyfm.Config.PositionConfig.rx_gpio["diy_only"]fm::config::position_config::RX_GPIO.diy_onlymeshtastic_field_metadata_get("meshtastic.Config.PositionConfig", 8)->diy_onlyAdding metadata later
Schema-only: add a scalar field to
FieldMetadata(next field number) → every target regenerates automatically. No generator/build changes, no new extension number consumed. Non-scalar attributes are a hard error at generation time. (Documented infield_metadata.proto's header.)Testing performed
buf lint/buf build/buf breakingvsmaster— clean (additive change).tools/protoc-gen-fieldmeta:gofmt/go vet/go testgreen (~92% coverage). Tests include an in-memory,buf-faithful end-to-end decode, the scalar-only guard, value rendering (incl. integral floats), string escaping, and multi-message cases.compileKotlinJvm), C (clang -Wall -Wextra), Python, Swift (swiftc -typecheck), TypeScript (tsc --strict), Rust (rustc -D warnings).buf generateproducesfield_metadata_registry.ts, re-exported frommod.tsasFieldMeta.Draft — open items / for review
tools/protoc-gen-fieldmeta/README.md).FieldMetadatashape (which attributes to standardize), the51001extension number (keep it in the 50000–99999 in-house range, or request a global-registry number for a public schema?), and the Swift integration assumptions (validated against a stub, not yet real swift-protobuf output).packages/kmp buildruns in CI on this PR.🤖 Generated with Claude Code