Documentation
¶
Overview ¶
Package protoreflect provides interfaces to dynamically manipulate messages.
This package includes type descriptors which describe the structure of types defined in proto source files and value interfaces which provide the ability to examine and manipulate the contents of messages.
Protocol Buffer Descriptors ¶
Protobuf descriptors (e.g., EnumDescriptor or MessageDescriptor) are immutable objects that represent protobuf type information. They are wrappers around the messages declared in descriptor.proto. Protobuf descriptors alone lack any information regarding Go types.
Enums and messages generated by this module implement Enum and ProtoMessage, where the Descriptor and ProtoReflect.Descriptor accessors respectively return the protobuf descriptor for the values.
The protobuf descriptor interfaces are not meant to be implemented by user code since they might need to be extended in the future to support additions to the protobuf language. The google.golang.org/protobuf/reflect/protodesc package converts between google.protobuf.DescriptorProto messages and protobuf descriptors.
Go Type Descriptors ¶
A type descriptor (e.g., EnumType or MessageType) is a constructor for a concrete Go type that represents the associated protobuf descriptor. There is commonly a one-to-one relationship between protobuf descriptors and Go type descriptors, but it can potentially be a one-to-many relationship.
Enums and messages generated by this module implement Enum and ProtoMessage, where the Type and ProtoReflect.Type accessors respectively return the protobuf descriptor for the values.
The google.golang.org/protobuf/types/dynamicpb package can be used to create Go type descriptors from protobuf descriptors.
Value Interfaces ¶
The Enum and Message interfaces provide a reflective view over an enum or message instance. For enums, it provides the ability to retrieve the enum value number for any concrete enum type. For messages, it provides the ability to access or manipulate fields of the message.
To convert a google.golang.org/protobuf/proto.Message to a protoreflect.Message, use the former's ProtoReflect method. Since the ProtoReflect method is new to the v2 message interface, it may not be present on older message implementations. The github.com/golang/protobuf/proto.MessageReflect function can be used to obtain a reflective view on older messages.
Relationships ¶
The following diagrams demonstrate the relationships between various types declared in this package.
┌───────────────────────────────────┐ V │ ┌────────────── New(n) ─────────────┐ │ │ │ │ │ ┌──── Descriptor() ──┐ │ ┌── Number() ──┐ │ │ │ V V │ V │ ╔════════════╗ ╔════════════════╗ ╔════════╗ ╔════════════╗ ║ EnumType ║ ║ EnumDescriptor ║ ║ Enum ║ ║ EnumNumber ║ ╚════════════╝ ╚════════════════╝ ╚════════╝ ╚════════════╝ Λ Λ │ │ │ └─── Descriptor() ──┘ │ │ │ └────────────────── Type() ───────┘
• An EnumType describes a concrete Go enum type. It has an EnumDescriptor and can construct an Enum instance.
• An EnumDescriptor describes an abstract protobuf enum type.
• An Enum is a concrete enum instance. Generated enums implement Enum.
┌──────────────── New() ─────────────────┐ │ │ │ ┌─── Descriptor() ─────┐ │ ┌── Interface() ───┐ │ │ V V │ V ╔═════════════╗ ╔═══════════════════╗ ╔═════════╗ ╔══════════════╗ ║ MessageType ║ ║ MessageDescriptor ║ ║ Message ║ ║ ProtoMessage ║ ╚═════════════╝ ╚═══════════════════╝ ╚═════════╝ ╚══════════════╝ Λ Λ │ │ Λ │ │ └──── Descriptor() ────┘ │ └─ ProtoReflect() ─┘ │ │ └─────────────────── Type() ─────────┘
• A MessageType describes a concrete Go message type. It has a MessageDescriptor and can construct a Message instance. Just as how Go's reflect.Type is a reflective description of a Go type, a MessageType is a reflective description of a Go type for a protobuf message.
• A MessageDescriptor describes an abstract protobuf message type. It has no understanding of Go types. In order to construct a MessageType from just a MessageDescriptor, you can consider looking up the message type in the global registry using the FindMessageByName method on google.golang.org/protobuf/reflect/protoregistry.GlobalTypes or constructing a dynamic MessageType using google.golang.org/protobuf/types/dynamicpb.NewMessageType.
• A Message is a reflective view over a concrete message instance. Generated messages implement ProtoMessage, which can convert to a Message. Just as how Go's reflect.Value is a reflective view over a Go value, a Message is a reflective view over a concrete protobuf message instance. Using Go reflection as an analogy, the [ProtoMessage.ProtoReflect] method is similar to calling reflect.ValueOf, and the [Message.Interface] method is similar to calling reflect.Value.Interface.
┌── TypeDescriptor() ──┐ ┌───── Descriptor() ─────┐ │ V │ V ╔═══════════════╗ ╔═════════════════════════╗ ╔═════════════════════╗ ║ ExtensionType ║ ║ ExtensionTypeDescriptor ║ ║ ExtensionDescriptor ║ ╚═══════════════╝ ╚═════════════════════════╝ ╚═════════════════════╝ Λ │ │ Λ │ Λ └─────── Type() ───────┘ │ └─── may implement ────┘ │ │ │ └────── implements ────────┘
• An ExtensionType describes a concrete Go implementation of an extension. It has an ExtensionTypeDescriptor and can convert to/from an abstract Value and a Go value.
• An ExtensionTypeDescriptor is an ExtensionDescriptor which also has an ExtensionType.
• An ExtensionDescriptor describes an abstract protobuf extension field and may not always be an ExtensionTypeDescriptor.
Index ¶
- type Cardinality
- type Descriptor
- type Enum
- type EnumDescriptor
- type EnumDescriptors
- type EnumNumber
- type EnumRanges
- type EnumType
- type EnumValueDescriptor
- type EnumValueDescriptors
- type ExtensionDescriptor
- type ExtensionDescriptors
- type ExtensionType
- type ExtensionTypeDescriptor
- type FieldDescriptor
- type FieldDescriptors
- type FieldNumber
- type FieldNumbers
- type FieldRanges
- type FileDescriptor
- type FileImport
- type FileImports
- type FullName
- type Kind
- type List
- type Map
- type MapKey
- type Message
- type MessageDescriptor
- type MessageDescriptors
- type MessageFieldTypes
- type MessageType
- type MethodDescriptor
- type MethodDescriptors
- type Name
- type Names
- type OneofDescriptor
- type OneofDescriptors
- type ProtoMessage
- type RawFields
- type ServiceDescriptor
- type ServiceDescriptors
- type SourceLocation
- type SourceLocations
- type SourcePath
- type Syntax
- type Value
- func ValueOf(v any) Value
- func ValueOfBool(v bool) Value
- func ValueOfBytes(v []byte) Value
- func ValueOfEnum(v EnumNumber) Value
- func ValueOfFloat32(v float32) Value
- func ValueOfFloat64(v float64) Value
- func ValueOfInt32(v int32) Value
- func ValueOfInt64(v int64) Value
- func ValueOfList(v List) Value
- func ValueOfMap(v Map) Value
- func ValueOfMessage(v Message) Value
- func ValueOfString(v string) Value
- func ValueOfUint32(v uint32) Value
- func ValueOfUint64(v uint64) Value
- func (v Value) Bool() bool
- func (v Value) Bytes() []byte
- func (v Value) Enum() EnumNumber
- func (v1 Value) Equal(v2 Value) bool
- func (v Value) Float() float64
- func (v Value) Int() int64
- func (v Value) Interface() any
- func (v Value) IsValid() bool
- func (v Value) List() List
- func (v Value) Map() Map
- func (v Value) MapKey() MapKey
- func (v Value) Message() Message
- func (v Value) String() string
- func (v Value) Uint() uint64
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cardinality ¶
type Cardinality cardinality
Cardinality determines whether a field is optional, required, or repeated.
const ( Optional Cardinality = 1 // appears zero or one times Required Cardinality = 2 // appears exactly one time; invalid with Proto3 Repeated Cardinality = 3 // appears zero or more times )
Constants as defined by the google.protobuf.Cardinality enumeration.
func (Cardinality) GoString ¶
func (c Cardinality) GoString() string
GoString returns c as a Go source identifier (e.g., "Optional").
func (Cardinality) IsValid ¶
func (c Cardinality) IsValid() bool
IsValid reports whether the cardinality is valid.
func (Cardinality) String ¶
func (c Cardinality) String() string
String returns c as a proto source identifier (e.g., "optional").
type Descriptor ¶
type Descriptor interface { // ParentFile returns the parent file descriptor that this descriptor // is declared within. The parent file for the file descriptor is itself. // // Support for this functionality is optional and may return nil. ParentFile() FileDescriptor // Parent returns the parent containing this descriptor declaration. // The following shows the mapping from child type to possible parent types: // // ╔═════════════════════╤═══════════════════════════════════╗ // ║ Child type │ Possible parent types ║ // ╠═════════════════════╪═══════════════════════════════════╣ // ║ FileDescriptor │ nil ║ // ║ MessageDescriptor │ FileDescriptor, MessageDescriptor ║ // ║ FieldDescriptor │ FileDescriptor, MessageDescriptor ║ // ║ OneofDescriptor │ MessageDescriptor ║ // ║ EnumDescriptor │ FileDescriptor, MessageDescriptor ║ // ║ EnumValueDescriptor │ EnumDescriptor ║ // ║ ServiceDescriptor │ FileDescriptor ║ // ║ MethodDescriptor │ ServiceDescriptor ║ // ╚═════════════════════╧═══════════════════════════════════╝ // // Support for this functionality is optional and may return nil. Parent() Descriptor // Index returns the index of this descriptor within its parent. // It returns 0 if the descriptor does not have a parent or if the parent // is unknown. Index() int // Syntax is the protobuf syntax. Syntax() Syntax // e.g., Proto2 or Proto3 // Name is the short name of the declaration (i.e., FullName.Name). Name() Name // e.g., "Any" // FullName is the fully-qualified name of the declaration. // // The FullName is a concatenation of the full name of the type that this // type is declared within and the declaration name. For example, // field "foo_field" in message "proto.package.MyMessage" is // uniquely identified as "proto.package.MyMessage.foo_field". // Enum values are an exception to the rule (see EnumValueDescriptor). FullName() FullName // e.g., "google.protobuf.Any" // IsPlaceholder reports whether type information is missing since a // dependency is not resolved, in which case only name information is known. // // Placeholder types may only be returned by the following accessors // as a result of unresolved dependencies: // // ╔═══════════════════════════════════╤═════════════════════╗ // ║ Accessor │ Descriptor ║ // ╠═══════════════════════════════════╪═════════════════════╣ // ║ FileImports.FileDescriptor │ FileDescriptor ║ // ║ FieldDescriptor.Enum │ EnumDescriptor ║ // ║ FieldDescriptor.Message │ MessageDescriptor ║ // ║ FieldDescriptor.DefaultEnumValue │ EnumValueDescriptor ║ // ║ FieldDescriptor.ContainingMessage │ MessageDescriptor ║ // ║ MethodDescriptor.Input │ MessageDescriptor ║ // ║ MethodDescriptor.Output │ MessageDescriptor ║ // ╚═══════════════════════════════════╧═════════════════════╝ // // If true, only Name and FullName are valid. // For FileDescriptor, the Path is also valid. IsPlaceholder() bool // Options returns the descriptor options. The caller must not modify // the returned value. // // To avoid a dependency cycle, this function returns a proto.Message value. // The proto message type returned for each descriptor type is as follows: // ╔═════════════════════╤══════════════════════════════════════════╗ // ║ Go type │ Protobuf message type ║ // ╠═════════════════════╪══════════════════════════════════════════╣ // ║ FileDescriptor │ google.protobuf.FileOptions ║ // ║ EnumDescriptor │ google.protobuf.EnumOptions ║ // ║ EnumValueDescriptor │ google.protobuf.EnumValueOptions ║ // ║ MessageDescriptor │ google.protobuf.MessageOptions ║ // ║ FieldDescriptor │ google.protobuf.FieldOptions ║ // ║ OneofDescriptor │ google.protobuf.OneofOptions ║ // ║ ServiceDescriptor │ google.protobuf.ServiceOptions ║ // ║ MethodDescriptor │ google.protobuf.MethodOptions ║ // ╚═════════════════════╧══════════════════════════════════════════╝ // // This method returns a typed nil-pointer if no options are present. // The caller must import the descriptorpb package to use this. Options() ProtoMessage // contains filtered or unexported methods }
Descriptor provides a set of accessors that are common to every descriptor. Each descriptor type wraps the equivalent google.protobuf.XXXDescriptorProto, but provides efficient lookup and immutability.
Each descriptor is comparable. Equality implies that the two types are exactly identical. However, it is possible for the same semantically identical proto type to be represented by multiple type descriptors.
For example, suppose we have t1 and t2 which are both an MessageDescriptor. If t1 == t2, then the types are definitely equal and all accessors return the same information. However, if t1 != t2, then it is still possible that they still represent the same proto type (e.g., t1.FullName == t2.FullName). This can occur if a descriptor type is created dynamically, or multiple versions of the same proto type are accidentally linked into the Go binary.
type Enum ¶
type Enum interface { // Descriptor returns enum descriptor, which contains only the protobuf // type information for the enum. Descriptor() EnumDescriptor // Type returns the enum type, which encapsulates both Go and protobuf // type information. If the Go type information is not needed, // it is recommended that the enum descriptor be used instead. Type() EnumType // Number returns the enum value as an integer. Number() EnumNumber }
Enum is a reflection interface for a concrete enum value, which provides type information and a getter for the enum number. Enum does not provide a mutable API since enums are commonly backed by Go constants, which are not addressable.
type EnumDescriptor ¶
type EnumDescriptor interface { Descriptor // Values is a list of nested enum value declarations. Values() EnumValueDescriptors // ReservedNames is a list of reserved enum names. ReservedNames() Names // ReservedRanges is a list of reserved ranges of enum numbers. ReservedRanges() EnumRanges // IsClosed reports whether this enum uses closed semantics. // See https://protobuf.dev/programming-guides/enum/#definitions. // Note: the Go protobuf implementation is not spec compliant and treats // all enums as open enums. IsClosed() bool // contains filtered or unexported methods }
EnumDescriptor describes an enum and corresponds with the google.protobuf.EnumDescriptorProto message.
Nested declarations: EnumValueDescriptor.
type EnumDescriptors ¶
type EnumDescriptors interface { // Len reports the number of enum types. Len() int // Get returns the ith EnumDescriptor. It panics if out of bounds. Get(i int) EnumDescriptor // ByName returns the EnumDescriptor for an enum named s. // It returns nil if not found. ByName(s Name) EnumDescriptor // contains filtered or unexported methods }
EnumDescriptors is a list of enum declarations.
type EnumRanges ¶
type EnumRanges interface { // Len reports the number of ranges in the list. Len() int // Get returns the ith range. It panics if out of bounds. Get(i int) [2]EnumNumber // start inclusive; end inclusive // Has reports whether n is within any of the ranges. Has(n EnumNumber) bool // contains filtered or unexported methods }
EnumRanges represent a list of enum number ranges.
type EnumType ¶
type EnumType interface { // New returns an instance of this enum type with its value set to n. New(n EnumNumber) Enum // Descriptor returns the enum descriptor. // // Invariant: t.Descriptor() == t.New(0).Descriptor() Descriptor() EnumDescriptor }
EnumType encapsulates an EnumDescriptor with a concrete Go implementation.
type EnumValueDescriptor ¶
type EnumValueDescriptor interface { Descriptor // Number returns the enum value as an integer. Number() EnumNumber // contains filtered or unexported methods }
EnumValueDescriptor describes an enum value and corresponds with the google.protobuf.EnumValueDescriptorProto message.
All other proto declarations are in the namespace of the parent. However, enum values do not follow this rule and are within the namespace of the parent's parent (i.e., they are a sibling of the containing enum). Thus, a value named "FOO_VALUE" declared within an enum uniquely identified as "proto.package.MyEnum" has a full name of "proto.package.FOO_VALUE".
type EnumValueDescriptors ¶
type EnumValueDescriptors interface { // Len reports the number of enum values. Len() int // Get returns the ith EnumValueDescriptor. It panics if out of bounds. Get(i int) EnumValueDescriptor // ByName returns the EnumValueDescriptor for the enum value named s. // It returns nil if not found. ByName(s Name) EnumValueDescriptor // ByNumber returns the EnumValueDescriptor for the enum value numbered n. // If multiple have the same number, the first one defined is returned // It returns nil if not found. ByNumber(n EnumNumber) EnumValueDescriptor // contains filtered or unexported methods }
EnumValueDescriptors is a list of enum value declarations.
type ExtensionDescriptor ¶
type ExtensionDescriptor = FieldDescriptor
ExtensionDescriptor is an alias of FieldDescriptor for documentation.
type ExtensionDescriptors ¶
type ExtensionDescriptors interface { // Len reports the number of fields. Len() int // Get returns the ith ExtensionDescriptor. It panics if out of bounds. Get(i int) ExtensionDescriptor // ByName returns the ExtensionDescriptor for a field named s. // It returns nil if not found. ByName(s Name) ExtensionDescriptor // contains filtered or unexported methods }
ExtensionDescriptors is a list of field declarations.
type ExtensionType ¶
type ExtensionType interface { // New returns a new value for the field. // For scalars, this returns the default value in native Go form. New() Value // Zero returns a new value for the field. // For scalars, this returns the default value in native Go form. // For composite types, this returns an empty, read-only message, list, or map. Zero() Value // TypeDescriptor returns the extension type descriptor. TypeDescriptor() ExtensionTypeDescriptor // ValueOf wraps the input and returns it as a Value. // ValueOf panics if the input value is invalid or not the appropriate type. // // ValueOf is more extensive than protoreflect.ValueOf for a given field's // value as it has more type information available. ValueOf(any) Value // InterfaceOf completely unwraps the Value to the underlying Go type. // InterfaceOf panics if the input is nil or does not represent the // appropriate underlying Go type. For composite types, it panics if the // value is not mutable. // // InterfaceOf is able to unwrap the Value further than Value.Interface // as it has more type information available. InterfaceOf(Value) any // IsValidValue reports whether the Value is valid to assign to the field. IsValidValue(Value) bool // IsValidInterface reports whether the input is valid to assign to the field. IsValidInterface(any) bool }
ExtensionType encapsulates an ExtensionDescriptor with a concrete Go implementation. The nested field descriptor must be for a extension field.
While a normal field is a member of the parent message that it is declared within (see [Descriptor.Parent]), an extension field is a member of some other target message (see [FieldDescriptor.ContainingMessage]) and may have no relationship with the parent. However, the full name of an extension field is relative to the parent that it is declared within.
For example:
syntax = "proto2"; package example; message FooMessage { extensions 100 to max; } message BarMessage { extends FooMessage { optional BarMessage bar_field = 100; } }
Field "bar_field" is an extension of FooMessage, but its full name is "example.BarMessage.bar_field" instead of "example.FooMessage.bar_field".