Expand description
Typed access to protobuf extensions stored in unknown fields.
Custom options — (buf.validate.field), (google.api.http), etc. — are
declared with extend google.protobuf.FieldOptions { ... } and attached in
proto source as [(my.option) = {...}]. Editions removed general-purpose
message extensions but custom options remain the sanctioned use of
extend: descriptor.proto still declares extensions 1000 to max; on
every *Options message.
On the wire, extension values are ordinary fields at their declared field
numbers. When an extendee is decoded without the extension in its schema,
those fields land in UnknownFields — already preserved. This module
provides a typed extraction/injection path on top of that storage.
§Usage
Codegen emits a pub const for each extend declaration:
// Generated from: extend google.protobuf.FieldOptions { optional FieldRules field = 1159; }
pub const FIELD: buffa::Extension<buffa::extension::codecs::MessageCodec<FieldRules>>
= buffa::Extension::new(1159, "google.protobuf.FieldOptions");The extendee (any message with unknown-field preservation) implements
ExtensionSet:
use buffa::ExtensionSet;
let rules: Option<FieldRules> = field.options.extension(&buf_validate::FIELD);
opts.set_extension(&buf_validate::FIELD, my_rules);§Panics
extension, set_extension, and clear_extension panic if the
descriptor’s extendee does not match the extendee
message’s PROTO_FQN. This catches bugs like
field_options.extension(&MESSAGE_LEVEL_OPTION) at the first call site
(matches protobuf-go, which panics, and protobuf-es, which throws).
has_extension returns false gracefully on mismatch — “is this
extension set here” when it can’t extend here has a legitimate answer.
§Defaults
Proto2 [default = ...] values are surfaced by extension_or_default,
which returns the declared default when the extension is absent. Presence
is still distinguishable via extension (returns None) or
has_extension.
§JSON
Extension fields serialize as "[pkg.ext]" keys in proto3 JSON. This
requires a populated TypeRegistry — see the type_registry module
(available under the json or text feature). Without a registry,
extension bytes stay in __buffa_unknown_fields and are silently
dropped from JSON output.
§Presence semantics
Extensions always have explicit field presence, regardless of proto3 or
editions IMPLICIT file defaults (see protocolbuffers/protobuf#8234). This
falls out naturally from unknown-field storage: set_extension(&ext, 0)
pushes a record with value 0, so has_extension returns true. Singular
Output is therefore Option<T>, not T with a sentinel.
Modules§
- codecs
- Codec types — one per proto field type.
Structs§
- Extension
- Typed extension descriptor.
Traits§
- Extension
Codec - One impl per proto field type.
Valueis what users pass toset;Outputis whatgetreturns (Option<Value>for singular,Vec<Elem>for repeated). - Extension
Set - Implemented by codegen on every message that preserves unknown fields.