dynamic

package
v1.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2019 License: Apache-2.0 Imports: 27 Imported by: 330

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:

  1. 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.
  2. Another call site retrieves a newer descriptor, A', which includes a newly added field with tag T.
  3. 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.
  4. 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

Constants

This section is empty.

Variables

View Source
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.

View Source
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.

View Source
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.

View Source
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.

View Source
var ErrUnknownFieldName = errors.New("unknown field name")

ErrUnknownFieldName is an error that is returned when an operation refers to an unknown field name.

View Source
var ErrUnknownTagNumber = errors.New("unknown tag number")

ErrUnknownTagNumber is an error that is returned when an operation refers to an unknown tag number.

View Source
var FieldIsNotMapError = ErrFieldIsNotMap

FieldIsNotMapError is the same as ErrFieldIsNotMap. Deprecated: use ErrFieldIsNotMap

View Source
var FieldIsNotRepeatedError = ErrFieldIsNotRepeated

FieldIsNotRepeatedError is the same as ErrFieldIsNotRepeated. Deprecated: use ErrFieldIsNotRepeated

View Source
var IndexOutOfRangeError = ErrIndexOutOfRange

IndexOutOfRangeError is the same as ErrIndexOutOfRange. Deprecated: use ErrIndexOutOfRange

View Source
var NumericOverflowError = ErrNumericOverflow

NumericOverflowError is the same as ErrNumericOverflow. Deprecated: use ErrNumericOverflow

View Source
var UnknownFieldNameError = ErrUnknownFieldName

UnknownFieldNameError is the same as ErrUnknownFieldName. Deprecated: use ErrUnknownFieldName

View Source
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

func Equal(a, b *Message) bool

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

func Merge(dst, src proto.Message)

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

func MessagesEqual(a, b proto.Message) bool

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 added in v1.2.0

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.

func TryMerge

func TryMerge(dst, src proto.Message) error

TryMerge merges the given source message into the given destination message. You can use this instead of proto.Merge when one or both of the messages might be a dynamic message. Unlike proto.Merge, this method will return an error on failure instead of panic'ing.

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 added in v1.2.0

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

func AsDynamicMessage(msg proto.Message) (*Message, error)

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

func (m *Message) AddRepeatedFieldByName(name string, val interface{})

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

func (m *Message) AddRepeatedFieldByNumber(tagNumber int, val interface{})

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

func (m *Message) ClearFieldByName(name string)

ClearFieldByName removes any value for the field with the given name. It panics if an error is encountered. See TryClearFieldByName.

func (*Message) ClearFieldByNumber

func (m *Message) ClearFieldByNumber(tagNumber int)

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

func (m *Message) ConvertFrom(target proto.Message) error

ConvertFrom converts the given message into this dynamic message. This is shorthand for resetting then merging:

m.Reset()
m.MergeFrom(target)

func (*Message) ConvertTo

func (m *Message) ConvertTo(target proto.Message) error

ConvertTo converts this dynamic message into the given message. This is shorthand for resetting then merging:

target.Reset()
m.MergeInto(target)

func (*Message) Descriptor

func (m *Message) Descriptor() ([]byte, []int)

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

func (m *Message) FieldLengthByName(name string) int

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

func (m *Message) FieldLengthByNumber(tagNumber int32) int

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

func (m *Message) ForEachMapFieldEntryByName(name string, fn func(key, val interface{}) bool)

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

func (m *Message) ForEachMapFieldEntryByNumber(tagNumber int, fn func(key, val interface{}) bool)

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

func (m *Message) GetFieldByName(name string) interface{}

GetFieldByName returns the value for the field with the given name. It panics if an error is encountered. See TryGetFieldByName.

func (*Message) GetFieldByNumber

func (m *Message) GetFieldByNumber(tagNumber int) interface{}

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

func (m *Message) GetMapFieldByName(name string, key interface{}) interface{}

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

func (m *Message) GetMapFieldByNumber(tagNumber int, key interface{}) interface{}

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

func (m *Message) GetRepeatedFieldByName(name string, index int) interface{}

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

func (m *Message) GetRepeatedFieldByNumber(tagNumber int, index int) interface{}

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

func (m *Message) GetUnknownFields() []int32

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

func (m *Message) HasFieldName(name string) bool

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

func (m *Message) HasFieldNumber(tagNumber int) bool

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

