Documentation ¶
Overview ¶
Package dynamic provides an implementation for a dynamic protobuf message.
The dynamic message is essentially a message descriptor along with a map of tag numbers to values. It has a broad API for interacting with the message, including inspection and modification. Generally, most operations have two forms: a regular method that panics on bad input or error and a "Try" form of the method that will instead return an error.
A dynamic message can optionally be constructed with a MessageFactory. The MessageFactory has various registries that may be used by the dynamic message, such as during de-serialization. The message factory is "inherited" by any other dynamic messages created, such as nested messages that are created during de-serialization. Similarly, any dynamic message created using MessageFactory.NewMessage will be associated with that factory, which in turn will be used to create other messages or parse extension fields during de-serialization.
Field Types ¶
The types of values expected by setters and returned by getters are the same as protoc generates for scalar fields. For repeated fields, there are methods for getting and setting values at a particular index or for adding an element. Similarly, for map fields, there are methods for getting and setting values for a particular key.
If you use GetField for a repeated field, it will return a copy of all elements as a slice []interface{}. Similarly, using GetField for a map field will return a copy of all mappings as a map[interface{}]interface{}. You can also use SetField to supply an entire slice or map for repeated or map fields. The slice need not be []interface{} but can actually be typed according to the field's expected type. For example, a repeated uint64 field can be set using a slice of type []uint64.
Descriptors for map fields describe them as repeated fields with a nested message type. The nested message type is a special generated type that represents a single mapping: key and value pair. The dynamic message has some special affordances for this representation. For example, you can use SetField to set a map field using a slice of these entry messages. Internally, the slice of entries will be converted to an actual map. Similarly, you can use AddRepeatedField with an entry message to add (or overwrite) a mapping. However, you cannot use GetRepeatedField or SetRepeatedField to modify maps, since those take numeric index arguments which are not relevant to maps (since maps in Go have no defined ordering).
When setting field values in dynamic messages, the type-checking is lenient in that it accepts any named type with the right kind. So a string field can be assigned to any type that is defined as a string. Enum fields require int32 values (or any type that is defined as an int32).
Unlike normal use of numeric values in Go, values will be automatically widened when assigned. So, for example, an int64 field can be set using an int32 value since it can be safely widened without truncation or loss of precision. Similar goes for uint32 values being converted to uint64 and float32 being converted to float64. Narrowing conversions are not done, however. Also, unsigned values will never be automatically converted to signed (and vice versa), and floating point values will never be automatically converted to integral values (and vice versa). Since the bit width of int and uint fields is allowed to be platform dependent, but will always be less than or equal to 64, they can only be used as values for int64 and uint64 fields, respectively. They cannot be used to set int32 or uint32 fields, which includes enums fields.
Fields whose type is a nested message can have values set to either other dynamic messages or generated messages (e.g. pointers to structs generated by protoc). Getting a value for such a field will return the actual type it is set to (e.g. either a dynamic message or a generated message). If the value is not set and the message uses proto2 syntax, the default message returned will be whatever is returned by the dynamic message's MessageFactory (if the dynamic message was not created with a factory, it will use the logic of the zero value factory). In most typical cases, it will return a dynamic message, but if the factory is configured with a KnownTypeRegistry, or if the field's type is a well-known type, it will return a zero value generated message.
Unrecognized Fields ¶
Unrecognized fields are preserved by the dynamic message when unmarshaling from the standard binary format. If the message's MessageFactory was configured with an ExtensionRegistry, it will be used to identify and parse extension fields for the message.
Unrecognized fields can dynamically become recognized fields if the application attempts to retrieve an unrecognized field's value using a FieldDescriptor. In this case, the given FieldDescriptor is used to parse the unknown field and move the parsed value into the message's set of known fields. This behavior is most suited to the use of extensions, where an ExtensionRegistry is not setup with all known extensions ahead of time. But it can even happen for non-extension fields! Here's an example scenario where a non-extension field can initially be unknown and become known:
- A dynamic message is created with a descriptor, A, and then de-serialized from a stream of bytes. The stream includes an unrecognized tag T. The message will include tag T in its unrecognized field set.
- Another call site retrieves a newer descriptor, A', which includes a newly added field with tag T.
- That other call site then uses a FieldDescriptor to access the value of the new field. This will cause the dynamic message to parse the bytes for the unknown tag T and store them as a known field.
- Subsequent operations for tag T, including setting the field using only tag number or de-serializing a stream that includes tag T, will operate as if that tag were part of the original descriptor, A.
Compatibility ¶
In addition to implementing the proto.Message interface, the included Message type also provides an XXX_MessageName() method, so it can work with proto.MessageName. And it provides a Descriptor() method that behaves just like the method of the same signature in messages generated by protoc. Because of this, it is actually compatible with proto.Message in many (though not all) contexts. In particular, it is compatible with proto.Marshal and proto.Unmarshal for serializing and de-serializing messages.
The dynamic message supports binary and text marshaling, using protobuf's well-defined binary format and the same text format that protoc-generated types use. It also supports JSON serialization/de-serialization by implementing the json.Marshaler and json.Unmarshaler interfaces. And dynamic messages can safely be used with the jsonpb package for JSON serialization and de-serialization.
In addition to implementing the proto.Message interface and numerous related methods, it also provides inter-op with generated messages via conversion. The ConvertTo, ConvertFrom, MergeInto, and MergeFrom methods copy message contents from a dynamic message to a generated message and vice versa.
When copying from a generated message into a dynamic message, if the generated message contains fields unknown to the dynamic message (e.g. not present in the descriptor used to create the dynamic message), these fields become known to the dynamic message (as per behavior described above in "Unrecognized Fields"). If the generated message has unrecognized fields of its own, including unrecognized extensions, they are preserved in the dynamic message. It is possible that the dynamic message knows about fields that the generated message did not, like if it has a different version of the descriptor or its MessageFactory has an ExtensionRegistry that knows about different extensions than were linked into the program. In this case, these unrecognized fields in the generated message will be known fields in the dynamic message.
Similarly, when copying from a dynamic message into a generated message, if the dynamic message has unrecognized fields they can be preserved in the generated message (currently only for syntax proto2 since proto3 generated messages do not preserve unrecognized fields). If the generated message knows about fields that the dynamic message does not, these unrecognized fields may become known fields in the generated message.
Registries ¶
This package also contains a couple of registries, for managing known types and descriptors.
The KnownTypeRegistry allows de-serialization of a dynamic message to use generated message types, instead of dynamic messages, for some kinds of nested message fields. This is particularly useful for working with proto messages that have special encodings as JSON (e.g. the well-known types), since the dynamic message does not try to handle these special cases in its JSON marshaling facilities.
The ExtensionRegistry allows for recognizing and parsing extensions fields (for proto2 messages).
Index ¶
- Variables
- func AnyResolver(mf *MessageFactory, files ...*desc.FileDescriptor) jsonpb.AnyResolver
- func Equal(a, b *Message) bool
- func Merge(dst, src proto.Message)
- func MessagesEqual(a, b proto.Message) bool
- func SetExtension(msg proto.Message, extd *desc.FieldDescriptor, val interface{}) error
- func TryMerge(dst, src proto.Message) error
- type ExtensionRegistry
- func (r *ExtensionRegistry) AddExtension(exts ...*desc.FieldDescriptor) error
- func (r *ExtensionRegistry) AddExtensionDesc(exts ...*proto.ExtensionDesc) error
- func (r *ExtensionRegistry) AddExtensionsFromFile(fd *desc.FileDescriptor)
- func (r *ExtensionRegistry) AddExtensionsFromFileRecursively(fd *desc.FileDescriptor)
- func (r *ExtensionRegistry) AllExtensionsForType(messageName string) []*desc.FieldDescriptor
- func (r *ExtensionRegistry) FindExtension(messageName string, tagNumber int32) *desc.FieldDescriptor
- func (r *ExtensionRegistry) FindExtensionByJSONName(messageName string, fieldName string) *desc.FieldDescriptor
- func (r *ExtensionRegistry) FindExtensionByName(messageName string, fieldName string) *desc.FieldDescriptor
- type KnownTypeRegistry
- type Message
- func AsDynamicMessage(msg proto.Message) (*Message, error)
- func AsDynamicMessageWithExtensionRegistry(msg proto.Message, er *ExtensionRegistry) (*Message, error)
- func AsDynamicMessageWithMessageFactory(msg proto.Message, mf *MessageFactory) (*Message, error)
- func NewMessage(md *desc.MessageDescriptor) *Message
- func NewMessageWithExtensionRegistry(md *desc.MessageDescriptor, er *ExtensionRegistry) *Message
- func NewMessageWithMessageFactory(md *desc.MessageDescriptor, mf *MessageFactory) *Message
- func (m *Message) AddRepeatedField(fd *desc.FieldDescriptor, val interface{})
- func (m *Message) AddRepeatedFieldByName(name string, val interface{})
- func (m *Message) AddRepeatedFieldByNumber(tagNumber int, val interface{})
- func (m *Message) ClearField(fd *desc.FieldDescriptor)
- func (m *Message) ClearFieldByName(name string)
- func (m *Message) ClearFieldByNumber(tagNumber int)
- func (m *Message) ClearOneOfField(od *desc.OneOfDescriptor)
- func (m *Message) ConvertFrom(target proto.Message) error
- func (m *Message) ConvertTo(target proto.Message) error
- func (m *Message) ConvertToDeterministic(target proto.Message) error
- func (m *Message) Descriptor() ([]byte, []int)
- func (m *Message) FieldLength(fd *desc.FieldDescriptor) int
- func (m *Message) FieldLengthByName(name string) int
- func (m *Message) FieldLengthByNumber(tagNumber int32) int
- func (m *Message) FindFieldDescriptor(tagNumber int32) *desc.FieldDescriptor
- func (m *Message) FindFieldDescriptorByJSONName(name string) *desc.FieldDescriptor
- func (m *Message) FindFieldDescriptorByName(name string) *desc.FieldDescriptor
- func (m *Message) ForEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool)
- func (m *Message) ForEachMapFieldEntryByName(name string, fn func(key, val interface{}) bool)
- func (m *Message) ForEachMapFieldEntryByNumber(tagNumber int, fn func(key, val interface{}) bool)
- func (m *Message) GetField(fd *desc.FieldDescriptor) interface{}
- func (m *Message) GetFieldByName(name string) interface{}
- func (m *Message) GetFieldByNumber(tagNumber int) interface{}
- func (m *Message) GetKnownExtensions() []*desc.FieldDescriptor
- func (m *Message) GetKnownFields() []*desc.FieldDescriptor
- func (m *Message) GetMapField(fd *desc.FieldDescriptor, key interface{}) interface{}
- func (m *Message) GetMapFieldByName(name string, key interface{}) interface{}
- func (m *Message) GetMapFieldByNumber(tagNumber int, key interface{}) interface{}
- func (m *Message) GetMessageDescriptor() *desc.MessageDescriptor
- func (m *Message) GetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{})
- func (m *Message) GetRepeatedField(fd *desc.FieldDescriptor, index int) interface{}
- func (m *Message) GetRepeatedFieldByName(name string, index int) interface{}
- func (m *Message) GetRepeatedFieldByNumber(tagNumber int, index int) interface{}
- func (m *Message) GetUnknownField(tagNumber int32) []UnknownField
- func (m *Message) GetUnknownFields() []int32
- func (m *Message) HasField(fd *desc.FieldDescriptor) bool
- func (m *Message) HasFieldName(name string) bool
- func (m *Message) HasFieldNumber(tagNumber int) bool
- func (m *Message) Marshal() ([]byte, error)
- func (m *Message) MarshalAppend(b []byte) ([]byte, error)
- func (m *Message) MarshalAppendDeterministic(b []byte) ([]byte, error)
- func (m *Message) MarshalDeterministic() ([]byte, error)
- func (m *Message) MarshalJSON() ([]byte, error)
- func (m *Message) MarshalJSONIndent() ([]byte, error)
- func (m *Message) MarshalJSONPB(opts *jsonpb.Marshaler) ([]byte, error)
- func (m *Message) MarshalText() ([]byte, error)
- func (m *Message) MarshalTextIndent() ([]byte, error)
- func (m *Message) Merge(source proto.Message)
- func (m *Message) MergeFrom(source proto.Message) error
- func (m *Message) MergeInto(target proto.Message) error
- func (m *Message) MergeIntoDeterministic(target proto.Message) error
- func (m *Message) ProtoMessage()
- func (m *Message) PutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{})
- func (m *Message) PutMapFieldByName(name string, key interface{}, val interface{})
- func (m *Message) PutMapFieldByNumber(tagNumber int, key interface{}, val interface{})
- func (m *Message) RemoveMapField(fd *desc.FieldDescriptor, key interface{})
- func (m *Message) RemoveMapFieldByName(name string, key interface{})
- func (m *Message) RemoveMapFieldByNumber(tagNumber int, key interface{})
- func (m *Message) Reset()
- func (m *Message) SetField(fd *desc.FieldDescriptor, val interface{})
- func (m *Message) SetFieldByName(name string, val interface{})
- func (m *Message) SetFieldByNumber(tagNumber int, val interface{})
- func (m *Message) SetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{})
- func (m *Message) SetRepeatedFieldByName(name string, index int, val interface{})
- func (m *Message) SetRepeatedFieldByNumber(tagNumber int, index int, val interface{})
- func (m *Message) String() string
- func (m *Message) TryAddRepeatedField(fd *desc.FieldDescriptor, val interface{}) error
- func (m *Message) TryAddRepeatedFieldByName(name string, val interface{}) error
- func (m *Message) TryAddRepeatedFieldByNumber(tagNumber int, val interface{}) error
- func (m *Message) TryClearField(fd *desc.FieldDescriptor) error
- func (m *Message) TryClearFieldByName(name string) error
- func (m *Message) TryClearFieldByNumber(tagNumber int) error
- func (m *Message) TryClearOneOfField(od *desc.OneOfDescriptor) error
- func (m *Message) TryFieldLength(fd *desc.FieldDescriptor) (int, error)
- func (m *Message) TryFieldLengthByName(name string) (int, error)
- func (m *Message) TryFieldLengthByNumber(tagNumber int32) (int, error)
- func (m *Message) TryForEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) error
- func (m *Message) TryForEachMapFieldEntryByName(name string, fn func(key, val interface{}) bool) error
- func (m *Message) TryForEachMapFieldEntryByNumber(tagNumber int, fn func(key, val interface{}) bool) error
- func (m *Message) TryGetField(fd *desc.FieldDescriptor) (interface{}, error)
- func (m *Message) TryGetFieldByName(name string) (interface{}, error)
- func (m *Message) TryGetFieldByNumber(tagNumber int) (interface{}, error)
- func (m *Message) TryGetMapField(fd *desc.FieldDescriptor, key interface{}) (interface{}, error)
- func (m *Message) TryGetMapFieldByName(name string, key interface{}) (interface{}, error)
- func (m *Message) TryGetMapFieldByNumber(tagNumber int, key interface{}) (interface{}, error)
- func (m *Message) TryGetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{}, error)
- func (m *Message) TryGetRepeatedField(fd *desc.FieldDescriptor, index int) (interface{}, error)
- func (m *Message) TryGetRepeatedFieldByName(name string, index int) (interface{}, error)
- func (m *Message) TryGetRepeatedFieldByNumber(tagNumber int, index int) (interface{}, error)
- func (m *Message) TryPutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) error
- func (m *Message) TryPutMapFieldByName(name string, key interface{}, val interface{}) error
- func (m *Message) TryPutMapFieldByNumber(tagNumber int, key interface{}, val interface{}) error
- func (m *Message) TryRemoveMapField(fd *desc.FieldDescriptor, key interface{}) error
- func (m *Message) TryRemoveMapFieldByName(name string, key interface{}) error
- func (m *Message) TryRemoveMapFieldByNumber(tagNumber int, key interface{}) error
- func (m *Message) TrySetField(fd *desc.FieldDescriptor, val interface{}) error
- func (m *Message) TrySetFieldByName(name string, val interface{}) error
- func (m *Message) TrySetFieldByNumber(tagNumber int, val interface{}) error
- func (m *Message) TrySetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) error
- func (m *Message) TrySetRepeatedFieldByName(name string, index int, val interface{}) error
- func (m *Message) TrySetRepeatedFieldByNumber(tagNumber int, index int, val interface{}) error
- func (m *Message) Unmarshal(b []byte) error
- func (m *Message) UnmarshalJSON(js []byte) error
- func (m *Message) UnmarshalJSONPB(opts *jsonpb.Unmarshaler, js []byte) error
- func (m *Message) UnmarshalMerge(b []byte) error
- func (m *Message) UnmarshalMergeJSON(js []byte) error
- func (m *Message) UnmarshalMergeJSONPB(opts *jsonpb.Unmarshaler, js []byte) error
- func (m *Message) UnmarshalMergeText(text []byte) error
- func (m *Message) UnmarshalText(text []byte) error
- func (m *Message) Validate() error
- func (m *Message) ValidateRecursive() error
- func (m *Message) XXX_MessageName() string
- type MessageFactory
- func NewMessageFactoryWithDefaults() *MessageFactory
- func NewMessageFactoryWithExtensionRegistry(er *ExtensionRegistry) *MessageFactory
- func NewMessageFactoryWithKnownTypeRegistry(ktr *KnownTypeRegistry) *MessageFactory
- func NewMessageFactoryWithRegistries(er *ExtensionRegistry, ktr *KnownTypeRegistry) *MessageFactory
- type UnknownField
Constants ¶
This section is empty.
Variables ¶
var ErrFieldIsNotMap = errors.New("field is not a map type")
ErrFieldIsNotMap is an error that is returned when map-related operations are attempted with fields that are not maps.
var ErrFieldIsNotRepeated = errors.New("field is not repeated")
ErrFieldIsNotRepeated is an error that is returned when repeated field operations are attempted with fields that are not repeated.
var ErrIndexOutOfRange = errors.New("index is out of range")
ErrIndexOutOfRange is an error that is returned when an invalid index is provided when access a single element of a repeated field.
var ErrNumericOverflow = errors.New("numeric value is out of range")
ErrNumericOverflow is an error returned by operations that encounter a numeric value that is too large, for example de-serializing a value into an int32 field when the value is larger that can fit into a 32-bit value.
var ErrUnknownFieldName = errors.New("unknown field name")
ErrUnknownFieldName is an error that is returned when an operation refers to an unknown field name.
var ErrUnknownTagNumber = errors.New("unknown tag number")
ErrUnknownTagNumber is an error that is returned when an operation refers to an unknown tag number.
var FieldIsNotMapError = ErrFieldIsNotMap
FieldIsNotMapError is the same as ErrFieldIsNotMap. Deprecated: use ErrFieldIsNotMap
var FieldIsNotRepeatedError = ErrFieldIsNotRepeated
FieldIsNotRepeatedError is the same as ErrFieldIsNotRepeated. Deprecated: use ErrFieldIsNotRepeated
var IndexOutOfRangeError = ErrIndexOutOfRange
IndexOutOfRangeError is the same as ErrIndexOutOfRange. Deprecated: use ErrIndexOutOfRange
var NumericOverflowError = ErrNumericOverflow
NumericOverflowError is the same as ErrNumericOverflow. Deprecated: use ErrNumericOverflow
var UnknownFieldNameError = ErrUnknownFieldName
UnknownFieldNameError is the same as ErrUnknownFieldName. Deprecated: use ErrUnknownFieldName
var UnknownTagNumberError = ErrUnknownTagNumber
UnknownTagNumberError is the same as ErrUnknownTagNumber. Deprecated: use ErrUnknownTagNumber
Functions ¶
func AnyResolver ¶
func AnyResolver(mf *MessageFactory, files ...*desc.FileDescriptor) jsonpb.AnyResolver
AnyResolver returns a jsonpb.AnyResolver that uses the given file descriptors to resolve message names. It uses the given factory, which may be nil, to instantiate messages. The messages that it returns when resolving a type name may often be dynamic messages.
func Equal ¶
Equal returns true if the given two dynamic messages are equal. Two messages are equal when they have the same message type and same fields set to equal values. For proto3 messages, fields set to their zero value are considered unset.
func Merge ¶
Merge merges the given source message into the given destination message. Use use this instead of proto.Merge when one or both of the messages might be a a dynamic message. If there is a problem merging the messages, such as the two messages having different types, then this method will panic (just as proto.Merges does).
func MessagesEqual ¶
MessagesEqual returns true if the given two messages are equal. Use this instead of proto.Equal when one or both of the messages might be a dynamic message.
func SetExtension ¶
func SetExtension(msg proto.Message, extd *desc.FieldDescriptor, val interface{}) error
SetExtension sets the given extension value. If the given message is not a dynamic message, the given extension may not be recognized (or may differ from the compiled and linked in version of the extension. So in that case, this function will serialize the given value to bytes and then use proto.SetRawExtension to set the value.
Types ¶
type ExtensionRegistry ¶
type ExtensionRegistry struct {
// contains filtered or unexported fields
}
ExtensionRegistry is a registry of known extension fields. This is used to parse extension fields encountered when de-serializing a dynamic message.
func NewExtensionRegistryWithDefaults ¶
func NewExtensionRegistryWithDefaults() *ExtensionRegistry
NewExtensionRegistryWithDefaults is a registry that includes all "default" extensions, which are those that are statically linked into the current program (e.g. registered by protoc-generated code via proto.RegisterExtension). Extensions explicitly added to the registry will override any default extensions that are for the same extendee and have the same tag number and/or name.
func (*ExtensionRegistry) AddExtension ¶
func (r *ExtensionRegistry) AddExtension(exts ...*desc.FieldDescriptor) error
AddExtension adds the given extensions to the registry. The given extensions will overwrite any previously added extensions that are for the same extendee message and same extension tag number.
func (*ExtensionRegistry) AddExtensionDesc ¶
func (r *ExtensionRegistry) AddExtensionDesc(exts ...*proto.ExtensionDesc) error
AddExtensionDesc adds the given extensions to the registry.
func (*ExtensionRegistry) AddExtensionsFromFile ¶
func (r *ExtensionRegistry) AddExtensionsFromFile(fd *desc.FileDescriptor)
AddExtensionsFromFile adds to the registry all extension fields defined in the given file descriptor.
func (*ExtensionRegistry) AddExtensionsFromFileRecursively ¶
func (r *ExtensionRegistry) AddExtensionsFromFileRecursively(fd *desc.FileDescriptor)
AddExtensionsFromFileRecursively adds to the registry all extension fields defined in the give file descriptor and also recursively adds all extensions defined in that file's dependencies. This adds extensions from the entire transitive closure for the given file.
func (*ExtensionRegistry) AllExtensionsForType ¶
func (r *ExtensionRegistry) AllExtensionsForType(messageName string) []*desc.FieldDescriptor
AllExtensionsForType returns all known extension fields for the given extendee name (must be a fully-qualified message name).
func (*ExtensionRegistry) FindExtension ¶
func (r *ExtensionRegistry) FindExtension(messageName string, tagNumber int32) *desc.FieldDescriptor
FindExtension queries for the extension field with the given extendee name (must be a fully-qualified message name) and tag number. If no extension is known, nil is returned.
func (*ExtensionRegistry) FindExtensionByJSONName ¶
func (r *ExtensionRegistry) FindExtensionByJSONName(messageName string, fieldName string) *desc.FieldDescriptor
FindExtensionByJSONName queries for the extension field with the given extendee name (must be a fully-qualified message name) and JSON field name (must also be a fully-qualified name). If no extension is known, nil is returned. The fully-qualified JSON name is the same as the extension's normal fully-qualified name except that the last component uses the field's JSON name (if present).
func (*ExtensionRegistry) FindExtensionByName ¶
func (r *ExtensionRegistry) FindExtensionByName(messageName string, fieldName string) *desc.FieldDescriptor
FindExtensionByName queries for the extension field with the given extendee name (must be a fully-qualified message name) and field name (must also be a fully-qualified extension name). If no extension is known, nil is returned.
type KnownTypeRegistry ¶
type KnownTypeRegistry struct {
// contains filtered or unexported fields
}
KnownTypeRegistry is a registry of known message types, as identified by their fully-qualified name. A known message type is one for which a protoc-generated struct exists, so a dynamic message is not necessary to represent it. A MessageFactory uses a KnownTypeRegistry to decide whether to create a generated struct or a dynamic message. The zero-value registry (including the behavior of a nil pointer) only knows about the "well-known types" in protobuf. These include only the wrapper types and a handful of other special types like Any, Duration, and Timestamp.
func NewKnownTypeRegistryWithDefaults ¶
func NewKnownTypeRegistryWithDefaults() *KnownTypeRegistry
NewKnownTypeRegistryWithDefaults creates a new registry that knows about all "default" types (those for which protoc-generated code is statically linked into the Go program).
func NewKnownTypeRegistryWithoutWellKnownTypes ¶
func NewKnownTypeRegistryWithoutWellKnownTypes() *KnownTypeRegistry
NewKnownTypeRegistryWithoutWellKnownTypes creates a new registry that does *not* include the "well-known types" in protobuf. So even well-known types would be represented by a dynamic message.
func (*KnownTypeRegistry) AddKnownType ¶
func (r *KnownTypeRegistry) AddKnownType(kts ...proto.Message)
AddKnownType adds the types of the given messages as known types.
func (*KnownTypeRegistry) CreateIfKnown ¶
func (r *KnownTypeRegistry) CreateIfKnown(messageName string) proto.Message
CreateIfKnown will construct an instance of the given message if it is a known type. If the given name is unknown, nil is returned.
func (*KnownTypeRegistry) GetKnownType ¶
func (r *KnownTypeRegistry) GetKnownType(messageName string) reflect.Type
GetKnownType will return the reflect.Type for the given message name if it is known. If it is not known, nil is returned.
type Message ¶
type Message struct {
// contains filtered or unexported fields
}
Message is a dynamic protobuf message. Instead of a generated struct, like most protobuf messages, this is a map of field number to values and a message descriptor, which is used to validate the field values and also to de-serialize messages (from the standard binary format, as well as from the text format and from JSON).
func AsDynamicMessage ¶
AsDynamicMessage converts the given message to a dynamic message. If the given message is dynamic, it is returned. Otherwise, a dynamic message is created using NewMessage.
func AsDynamicMessageWithExtensionRegistry ¶
func AsDynamicMessageWithExtensionRegistry(msg proto.Message, er *ExtensionRegistry) (*Message, error)
AsDynamicMessageWithExtensionRegistry converts the given message to a dynamic message. If the given message is dynamic, it is returned. Otherwise, a dynamic message is created using NewMessageWithExtensionRegistry.
func AsDynamicMessageWithMessageFactory ¶
func AsDynamicMessageWithMessageFactory(msg proto.Message, mf *MessageFactory) (*Message, error)
AsDynamicMessageWithMessageFactory converts the given message to a dynamic message. If the given message is dynamic, it is returned. Otherwise, a dynamic message is created using NewMessageWithMessageFactory.
func NewMessage ¶
func NewMessage(md *desc.MessageDescriptor) *Message
NewMessage creates a new dynamic message for the type represented by the given message descriptor. During de-serialization, a default MessageFactory is used to instantiate any nested message fields and no extension fields will be parsed. To use a custom MessageFactory or ExtensionRegistry, use MessageFactory.NewMessage.
func NewMessageWithExtensionRegistry ¶
func NewMessageWithExtensionRegistry(md *desc.MessageDescriptor, er *ExtensionRegistry) *Message
NewMessageWithExtensionRegistry creates a new dynamic message for the type represented by the given message descriptor. During de-serialization, the given ExtensionRegistry is used to parse extension fields and nested messages will be instantiated using dynamic.NewMessageFactoryWithExtensionRegistry(er).
func NewMessageWithMessageFactory ¶
func NewMessageWithMessageFactory(md *desc.MessageDescriptor, mf *MessageFactory) *Message
NewMessageWithMessageFactory creates a new dynamic message for the type represented by the given message descriptor. During de-serialization, the given MessageFactory is used to instantiate nested messages.
func (*Message) AddRepeatedField ¶
func (m *Message) AddRepeatedField(fd *desc.FieldDescriptor, val interface{})
AddRepeatedField appends the given value to the given repeated field. It panics if an error is encountered. See TryAddRepeatedField.
func (*Message) AddRepeatedFieldByName ¶
AddRepeatedFieldByName appends the given value to the repeated field with the given name. It panics if an error is encountered. See TryAddRepeatedFieldByName.
func (*Message) AddRepeatedFieldByNumber ¶
AddRepeatedFieldByNumber appends the given value to the repeated field with the given tag number. It panics if an error is encountered. See TryAddRepeatedFieldByNumber.
func (*Message) ClearField ¶
func (m *Message) ClearField(fd *desc.FieldDescriptor)
ClearField removes any value for the given field. It panics if an error is encountered. See TryClearField.
func (*Message) ClearFieldByName ¶
ClearFieldByName removes any value for the field with the given name. It panics if an error is encountered. See TryClearFieldByName.
func (*Message) ClearFieldByNumber ¶
ClearFieldByNumber removes any value for the field with the given tag number. It panics if an error is encountered. See TryClearFieldByNumber.
func (*Message) ClearOneOfField ¶
func (m *Message) ClearOneOfField(od *desc.OneOfDescriptor)
ClearOneOfField removes any value for any of the given one-of's fields. It panics if an error is encountered. See TryClearOneOfField.
func (*Message) ConvertFrom ¶
ConvertFrom converts the given message into this dynamic message. This is shorthand for resetting then merging:
m.Reset() m.MergeFrom(target)
func (*Message) ConvertTo ¶
ConvertTo converts this dynamic message into the given message. This is shorthand for resetting then merging:
target.Reset() m.MergeInto(target)
func (*Message) ConvertToDeterministic ¶
ConvertToDeterministic converts this dynamic message into the given message. It is just like ConvertTo, but it attempts to produce deterministic results. That means that if the target is a generated message (not another dynamic message) and the current runtime is unaware of any fields or extensions that are present in m, they will be serialized into the target's unrecognized fields deterministically.
func (*Message) Descriptor ¶
Descriptor returns the serialized form of the file descriptor in which the message was defined and a path to the message type therein. This mimics the method of the same name on message types generated by protoc.
func (*Message) FieldLength ¶
func (m *Message) FieldLength(fd *desc.FieldDescriptor) int
FieldLength returns the number of elements in this message for the given field descriptor. It panics if an error is encountered. See TryFieldLength.
func (*Message) FieldLengthByName ¶
FieldLengthByName returns the number of elements in this message for the field with the given name. It panics if an error is encountered. See TryFieldLengthByName.
func (*Message) FieldLengthByNumber ¶
FieldLengthByNumber returns the number of elements in this message for the field with the given tag number. It panics if an error is encountered. See TryFieldLengthByNumber.
func (*Message) FindFieldDescriptor ¶
func (m *Message) FindFieldDescriptor(tagNumber int32) *desc.FieldDescriptor
FindFieldDescriptor returns a field descriptor for the given tag number. This searches known fields in the descriptor, known fields discovered during calls to GetField or SetField, and extension fields known by the message's extension registry. It returns nil if the tag is unknown.
func (*Message) FindFieldDescriptorByJSONName ¶
func (m *Message) FindFieldDescriptorByJSONName(name string) *desc.FieldDescriptor
FindFieldDescriptorByJSONName returns a field descriptor for the given JSON name. This searches known fields in the descriptor, known fields discovered during calls to GetField or SetField, and extension fields known by the message's extension registry. If no field matches the given JSON name, it will fall back to searching field names (e.g. FindFieldDescriptorByName). If this also yields no match, nil is returned.
func (*Message) FindFieldDescriptorByName ¶
func (m *Message) FindFieldDescriptorByName(name string) *desc.FieldDescriptor
FindFieldDescriptorByName returns a field descriptor for the given field name. This searches known fields in the descriptor, known fields discovered during calls to GetField or SetField, and extension fields known by the message's extension registry. It returns nil if the name is unknown. If the given name refers to an extension, it should be fully qualified and may be optionally enclosed in parentheses or brackets.
func (*Message) ForEachMapFieldEntry ¶
func (m *Message) ForEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool)
ForEachMapFieldEntry executes the given function for each entry in the map value for the given field descriptor. It stops iteration if the function returns false. It panics if an error is encountered. See TryForEachMapFieldEntry.
func (*Message) ForEachMapFieldEntryByName ¶
ForEachMapFieldEntryByName executes the given function for each entry in the map value for the field with the given name. It stops iteration if the function returns false. It panics if an error is encountered. See TryForEachMapFieldEntryByName.
func (*Message) ForEachMapFieldEntryByNumber ¶
ForEachMapFieldEntryByNumber executes the given function for each entry in the map value for the field with the given tag number. It stops iteration if the function returns false. It panics if an error is encountered. See TryForEachMapFieldEntryByNumber.
func (*Message) GetField ¶
func (m *Message) GetField(fd *desc.FieldDescriptor) interface{}
GetField returns the value for the given field descriptor. It panics if an error is encountered. See TryGetField.
func (*Message) GetFieldByName ¶
GetFieldByName returns the value for the field with the given name. It panics if an error is encountered. See TryGetFieldByName.
func (*Message) GetFieldByNumber ¶
GetFieldByNumber returns the value for the field with the given tag number. It panics if an error is encountered. See TryGetFieldByNumber.
func (*Message) GetKnownExtensions ¶
func (m *Message) GetKnownExtensions() []*desc.FieldDescriptor
GetKnownExtensions returns a slice of descriptors for all extensions known by the message's extension registry. The fields will not be in any defined order.
func (*Message) GetKnownFields ¶
func (m *Message) GetKnownFields() []*desc.FieldDescriptor
GetKnownFields returns a slice of descriptors for all known fields. The fields will not be in any defined order.
func (*Message) GetMapField ¶
func (m *Message) GetMapField(fd *desc.FieldDescriptor, key interface{}) interface{}
GetMapField returns the value for the given map field descriptor and given key. It panics if an error is encountered. See TryGetMapField.
func (*Message) GetMapFieldByName ¶
GetMapFieldByName returns the value for the map field with the given name and given key. It panics if an error is encountered. See TryGetMapFieldByName.
func (*Message) GetMapFieldByNumber ¶
GetMapFieldByNumber returns the value for the map field with the given tag number and given key. It panics if an error is encountered. See TryGetMapFieldByNumber.
func (*Message) GetMessageDescriptor ¶
func (m *Message) GetMessageDescriptor() *desc.MessageDescriptor
GetMessageDescriptor returns a descriptor for this message's type.
func (*Message) GetOneOfField ¶
func (m *Message) GetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{})
GetOneOfField returns which of the given one-of's fields is set and the corresponding value. It panics if an error is encountered. See TryGetOneOfField.
func (*Message) GetRepeatedField ¶
func (m *Message) GetRepeatedField(fd *desc.FieldDescriptor, index int) interface{}
GetRepeatedField returns the value for the given repeated field descriptor at the given index. It panics if an error is encountered. See TryGetRepeatedField.
func (*Message) GetRepeatedFieldByName ¶
GetRepeatedFieldByName returns the value for the repeated field with the given name at the given index. It panics if an error is encountered. See TryGetRepeatedFieldByName.
func (*Message) GetRepeatedFieldByNumber ¶
GetRepeatedFieldByNumber returns the value for the repeated field with the given tag number at the given index. It panics if an error is encountered. See TryGetRepeatedFieldByNumber.
func (*Message) GetUnknownField ¶
func (m *Message) GetUnknownField(tagNumber int32) []UnknownField
GetUnknownField gets the value(s) for the given unknown tag number. If this message has no unknown fields with the given tag, nil is returned.
func (*Message) GetUnknownFields ¶
GetUnknownFields returns a slice of tag numbers for all unknown fields that this message contains. The tags will not be in any defined order.
func (*Message) HasField ¶
func (m *Message) HasField(fd *desc.FieldDescriptor) bool
HasField returns true if this message has a value for the given field. If the given field is not valid (e.g. belongs to a different message type), false is returned. If this message is defined in a file with "proto3" syntax, this will return false even if a field was explicitly assigned its zero value (the zero values for a field are intentionally indistinguishable from absent).
func (*Message) HasFieldName ¶
HasFieldName returns true if this message has a value for a field with the given name. If the given name is unknown, this returns false.
func (*Message) HasFieldNumber ¶
HasFieldNumber returns true if this message has a value for a field with the given tag number. If the given tag is unknown, this returns false.
func (*Message) Marshal ¶
Marshal serializes this message to bytes, returning an error if the operation fails. The resulting bytes are in the standard protocol buffer binary format.
func (*Message) MarshalAppend ¶
MarshalAppend behaves exactly the same as Marshal, except instead of allocating a new byte slice to marshal into, it uses the provided byte slice. The backing array for the returned byte slice *may* be the same as the one that was passed in, but it's not guaranteed as a new backing array will automatically be allocated if more bytes need to be written than the provided buffer has capacity for.
func (*Message) MarshalAppendDeterministic ¶
MarshalAppendDeterministic behaves exactly the same as MarshalDeterministic, except instead of allocating a new byte slice to marshal into, it uses the provided byte slice. The backing array for the returned byte slice *may* be the same as the one that was passed in, but it's not guaranteed as a new backing array will automatically be allocated if more bytes need to be written than the provided buffer has capacity for.
func (*Message) MarshalDeterministic ¶
MarshalDeterministic serializes this message to bytes in a deterministic way, returning an error if the operation fails. This differs from Marshal in that map keys will be sorted before serializing to bytes. The protobuf spec does not define ordering for map entries, so Marshal will use standard Go map iteration order (which will be random). But for cases where determinism is more important than performance, use this method instead.
func (*Message) MarshalJSON ¶
MarshalJSON serializes this message to bytes in JSON format, returning an error if the operation fails. The resulting bytes will be a valid UTF8 string.
This method uses a compact form: no newlines, and spaces between fields and between field identifiers and values are elided.
This method is convenient shorthand for invoking MarshalJSONPB with a default (zero value) marshaler:
m.MarshalJSONPB(&jsonpb.Marshaler{})
So enums are serialized using enum value name strings, and values that are not present (including those with default/zero value for messages defined in "proto3" syntax) are omitted.
func (*Message) MarshalJSONIndent ¶
MarshalJSONIndent serializes this message to bytes in JSON format, returning an error if the operation fails. The resulting bytes will be a valid UTF8 string.
This method uses a "pretty-printed" form, with each field on its own line and spaces between field identifiers and values. Indentation of two spaces is used.
This method is convenient shorthand for invoking MarshalJSONPB with a default (zero value) marshaler:
m.MarshalJSONPB(&jsonpb.Marshaler{Indent: " "})
So enums are serialized using enum value name strings, and values that are not present (including those with default/zero value for messages defined in "proto3" syntax) are omitted.
func (*Message) MarshalJSONPB ¶
MarshalJSONPB serializes this message to bytes in JSON format, returning an error if the operation fails. The resulting bytes will be a valid UTF8 string. The given marshaler is used to convey options used during marshaling.
If this message contains nested messages that are generated message types (as opposed to dynamic messages), the given marshaler is used to marshal it.
When marshaling any nested messages, any jsonpb.AnyResolver configured in the given marshaler is augmented with knowledge of message types known to this message's descriptor (and its enclosing file and set of transitive dependencies).
func (*Message) MarshalText ¶
MarshalText serializes this message to bytes in the standard text format, returning an error if the operation fails. The resulting bytes will be a valid UTF8 string.
This method uses a compact form: no newlines, and spaces between field identifiers and values are elided.
func (*Message) MarshalTextIndent ¶
MarshalTextIndent serializes this message to bytes in the standard text format, returning an error if the operation fails. The resulting bytes will be a valid UTF8 string.
This method uses a "pretty-printed" form, with each field on its own line and spaces between field identifiers and values.
func (*Message) Merge ¶
Merge implements the proto.Merger interface so that dynamic messages are compatible with the proto.Merge function. It delegates to MergeFrom but will panic on error as the proto.Merger interface doesn't allow for returning an error.
Unlike nearly all other methods, this method can work if this message's type is not defined (such as instantiating the message without using NewMessage). This is strictly so that dynamic message's are compatible with the proto.Clone function, which instantiates a new message via reflection (thus its message descriptor will not be set) and than calls Merge.
func (*Message) MergeFrom ¶
MergeFrom merges the given message into this dynamic message. All field values in the given message will be set on this message. For map fields, entries are added to this message (if this message has existing values for like keys, they are overwritten). For slice fields, elements are added.
If the given message has a different set of known fields, it is possible for some known fields in that message to be represented as unknown fields in this message after merging, and vice versa.
func (*Message) MergeInto ¶
MergeInto merges this dynamic message into the given message. All field values in this message will be set on the given message. For map fields, entries are added to the given message (if the given message has existing values for like keys, they are overwritten). For slice fields, elements are added.
If the given message has a different set of known fields, it is possible for some known fields in this message to be represented as unknown fields in the given message after merging, and vice versa.
func (*Message) MergeIntoDeterministic ¶
MergeIntoDeterministic merges this dynamic message into the given message. It is just like MergeInto, but it attempts to produce deterministic results. That means that if the target is a generated message (not another dynamic message) and the current runtime is unaware of any fields or extensions that are present in m, they will be serialized into the target's unrecognized fields deterministically.
func (*Message) ProtoMessage ¶
func (m *Message) ProtoMessage()
ProtoMessage is present to satisfy the proto.Message interface.
func (*Message) PutMapField ¶
func (m *Message) PutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{})
PutMapField sets the value for the given map field descriptor and given key to the given value. It panics if an error is encountered. See TryPutMapField.
func (*Message) PutMapFieldByName ¶
PutMapFieldByName sets the value for the map field with the given name and given key to the given value. It panics if an error is encountered. See TryPutMapFieldByName.
func (*Message) PutMapFieldByNumber ¶
PutMapFieldByNumber sets the value for the map field with the given tag number and given key to the given value. It panics if an error is encountered. See TryPutMapFieldByNumber.
func (*Message) RemoveMapField ¶
func (m *Message) RemoveMapField(fd *desc.FieldDescriptor, key interface{})
RemoveMapField changes the value for the given field descriptor by removing any value associated with the given key. It panics if an error is encountered. See TryRemoveMapField.
func (*Message) RemoveMapFieldByName ¶
RemoveMapFieldByName changes the value for the field with the given name by removing any value associated with the given key. It panics if an error is encountered. See TryRemoveMapFieldByName.
func (*Message) RemoveMapFieldByNumber ¶
RemoveMapFieldByNumber changes the value for the field with the given tag number by removing any value associated with the given key. It panics if an error is encountered. See TryRemoveMapFieldByNumber.
func (*Message) Reset ¶
func (m *Message) Reset()
Reset resets this message to an empty message. It removes all values set in the message.
func (*Message) SetField ¶
func (m *Message) SetField(fd *desc.FieldDescriptor, val interface{})
SetField sets the value for the given field descriptor to the given value. It panics if an error is encountered. See TrySetField.
func (*Message) SetFieldByName ¶
SetFieldByName sets the value for the field with the given name to the given value. It panics if an error is encountered. See TrySetFieldByName.
func (*Message) SetFieldByNumber ¶
SetFieldByNumber sets the value for the field with the given tag number to the given value. It panics if an error is encountered. See TrySetFieldByNumber.
func (*Message) SetRepeatedField ¶
func (m *Message) SetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{})
SetRepeatedField sets the value for the given repeated field descriptor and given index to the given value. It panics if an error is encountered. See SetRepeatedField.
func (*Message) SetRepeatedFieldByName ¶
SetRepeatedFieldByName sets the value for the repeated field with the given name and given index to the given value. It panics if an error is encountered. See TrySetRepeatedFieldByName.
func (*Message) SetRepeatedFieldByNumber ¶
SetRepeatedFieldByNumber sets the value for the repeated field with the given tag number and given index to the given value. It panics if an error is encountered. See TrySetRepeatedFieldByNumber.
func (*Message) TryAddRepeatedField ¶
func (m *Message) TryAddRepeatedField(fd *desc.FieldDescriptor, val interface{}) error
TryAddRepeatedField appends the given value to the given repeated field. An error is returned if the given field descriptor does not belong to the right message type, if the given field is not repeated, or if the given value is not a correct/compatible type for the given field. If the given field is a map field, the call will succeed if the given value is an instance of the map's entry message type.
The Go type expected for a field is the same as required by TrySetField for a non-repeated field of the same type.
If the given field descriptor is not known (e.g. not present in the message descriptor) it will become known. Subsequent operations using tag numbers or names will be able to resolve the newly-known type. If the message has a value for the unknown value, it is parsed and the given value is appended to it.
func (*Message) TryAddRepeatedFieldByName ¶
TryAddRepeatedFieldByName appends the given value to the repeated field with the given name. An error is returned if the given name is unknown, if it names a field that is not repeated, or if the given value has an incorrect type.
(See TrySetField for more info on types.)
func (*Message) TryAddRepeatedFieldByNumber ¶
TryAddRepeatedFieldByNumber appends the given value to the repeated field with the given tag number. An error is returned if the given tag is unknown, if it indicates a field that is not repeated, or if the given value has an incorrect type.
(See TrySetField for more info on types.)
func (*Message) TryClearField ¶
func (m *Message) TryClearField(fd *desc.FieldDescriptor) error
TryClearField removes any value for the given field. An error is returned if the given field descriptor does not belong to the right message type.
func (*Message) TryClearFieldByName ¶
TryClearFieldByName removes any value for the field with the given name. An error is returned if the given name is unknown. If the given name refers to an extension field, it should be fully qualified and optionally enclosed in parenthesis or brackets.
func (*Message) TryClearFieldByNumber ¶
TryClearFieldByNumber removes any value for the field with the given tag number. An error is returned if the given tag is unknown.
func (*Message) TryClearOneOfField ¶
func (m *Message) TryClearOneOfField(od *desc.OneOfDescriptor) error
TryClearOneOfField removes any value for any of the given one-of's fields. An error is returned if the given one-of descriptor does not belong to the right message type.
func (*Message) TryFieldLength ¶
func (m *Message) TryFieldLength(fd *desc.FieldDescriptor) (int, error)
TryFieldLength returns the number of elements in this message for the given field descriptor. An error is returned if the given field descriptor does not belong to the right message type or if it is neither a map field nor a repeated field.
func (*Message) TryFieldLengthByName ¶
TryFieldLengthByName returns the number of elements in this message for the field with the given name. An error is returned if the given name is unknown or if the named field is neither a map field nor a repeated field.
func (*Message) TryFieldLengthByNumber ¶
TryFieldLengthByNumber returns the number of elements in this message for the field with the given tag number. An error is returned if the given tag is unknown or if the named field is neither a map field nor a repeated field.
func (*Message) TryForEachMapFieldEntry ¶
func (m *Message) TryForEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) error
TryForEachMapFieldEntry executes the given function for each entry in the map value for the given field descriptor. An error is returned if the given field descriptor does not belong to the right message type or if it is not a map field.
Iteration ends either when all entries have been examined or when the given function returns false. So the function is expected to return true for normal iteration and false to break out. If this message has no value for the given field, it returns without invoking the given function.
The Go type of the key and value supplied to the function mirrors the type that protoc would generate for the field. (See TryGetField for more details on types).
If the given field descriptor is not known (e.g. not present in the message descriptor) but corresponds to an unknown field, the unknown value will be parsed and become known. The parsed value will be searched for the requested key and any value returned. An error will be returned if the unknown value cannot be parsed according to the field descriptor's type information.
func (*Message) TryForEachMapFieldEntryByName ¶
func (m *Message) TryForEachMapFieldEntryByName(name string, fn func(key, val interface{}) bool) error
TryForEachMapFieldEntryByName executes the given function for each entry in the map value for the field with the given name. It stops iteration if the function returns false. An error is returned if the given name is unknown or if it names a field that is not a map field.
If this message has no value for the given field, it returns without ever invoking the given function.
(See TryGetField for more info on types supplied to the function.)
func (*Message) TryForEachMapFieldEntryByNumber ¶
func (m *Message) TryForEachMapFieldEntryByNumber(tagNumber int, fn func(key, val interface{}) bool) error
TryForEachMapFieldEntryByNumber executes the given function for each entry in the map value for the field with the given tag number. It stops iteration if the function returns false. An error is returned if the given tag is unknown or if it indicates a field that is not a map field.
If this message has no value for the given field, it returns without ever invoking the given function.
(See TryGetField for more info on types supplied to the function.)
func (*Message) TryGetField ¶
func (m *Message) TryGetField(fd *desc.FieldDescriptor) (interface{}, error)
TryGetField returns the value for the given field descriptor. An error is returned if the given field descriptor does not belong to the right message type.
The Go type of the returned value, for scalar fields, is the same as protoc would generate for the field (in a non-dynamic message). The table below lists the scalar types and the corresponding Go types.
+-------------------------+-----------+ | Declared Type | Go Type | +-------------------------+-----------+ | int32, sint32, sfixed32 | int32 | | int64, sint64, sfixed64 | int64 | | uint32, fixed32 | uint32 | | uint64, fixed64 | uint64 | | float | float32 | | double | double32 | | bool | bool | | string | string | | bytes | []byte | +-------------------------+-----------+
Values for enum fields will always be int32 values. You can use the enum descriptor associated with the field to lookup value names with those values. Values for message type fields may be an instance of the generated type *or* may be another *dynamic.Message that represents the type.
If the given field is a map field, the returned type will be map[interface{}]interface{}. The actual concrete types of keys and values is as described above. If the given field is a (non-map) repeated field, the returned type is always []interface{}; the type of the actual elements is as described above.
If this message has no value for the given field, its default value is returned. If the message is defined in a file with "proto3" syntax, the default is always the zero value for the field. The default value for map and repeated fields is a nil map or slice (respectively). For field's whose types is a message, the default value is an empty message for "proto2" syntax or a nil message for "proto3" syntax. Note that the in the latter case, a non-nil interface with a nil pointer is returned, not a nil interface. Also note that whether the returned value is an empty message or nil depends on if *this* message was defined as "proto3" syntax, not the message type referred to by the field's type.
If the given field descriptor is not known (e.g. not present in the message descriptor) but corresponds to an unknown field, the unknown value will be parsed and become known. The parsed value will be returned, or an error will be returned if the unknown value cannot be parsed according to the field descriptor's type information.
func (*Message) TryGetFieldByName ¶
TryGetFieldByName returns the value for the field with the given name. An error is returned if the given name is unknown. If the given name refers to an extension field, it should be fully qualified and optionally enclosed in parenthesis or brackets.
If this message has no value for the given field, its default value is returned. (See TryGetField for more info on types and default field values.)
func (*Message) TryGetFieldByNumber ¶
TryGetFieldByNumber returns the value for the field with the given tag number. An error is returned if the given tag is unknown.
If this message has no value for the given field, its default value is returned. (See TryGetField for more info on types and default field values.)
func (*Message) TryGetMapField ¶
func (m *Message) TryGetMapField(fd *desc.FieldDescriptor, key interface{}) (interface{}, error)
TryGetMapField returns the value for the given map field descriptor and given key. An error is returned if the given field descriptor does not belong to the right message type or if it is not a map field.
If the map field does not contain the requested key, this method returns nil, nil. The Go type of the value returned mirrors the type that protoc would generate for the field. (See TryGetField for more details on types).
If the given field descriptor is not known (e.g. not present in the message descriptor) but corresponds to an unknown field, the unknown value will be parsed and become known. The parsed value will be searched for the requested key and any value returned. An error will be returned if the unknown value cannot be parsed according to the field descriptor's type information.
func (*Message) TryGetMapFieldByName ¶
TryGetMapFieldByName returns the value for the map field with the given name and given key. An error is returned if the given name is unknown or if it names a field that is not a map field.
If this message has no value for the given field or the value has no value for the requested key, then this method returns nil, nil.
(See TryGetField for more info on types.)
func (*Message) TryGetMapFieldByNumber ¶
TryGetMapFieldByNumber returns the value for the map field with the given tag number and given key. An error is returned if the given tag is unknown or if it indicates a field that is not a map field.
If this message has no value for the given field or the value has no value for the requested key, then this method returns nil, nil.
(See TryGetField for more info on types.)
func (*Message) TryGetOneOfField ¶
func (m *Message) TryGetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{}, error)
TryGetOneOfField returns which of the given one-of's fields is set and the corresponding value. An error is returned if the given one-of belongs to the wrong message type. If the given one-of has no field set, this method will return nil, nil.
The type of the value, if one is set, is the same as would be returned by TryGetField using the returned field descriptor.
Like with TryGetField, if the given one-of contains any fields that are not known (e.g. not present in this message's descriptor), they will become known and any unknown value will be parsed (and become a known value on success).
func (*Message) TryGetRepeatedField ¶
func (m *Message) TryGetRepeatedField(fd *desc.FieldDescriptor, index int) (interface{}, error)
TryGetRepeatedField returns the value for the given repeated field descriptor at the given index. An error is returned if the given field descriptor does not belong to the right message type, if it is not a repeated field, or if the given index is out of range (less than zero or greater than or equal to the length of the repeated field). Also, even though map fields technically are repeated fields, if the given field is a map field an error will result: map representation does not lend itself to random access by index.
The Go type of the value returned mirrors the type that protoc would generate for the field's element type. (See TryGetField for more details on types).
If the given field descriptor is not known (e.g. not present in the message descriptor) but corresponds to an unknown field, the unknown value will be parsed and become known. The value at the given index in the parsed value will be returned. An error will be returned if the unknown value cannot be parsed according to the field descriptor's type information.
func (*Message) TryGetRepeatedFieldByName ¶
TryGetRepeatedFieldByName returns the value for the repeated field with the given name at the given index. An error is returned if the given name is unknown, if it names a field that is not a repeated field (or is a map field), or if the given index is out of range (less than zero or greater than or equal to the length of the repeated field).
(See TryGetField for more info on types.)
func (*Message) TryGetRepeatedFieldByNumber ¶
TryGetRepeatedFieldByNumber returns the value for the repeated field with the given tag number at the given index. An error is returned if the given tag is unknown, if it indicates a field that is not a repeated field (or is a map field), or if the given index is out of range (less than zero or greater than or equal to the length of the repeated field).
(See TryGetField for more info on types.)
func (*Message) TryPutMapField ¶
func (m *Message) TryPutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) error
TryPutMapField sets the value for the given map field descriptor and given key to the given value. An error is returned if the given field descriptor does not belong to the right message type, if the given field is not a map field, or if the given value is not a correct/compatible type for the given field.
The Go type expected for a field is the same as required by TrySetField for a field with the same type as the map's value type.
If the given field descriptor is not known (e.g. not present in the message descriptor) it will become known. Subsequent operations using tag numbers or names will be able to resolve the newly-known type. If the message has a value for the unknown value, it is cleared, replaced by the given known value.
func (*Message) TryPutMapFieldByName ¶
TryPutMapFieldByName sets the value for the map field with the given name and the given key to the given value. An error is returned if the given name is unknown, if it names a field that is not a map, or if the given value has an incorrect type.
(See TrySetField for more info on types.)
func (*Message) TryPutMapFieldByNumber ¶
TryPutMapFieldByNumber sets the value for the map field with the given tag number and the given key to the given value. An error is returned if the given tag is unknown, if it indicates a field that is not a map, or if the given value has an incorrect type.
(See TrySetField for more info on types.)
func (*Message) TryRemoveMapField ¶
func (m *Message) TryRemoveMapField(fd *desc.FieldDescriptor, key interface{}) error
TryRemoveMapField changes the value for the given field descriptor by removing any value associated with the given key. An error is returned if the given field descriptor does not belong to the right message type or if the given field is not a map field.
If the given field descriptor is not known (e.g. not present in the message descriptor) it will become known. Subsequent operations using tag numbers or names will be able to resolve the newly-known type. If the message has a value for the unknown value, it is parsed and any value for the given key removed.
func (*Message) TryRemoveMapFieldByName ¶
TryRemoveMapFieldByName changes the value for the field with the given name by removing any value associated with the given key. An error is returned if the given name is unknown or if it names a field that is not a map.
func (*Message) TryRemoveMapFieldByNumber ¶
TryRemoveMapFieldByNumber changes the value for the field with the given tag number by removing any value associated with the given key. An error is returned if the given tag is unknown or if it indicates a field that is not a map.
func (*Message) TrySetField ¶
func (m *Message) TrySetField(fd *desc.FieldDescriptor, val interface{}) error
TrySetField sets the value for the given field descriptor to the given value. An error is returned if the given field descriptor does not belong to the right message type or if the given value is not a correct/compatible type for the given field.
The Go type expected for a field is the same as TryGetField would return for the field. So message values can be supplied as either the correct generated message type or as a *dynamic.Message.
Since it is cumbersome to work with dynamic messages, some concessions are made to simplify usage regarding types:
- If a numeric type is provided that can be converted *without loss or overflow*, it is accepted. This allows for setting int64 fields using int or int32 values. Similarly for uint64 with uint and uint32 values and for float64 fields with float32 values.
- The value can be a named type, as long as its underlying type is correct.
- Map and repeated fields can be set using any kind of concrete map or slice type, as long as the values within are all of the correct type. So a field defined as a 'map<string, int32>` can be set using a map[string]int32, a map[string]interface{}, or even a map[interface{}]interface{}.
- Finally, dynamic code that chooses to not treat maps as a special-case find that they can set map fields using a slice where each element is a message that matches the implicit map-entry field message type.
If the given field descriptor is not known (e.g. not present in the message descriptor) it will become known. Subsequent operations using tag numbers or names will be able to resolve the newly-known type. If the message has a value for the unknown value, it is cleared, replaced by the given known value.
func (*Message) TrySetFieldByName ¶
TrySetFieldByName sets the value for the field with the given name to the given value. An error is returned if the given name is unknown or if the given value has an incorrect type. If the given name refers to an extension field, it should be fully qualified and optionally enclosed in parenthesis or brackets.
(See TrySetField for more info on types.)
func (*Message) TrySetFieldByNumber ¶
TrySetFieldByNumber sets the value for the field with the given tag number to the given value. An error is returned if the given tag is unknown or if the given value has an incorrect type.
(See TrySetField for more info on types.)
func (*Message) TrySetRepeatedField ¶
func (m *Message) TrySetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) error
TrySetRepeatedField sets the value for the given repeated field descriptor and given index to the given value. An error is returned if the given field descriptor does not belong to the right message type, if the given field is not repeated, or if the given value is not a correct/compatible type for the given field. Also, even though map fields technically are repeated fields, if the given field is a map field an error will result: map representation does not lend itself to random access by index.
The Go type expected for a field is the same as required by TrySetField for a non-repeated field of the same type.
If the given field descriptor is not known (e.g. not present in the message descriptor) it will become known. Subsequent operations using tag numbers or names will be able to resolve the newly-known type. If the message has a value for the unknown value, it is parsed and the element at the given index is replaced with the given value.
func (*Message) TrySetRepeatedFieldByName ¶
TrySetRepeatedFieldByName sets the value for the repeated field with the given name and the given index to the given value. An error is returned if the given name is unknown, if it names a field that is not repeated (or is a map field), or if the given value has an incorrect type.
(See TrySetField for more info on types.)
func (*Message) TrySetRepeatedFieldByNumber ¶
TrySetRepeatedFieldByNumber sets the value for the repeated field with the given tag number and the given index to the given value. An error is returned if the given tag is unknown, if it indicates a field that is not repeated (or is a map field), or if the given value has an incorrect type.
(See TrySetField for more info on types.)
func (*Message) Unmarshal ¶
Unmarshal de-serializes the message that is present in the given bytes into this message. It first resets the current message. It returns an error if the given bytes do not contain a valid encoding of this message type.
func (*Message) UnmarshalJSON ¶
UnmarshalJSON de-serializes the message that is present, in JSON format, in the given bytes into this message. It first resets the current message. It returns an error if the given bytes do not contain a valid encoding of this message type in JSON format.
This method is shorthand for invoking UnmarshalJSONPB with a default (zero value) unmarshaler:
m.UnmarshalMergeJSONPB(&jsonpb.Unmarshaler{}, js)
So unknown fields will result in an error, and no provided jsonpb.AnyResolver will be used when parsing google.protobuf.Any messages.
func (*Message) UnmarshalJSONPB ¶
func (m *Message) UnmarshalJSONPB(opts *jsonpb.Unmarshaler, js []byte) error
UnmarshalJSONPB de-serializes the message that is present, in JSON format, in the given bytes into this message. The given unmarshaler conveys options used when parsing the JSON. This function first resets the current message. It returns an error if the given bytes do not contain a valid encoding of this message type in JSON format.
The decoding is lenient:
- The JSON can refer to fields either by their JSON name or by their declared name.
- The JSON can use either numeric values or string names for enum values.
When instantiating nested messages, if this message's associated factory returns a generated message type (as opposed to a dynamic message), the given unmarshaler is used to unmarshal it.
When unmarshaling any nested messages, any jsonpb.AnyResolver configured in the given unmarshaler is augmented with knowledge of message types known to this message's descriptor (and its enclosing file and set of transitive dependencies).
func (*Message) UnmarshalMerge ¶
UnmarshalMerge de-serializes the message that is present in the given bytes into this message. Unlike Unmarshal, it does not first reset the message, instead merging the data in the given bytes into the existing data in this message.
func (*Message) UnmarshalMergeJSON ¶
UnmarshalMergeJSON de-serializes the message that is present, in JSON format, in the given bytes into this message. Unlike UnmarshalJSON, it does not first reset the message, instead merging the data in the given bytes into the existing data in this message.
func (*Message) UnmarshalMergeJSONPB ¶
func (m *Message) UnmarshalMergeJSONPB(opts *jsonpb.Unmarshaler, js []byte) error
UnmarshalMergeJSONPB de-serializes the message that is present, in JSON format, in the given bytes into this message. The given unmarshaler conveys options used when parsing the JSON. Unlike UnmarshalJSONPB, it does not first reset the message, instead merging the data in the given bytes into the existing data in this message.
func (*Message) UnmarshalMergeText ¶
UnmarshalMergeText de-serializes the message that is present, in text format, in the given bytes into this message. Unlike UnmarshalText, it does not first reset the message, instead merging the data in the given bytes into the existing data in this message.
func (*Message) UnmarshalText ¶
UnmarshalText de-serializes the message that is present, in text format, in the given bytes into this message. It first resets the current message. It returns an error if the given bytes do not contain a valid encoding of this message type in the standard text format
func (*Message) Validate ¶
Validate checks that all required fields are present. It returns an error if any are absent.
func (*Message) ValidateRecursive ¶
ValidateRecursive checks that all required fields are present and also recursively validates all fields who are also messages. It returns an error if any required fields, in this message or nested within, are absent.
func (*Message) XXX_MessageName ¶
XXX_MessageName returns the fully qualified name of this message's type. This allows dynamic messages to be used with proto.MessageName.
type MessageFactory ¶
type MessageFactory struct {
// contains filtered or unexported fields
}
MessageFactory can be used to create new empty message objects. A default instance (without extension registry or known-type registry specified) will always return dynamic messages (e.g. type will be *dynamic.Message) except for "well-known" types. The well-known types include primitive wrapper types and a handful of other special types defined in standard protobuf definitions, like Any, Duration, and Timestamp.
func NewMessageFactoryWithDefaults ¶
func NewMessageFactoryWithDefaults() *MessageFactory
NewMessageFactoryWithDefaults creates a new message factory where all "default" types (those for which protoc-generated code is statically linked into the Go program) are known types. If any dynamic messages are produced, they will recognize and parse all "default" extension fields. This is the equivalent of:
NewMessageFactoryWithRegistries( NewExtensionRegistryWithDefaults(), NewKnownTypeRegistryWithDefaults())
func NewMessageFactoryWithExtensionRegistry ¶
func NewMessageFactoryWithExtensionRegistry(er *ExtensionRegistry) *MessageFactory
NewMessageFactoryWithExtensionRegistry creates a new message factory where any dynamic messages produced will use the given extension registry to recognize and parse extension fields.
func NewMessageFactoryWithKnownTypeRegistry ¶
func NewMessageFactoryWithKnownTypeRegistry(ktr *KnownTypeRegistry) *MessageFactory
NewMessageFactoryWithKnownTypeRegistry creates a new message factory where the known types, per the given registry, will be returned as normal protobuf messages (e.g. generated structs, instead of dynamic messages).
func NewMessageFactoryWithRegistries ¶
func NewMessageFactoryWithRegistries(er *ExtensionRegistry, ktr *KnownTypeRegistry) *MessageFactory
NewMessageFactoryWithRegistries creates a new message factory with the given extension and known type registries.
func (*MessageFactory) GetExtensionRegistry ¶
func (f *MessageFactory) GetExtensionRegistry() *ExtensionRegistry
GetExtensionRegistry returns the extension registry that this factory uses to create dynamic messages. The registry is used by dynamic messages to recognize and parse extension fields during de-serialization.
func (*MessageFactory) GetKnownTypeRegistry ¶
func (f *MessageFactory) GetKnownTypeRegistry() *KnownTypeRegistry
GetKnownTypeRegistry returns the known type registry that this factory uses to instantiate known (e.g. generated) message types.
func (*MessageFactory) NewDynamicMessage ¶
func (f *MessageFactory) NewDynamicMessage(md *desc.MessageDescriptor) *Message
NewDynamicMessage creates a new empty dynamic message that corresponds to the given descriptor. This is like f.NewMessage(md) except the known type registry is not consulted so the return value is always a dynamic message.
This is also like dynamic.NewMessage(md) except that the returned message will use this factory when creating other messages, like during de-serialization of fields that are themselves message types.
func (*MessageFactory) NewMessage ¶
func (f *MessageFactory) NewMessage(md *desc.MessageDescriptor) proto.Message
NewMessage creates a new empty message that corresponds to the given descriptor. If the given descriptor describes a "known type" then that type is instantiated. Otherwise, an empty dynamic message is returned.
type UnknownField ¶
type UnknownField struct { // Encoding indicates how the unknown field was encoded on the wire. If it // is proto.WireBytes or proto.WireGroupStart then Contents will be set to // the raw bytes. If it is proto.WireTypeFixed32 then the data is in the least // significant 32 bits of Value. Otherwise, the data is in all 64 bits of // Value. Encoding int8 Contents []byte Value uint64 }
UnknownField represents a field that was parsed from the binary wire format for a message, but was not a recognized field number. Enough information is preserved so that re-serializing the message won't lose any of the unrecognized data.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package grpcdynamic provides a dynamic RPC stub.
|
Package grpcdynamic provides a dynamic RPC stub. |
Package msgregistry contains a registry of known message and enum types.
|
Package msgregistry contains a registry of known message and enum types. |