dynamic

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2018 License: Apache-2.0 Imports: 21 Imported by: 0

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 ErrOverflow = errors.New("proto: integer overflow")

ErrOverflow is returned when an integer is too large to be represented.

View Source
var FieldIsNotMapError = errors.New("Field is not a map type")
View Source
var FieldIsNotRepeatedError = errors.New("Field is not repeated")
View Source
var IndexOutOfRangeError = errors.New("Index is out of range")
View Source
var NumericOverflowError = errors.New("Numeric value is out of range")
View Source
var UnknownFieldNameError = errors.New("Unknown field name")
View Source
var UnknownTagNumberError = errors.New("Unknown tag number")

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 will 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 this instead of proto.Merge when one or both of the messages might be 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 TryMerge

func TryMerge(dst, src proto.Message) error

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.

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.

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 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 (*Message) AddRepeatedField

func (m *Message) AddRepeatedField(fd *desc.FieldDescriptor, val interface{})

func (*Message) AddRepeatedFieldByName

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

func (*Message) AddRepeatedFieldByNumber

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

func (*Message) ClearField

func (m *Message) ClearField(fd *desc.FieldDescriptor)

func (*Message) ClearFieldByName

func (m *Message) ClearFieldByName(name string)

func (*Message) ClearFieldByNumber

func (m *Message) ClearFieldByNumber(tagNumber int)

func (*Message) ConvertFrom

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

func (*Message) ConvertTo

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

func (*Message) Descriptor

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

func (*Message) FieldLength

func (m *Message) FieldLength(fd *desc.FieldDescriptor) int

func (*Message) FieldLengthByName

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

func (*Message) FieldLengthByNumber

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

func (*Message) FindFieldDescriptor

func (m *Message) FindFieldDescriptor(tagNumber int32) *desc.FieldDescriptor

func (*Message) FindFieldDescriptorByJSONName

func (m *Message) FindFieldDescriptorByJSONName(name string) *desc.FieldDescriptor

func (*Message) FindFieldDescriptorByName

func (m *Message) FindFieldDescriptorByName(name string) *desc.FieldDescriptor

func (*Message) GetField

func (m *Message) GetField(fd *desc.FieldDescriptor) interface{}

func (*Message) GetFieldByName

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

func (*Message) GetFieldByNumber

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

func (*Message) GetKnownExtensions

func (m *Message) GetKnownExtensions() []*desc.FieldDescriptor

func (*Message) GetKnownFields

func (m *Message) GetKnownFields() []*desc.FieldDescriptor

func (*Message) GetMapField

func (m *Message) GetMapField(fd *desc.FieldDescriptor, key interface{}) interface{}

func (*Message) GetMapFieldByName

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

func (*Message) GetMapFieldByNumber

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

func (*Message) GetMessageDescriptor

func (m *Message) GetMessageDescriptor() *desc.MessageDescriptor

func (*Message) GetOneOfField

func (m *Message) GetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{})

func (*Message) GetRepeatedField

func (m *Message) GetRepeatedField(fd *desc.FieldDescriptor, index int) interface{}

func (*Message) GetRepeatedFieldByName

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

func (*Message) GetRepeatedFieldByNumber

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

func (*Message) GetUnknownField

func (m *Message) GetUnknownField(tagNumber int32) []UnknownField

func (*Message) GetUnknownFields

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

func (*Message) HasField

func (m *Message) HasField(fd *desc.FieldDescriptor) bool

func (*Message) HasFieldName

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

func (*Message) HasFieldNumber

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

func (*Message) Marshal

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

func (*Message) MarshalJSON

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

func (*Message) MarshalJSONIndent

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

func (*Message) MarshalJSONPB

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

func (*Message) MarshalText

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

func (*Message) MarshalTextIndent

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

func (*Message) MergeFrom

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

func (*Message) MergeInto

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

func (*Message) ProtoMessage

func (m *Message) ProtoMessage()

func (*Message) PutMapField

func (m *Message) PutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{})

func (*Message) PutMapFieldByName

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

func (*Message) PutMapFieldByNumber

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

func (*Message) RemoveMapField

func (m *Message) RemoveMapField(fd *desc.FieldDescriptor, key interface{})

func (*Message) RemoveMapFieldByName

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

func (*Message) RemoveMapFieldByNumber

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

func (*Message) Reset

func (m *Message) Reset()

func (*Message) SetField

func (m *Message) SetField(fd *desc.FieldDescriptor, val interface{})

func (*Message) SetFieldByName

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

func (*Message) SetFieldByNumber

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

func (*Message) SetRepeatedField

func (m *Message) SetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{})

func (*Message) SetRepeatedFieldByName

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

func (*Message) SetRepeatedFieldByNumber

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

func (*Message) String

func (m *Message) String() string

func (*Message) TryAddRepeatedField

func (m *Message) TryAddRepeatedField(fd *desc.FieldDescriptor, val interface{}) error

func (*Message) TryAddRepeatedFieldByName

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

func (*Message) TryAddRepeatedFieldByNumber

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

func (*Message) TryClearField

func (m *Message) TryClearField(fd *desc.FieldDescriptor) error

func (*Message) TryClearFieldByName

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

func (*Message) TryClearFieldByNumber

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

func (*Message) TryFieldLength

func (m *Message) TryFieldLength(fd *desc.FieldDescriptor) (int, error)

func (*Message) TryFieldLengthByName

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

func (*Message) TryFieldLengthByNumber

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

func (*Message) TryGetField

func (m *Message) TryGetField(fd *desc.FieldDescriptor) (interface{}, error)

func (*Message) TryGetFieldByName

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

func (*Message) TryGetFieldByNumber

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

func (*Message) TryGetMapField

func (m *Message) TryGetMapField(fd *desc.FieldDescriptor, key interface{}) (interface{}, error)

func (*Message) TryGetMapFieldByName

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

func (*Message) TryGetMapFieldByNumber

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

func (*Message) TryGetOneOfField

func (m *Message) TryGetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{}, error)

func (*Message) TryGetRepeatedField

func (m *Message) TryGetRepeatedField(fd *desc.FieldDescriptor, index int) (interface{}, error)

func (*Message) TryGetRepeatedFieldByName

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

func (*Message) TryGetRepeatedFieldByNumber

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

func (*Message) TryPutMapField

func (m *Message) TryPutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) error

func (*Message) TryPutMapFieldByName

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

func (*Message) TryPutMapFieldByNumber

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

func (*Message) TryRemoveMapField

func (m *Message) TryRemoveMapField(fd *desc.FieldDescriptor, key interface{}) error

func (*Message) TryRemoveMapFieldByName

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

func (*Message) TryRemoveMapFieldByNumber

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

func (*Message) TrySetField

func (m *Message) TrySetField(fd *desc.FieldDescriptor, val interface{}) error

func (*Message) TrySetFieldByName

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

func (*Message) TrySetFieldByNumber

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

func (*Message) TrySetRepeatedField

func (m *Message) TrySetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) error

func (*Message) TrySetRepeatedFieldByName

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

func (*Message) TrySetRepeatedFieldByNumber

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

func (*Message) Unmarshal

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

func (*Message) UnmarshalJSON

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

func (*Message) UnmarshalJSONPB

func (m *Message) UnmarshalJSONPB(opts *jsonpb.Unmarshaler, js []byte) error

func (*Message) UnmarshalMerge

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

func (*Message) UnmarshalMergeJSON

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

func (*Message) UnmarshalMergeJSONPB

func (m *Message) UnmarshalMergeJSONPB(opts *jsonpb.Unmarshaler, js []byte) error

func (*Message) UnmarshalMergeText

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

func (*Message) UnmarshalText

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

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

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