func (m *Message) Marshal() ([]byte, error)

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 added in v1.3.0

func (m *Message) MarshalAppend(b []byte) ([]byte, error)

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 added in v1.5.0

func (m *Message) MarshalAppendDeterministic(b []byte) ([]byte, error)

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

func (m *Message) MarshalDeterministic() ([]byte, error)

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

func (m *Message) MarshalJSON() ([]byte, error)

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

func (m *Message) MarshalJSONIndent() ([]byte, error)

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

func (m *Message) MarshalJSONPB(opts *jsonpb.Marshaler) ([]byte, error)

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

func (m *Message) MarshalText() ([]byte, error)

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

func (m *Message) MarshalTextIndent() ([]byte, error)

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

func (m *Message) Merge(source proto.Message)

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

func (m *Message) MergeFrom(source proto.Message) error

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

func (m *Message) MergeInto(target proto.Message) error

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) 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

func (m *Message) PutMapFieldByName(name string, key interface{}, val interface{})

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

func (m *Message) PutMapFieldByNumber(tagNumber int, key interface{}, val interface{})

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

func (m *Message) RemoveMapFieldByName(name string, key interface{})

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

func (m *Message) RemoveMapFieldByNumber(tagNumber int, key interface{})

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

func (m *Message) SetFieldByName(name string, val interface{})

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

func (m *Message) SetFieldByNumber(tagNumber int, val interface{})

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

func (m *Message) SetRepeatedFieldByName(name string, index int, val interface{})

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

func (m *Message) SetRepeatedFieldByNumber(tagNumber int, index int, val interface{})

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) String

func (m *Message) String() string

String returns this message rendered in compact text format.

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

func (m *Message) TryAddRepeatedFieldByName(name string, val interface{}) error

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

func (m *Message) TryAddRepeatedFieldByNumber(tagNumber int, val interface{}) error

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

func (m *Message) TryClearFieldByName(name string) error

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

func (m *Message) TryClearFieldByNumber(tagNumber int) error

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

func (m *Message) TryFieldLengthByName(name string) (int, error)

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

func (m *Message) TryFieldLengthByNumber(tagNumber int32) (int, error)

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

func (m *Message) TryGetFieldByName(name string) (interface{}, error)

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

func (m *Message) TryGetFieldByNumber(tagNumber int) (interface{}, error)

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

func (m *Message) TryGetMapFieldByName(name string, key interface{}) (interface{}, error)

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

func (m *Message) TryGetMapFieldByNumber(tagNumber int, key interface{}) (interface{}, error)

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

func (m *Message) TryGetRepeatedFieldByName(name string, index int) (interface{}, error)

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

func (m *Message) TryGetRepeatedFieldByNumber(tagNumber int, index int) (interface{}, error)

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

func (m *Message) TryPutMapFieldByName(name string, key interface{}, val interface{}) error

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

func (m *Message) TryPutMapFieldByNumber(tagNumber int, key interface{}, val interface{}) error

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

func (m *Message) TryRemoveMapFieldByName(name string, key interface{}) error

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

func (m *Message) TryRemoveMapFieldByNumber(tagNumber int, key interface{}) error

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:

  1. 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.
  2. The value can be a named type, as long as its underlying type is correct.
  3. 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{}.
  4. 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

func (m *Message) TrySetFieldByName(name string, val interface{}) error

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

func (m *Message) TrySetFieldByNumber(tagNumber int, val interface{}) error

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

func (m *Message) TrySetRepeatedFieldByName(name string, index int, val interface{}) error

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

func (m *Message) TrySetRepeatedFieldByNumber(tagNumber int, index int, val interface{}) error

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

func (m *Message) Unmarshal(b []byte) error

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

func (m *Message) UnmarshalJSON(js []byte) error

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:

  1. The JSON can refer to fields either by their JSON name or by their declared name.
  2. 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

func (m *Message) UnmarshalMerge(b []byte) error

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

func (m *Message) UnmarshalMergeJSON(js []byte) error

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

func (m *Message) UnmarshalMergeText(text []byte) error

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

func (m *Message) UnmarshalText(text []byte) error

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

func (m *Message) Validate() error

Validate checks that all required fields are present. It returns an error if any are absent.

func (*Message) ValidateRecursive

func (m *Message) ValidateRecursive() error

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

func (m *Message) XXX_MessageName() string

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.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL