package dynamic import ( "bytes" "compress/gzip" "errors" "fmt" "reflect" "sort" "strings" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/protoc-gen-go/descriptor" "github.com/jhump/protoreflect/codec" "github.com/jhump/protoreflect/desc" "github.com/jhump/protoreflect/internal" ) // ErrUnknownTagNumber is an error that is returned when an operation refers // to an unknown tag number. var ErrUnknownTagNumber = errors.New("unknown tag number") // UnknownTagNumberError is the same as ErrUnknownTagNumber. // Deprecated: use ErrUnknownTagNumber var UnknownTagNumberError = ErrUnknownTagNumber // ErrUnknownFieldName is an error that is returned when an operation refers // to an unknown field name. var ErrUnknownFieldName = errors.New("unknown field name") // UnknownFieldNameError is the same as ErrUnknownFieldName. // Deprecated: use ErrUnknownFieldName var UnknownFieldNameError = ErrUnknownFieldName // ErrFieldIsNotMap is an error that is returned when map-related operations // are attempted with fields that are not maps. var ErrFieldIsNotMap = errors.New("field is not a map type") // FieldIsNotMapError is the same as ErrFieldIsNotMap. // Deprecated: use ErrFieldIsNotMap var FieldIsNotMapError = ErrFieldIsNotMap // ErrFieldIsNotRepeated is an error that is returned when repeated field // operations are attempted with fields that are not repeated. var ErrFieldIsNotRepeated = errors.New("field is not repeated") // FieldIsNotRepeatedError is the same as ErrFieldIsNotRepeated. // Deprecated: use ErrFieldIsNotRepeated var FieldIsNotRepeatedError = ErrFieldIsNotRepeated // ErrIndexOutOfRange is an error that is returned when an invalid index is // provided when access a single element of a repeated field. var ErrIndexOutOfRange = errors.New("index is out of range") // IndexOutOfRangeError is the same as ErrIndexOutOfRange. // Deprecated: use ErrIndexOutOfRange var IndexOutOfRangeError = ErrIndexOutOfRange // ErrNumericOverflow is an error returned by operations that encounter a // numeric value that is too large, for example de-serializing a value into an // int32 field when the value is larger that can fit into a 32-bit value. var ErrNumericOverflow = errors.New("numeric value is out of range") // NumericOverflowError is the same as ErrNumericOverflow. // Deprecated: use ErrNumericOverflow var NumericOverflowError = ErrNumericOverflow var typeOfProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem() var typeOfDynamicMessage = reflect.TypeOf((*Message)(nil)) var typeOfBytes = reflect.TypeOf(([]byte)(nil)) // 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). type Message struct { md *desc.MessageDescriptor er *ExtensionRegistry mf *MessageFactory extraFields map[int32]*desc.FieldDescriptor values map[int32]interface{} unknownFields map[int32][]UnknownField } // 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. 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 } // 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 NewMessage(md *desc.MessageDescriptor) *Message { return NewMessageWithMessageFactory(md, nil) } // 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 NewMessageWithExtensionRegistry(md *desc.MessageDescriptor, er *ExtensionRegistry) *Message { mf := NewMessageFactoryWithExtensionRegistry(er) return NewMessageWithMessageFactory(md, mf) } // 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 NewMessageWithMessageFactory(md *desc.MessageDescriptor, mf *MessageFactory) *Message { var er *ExtensionRegistry if mf != nil { er = mf.er } return &Message{ md: md, mf: mf, er: er, } } // 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 AsDynamicMessage(msg proto.Message) (*Message, error) { return AsDynamicMessageWithMessageFactory(msg, nil) } // 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 AsDynamicMessageWithExtensionRegistry(msg proto.Message, er *ExtensionRegistry) (*Message, error) { mf := NewMessageFactoryWithExtensionRegistry(er) return AsDynamicMessageWithMessageFactory(msg, mf) } // 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 AsDynamicMessageWithMessageFactory(msg proto.Message, mf *MessageFactory) (*Message, error) { if dm, ok := msg.(*Message); ok { return dm, nil } md, err := desc.LoadMessageDescriptorForMessage(msg) if err != nil { return nil, err } dm := NewMessageWithMessageFactory(md, mf) err = dm.mergeFrom(msg) if err != nil { return nil, err } return dm, nil } // GetMessageDescriptor returns a descriptor for this message's type. func (m *Message) GetMessageDescriptor() *desc.MessageDescriptor { return m.md } // GetKnownFields returns a slice of descriptors for all known fields. The // fields will not be in any defined order. func (m *Message) GetKnownFields() []*desc.FieldDescriptor { if len(m.extraFields) == 0 { return m.md.GetFields() } flds := make([]*desc.FieldDescriptor, len(m.md.GetFields()), len(m.md.GetFields())+len(m.extraFields)) copy(flds, m.md.GetFields()) for _, fld := range m.extraFields { if !fld.IsExtension() { flds = append(flds, fld) } } return flds } // 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 (m *Message) GetKnownExtensions() []*desc.FieldDescriptor { if !m.md.IsExtendable() { return nil } exts := m.er.AllExtensionsForType(m.md.GetFullyQualifiedName()) for _, fld := range m.extraFields { if fld.IsExtension() { exts = append(exts, fld) } } return exts } // 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 (m *Message) GetUnknownFields() []int32 { flds := make([]int32, 0, len(m.unknownFields)) for tag := range m.unknownFields { flds = append(flds, tag) } return flds } // 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 (m *Message) Descriptor() ([]byte, []int) { // get encoded file descriptor b, err := proto.Marshal(m.md.GetFile().AsProto()) if err != nil { panic(fmt.Sprintf("failed to get encoded descriptor for %s: %v", m.md.GetFile().GetName(), err)) } var zippedBytes bytes.Buffer w := gzip.NewWriter(&zippedBytes) if _, err := w.Write(b); err != nil { panic(fmt.Sprintf("failed to get encoded descriptor for %s: %v", m.md.GetFile().GetName(), err)) } if err := w.Close(); err != nil { panic(fmt.Sprintf("failed to get an encoded descriptor for %s: %v", m.md.GetFile().GetName(), err)) } // and path to message path := []int{} var d desc.Descriptor name := m.md.GetFullyQualifiedName() for d = m.md.GetParent(); d != nil; name, d = d.GetFullyQualifiedName(), d.GetParent() { found := false switch d := d.(type) { case (*desc.FileDescriptor): for i, md := range d.GetMessageTypes() { if md.GetFullyQualifiedName() == name { found = true path = append(path, i) } } case (*desc.MessageDescriptor): for i, md := range d.GetNestedMessageTypes() { if md.GetFullyQualifiedName() == name { found = true path = append(path, i) } } } if !found { panic(fmt.Sprintf("failed to compute descriptor path for %s", m.md.GetFullyQualifiedName())) } } // reverse the path i := 0 j := len(path) - 1 for i < j { path[i], path[j] = path[j], path[i] i++ j-- } return zippedBytes.Bytes(), path } // XXX_MessageName returns the fully qualified name of this message's type. This // allows dynamic messages to be used with proto.MessageName. func (m *Message) XXX_MessageName() string { return m.md.GetFullyQualifiedName() } // 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 (m *Message) FindFieldDescriptor(tagNumber int32) *desc.FieldDescriptor { fd := m.md.FindFieldByNumber(tagNumber) if fd != nil { return fd } fd = m.er.FindExtension(m.md.GetFullyQualifiedName(), tagNumber) if fd != nil { return fd } return m.extraFields[tagNumber] } // 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 (m *Message) FindFieldDescriptorByName(name string) *desc.FieldDescriptor { if name == "" { return nil } fd := m.md.FindFieldByName(name) if fd != nil { return fd } mustBeExt := false if name[0] == '(' { if name[len(name)-1] != ')' { // malformed name return nil } mustBeExt = true name = name[1 : len(name)-1] } else if name[0] == '[' { if name[len(name)-1] != ']' { // malformed name return nil } mustBeExt = true name = name[1 : len(name)-1] } fd = m.er.FindExtensionByName(m.md.GetFullyQualifiedName(), name) if fd != nil { return fd } for _, fd := range m.extraFields { if fd.IsExtension() && name == fd.GetFullyQualifiedName() { return fd } else if !mustBeExt && !fd.IsExtension() && name == fd.GetName() { return fd } } return nil } // 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 (m *Message) FindFieldDescriptorByJSONName(name string) *desc.FieldDescriptor { if name == "" { return nil } fd := m.md.FindFieldByJSONName(name) if fd != nil { return fd } mustBeExt := false if name[0] == '(' { if name[len(name)-1] != ')' { // malformed name return nil } mustBeExt = true name = name[1 : len(name)-1] } else if name[0] == '[' { if name[len(name)-1] != ']' { // malformed name return nil } mustBeExt = true name = name[1 : len(name)-1] } fd = m.er.FindExtensionByJSONName(m.md.GetFullyQualifiedName(), name) if fd != nil { return fd } for _, fd := range m.extraFields { if fd.IsExtension() && name == fd.GetFullyQualifiedJSONName() { return fd } else if !mustBeExt && !fd.IsExtension() && name == fd.GetJSONName() { return fd } } // try non-JSON names return m.FindFieldDescriptorByName(name) } func (m *Message) checkField(fd *desc.FieldDescriptor) error { return checkField(fd, m.md) } func checkField(fd *desc.FieldDescriptor, md *desc.MessageDescriptor) error { if fd.GetOwner().GetFullyQualifiedName() != md.GetFullyQualifiedName() { return fmt.Errorf("given field, %s, is for wrong message type: %s; expecting %s", fd.GetName(), fd.GetOwner().GetFullyQualifiedName(), md.GetFullyQualifiedName()) } if fd.IsExtension() && !md.IsExtension(fd.GetNumber()) { return fmt.Errorf("given field, %s, is an extension but is not in message extension range: %v", fd.GetFullyQualifiedName(), md.GetExtensionRanges()) } return nil } // GetField returns the value for the given field descriptor. It panics if an // error is encountered. See TryGetField. func (m *Message) GetField(fd *desc.FieldDescriptor) interface{} { if v, err := m.TryGetField(fd); err != nil { panic(err.Error()) } else { return v } } // 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 (m *Message) TryGetField(fd *desc.FieldDescriptor) (interface{}, error) { if err := m.checkField(fd); err != nil { return nil, err } return m.getField(fd) } // GetFieldByName returns the value for the field with the given name. It panics // if an error is encountered. See TryGetFieldByName. func (m *Message) GetFieldByName(name string) interface{} { if v, err := m.TryGetFieldByName(name); err != nil { panic(err.Error()) } else { return v } } // 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 (m *Message) TryGetFieldByName(name string) (interface{}, error) { fd := m.FindFieldDescriptorByName(name) if fd == nil { return nil, UnknownFieldNameError } return m.getField(fd) } // GetFieldByNumber returns the value for the field with the given tag number. // It panics if an error is encountered. See TryGetFieldByNumber. func (m *Message) GetFieldByNumber(tagNumber int) interface{} { if v, err := m.TryGetFieldByNumber(tagNumber); err != nil { panic(err.Error()) } else { return v } } // 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 (m *Message) TryGetFieldByNumber(tagNumber int) (interface{}, error) { fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return nil, UnknownTagNumberError } return m.getField(fd) } func (m *Message) getField(fd *desc.FieldDescriptor) (interface{}, error) { return m.doGetField(fd, false) } func (m *Message) doGetField(fd *desc.FieldDescriptor, nilIfAbsent bool) (interface{}, error) { res := m.values[fd.GetNumber()] if res == nil { var err error if res, err = m.parseUnknownField(fd); err != nil { return nil, err } if res == nil { if nilIfAbsent { return nil, nil } else { def := fd.GetDefaultValue() if def != nil { return def, nil } // GetDefaultValue only returns nil for message types md := fd.GetMessageType() if m.md.IsProto3() { return nilMessage(md), nil } else { // for proto2, return default instance of message return m.mf.NewMessage(md), nil } } } } rt := reflect.TypeOf(res) if rt.Kind() == reflect.Map { // make defensive copies to prevent caller from storing illegal keys and values m := res.(map[interface{}]interface{}) res := map[interface{}]interface{}{} for k, v := range m { res[k] = v } return res, nil } else if rt.Kind() == reflect.Slice && rt != typeOfBytes { // make defensive copies to prevent caller from storing illegal elements sl := res.([]interface{}) res := make([]interface{}, len(sl)) copy(res, sl) return res, nil } return res, nil } func nilMessage(md *desc.MessageDescriptor) interface{} { // try to return a proper nil pointer msgType := proto.MessageType(md.GetFullyQualifiedName()) if msgType != nil && msgType.Implements(typeOfProtoMessage) { return reflect.Zero(msgType).Interface().(proto.Message) } // fallback to nil dynamic message pointer return (*Message)(nil) } // 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 (m *Message) HasField(fd *desc.FieldDescriptor) bool { if err := m.checkField(fd); err != nil { return false } return m.HasFieldNumber(int(fd.GetNumber())) } // 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 (m *Message) HasFieldName(name string) bool { fd := m.FindFieldDescriptorByName(name) if fd == nil { return false } return m.HasFieldNumber(int(fd.GetNumber())) } // 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 (m *Message) HasFieldNumber(tagNumber int) bool { if _, ok := m.values[int32(tagNumber)]; ok { return true } _, ok := m.unknownFields[int32(tagNumber)] return ok } // SetField sets the value for the given field descriptor to the given value. It // panics if an error is encountered. See TrySetField. func (m *Message) SetField(fd *desc.FieldDescriptor, val interface{}) { if err := m.TrySetField(fd, val); err != nil { panic(err.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` 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 (m *Message) TrySetField(fd *desc.FieldDescriptor, val interface{}) error { if err := m.checkField(fd); err != nil { return err } return m.setField(fd, val) } // 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 (m *Message) SetFieldByName(name string, val interface{}) { if err := m.TrySetFieldByName(name, val); err != nil { panic(err.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 (m *Message) TrySetFieldByName(name string, val interface{}) error { fd := m.FindFieldDescriptorByName(name) if fd == nil { return UnknownFieldNameError } return m.setField(fd, val) } // 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 (m *Message) SetFieldByNumber(tagNumber int, val interface{}) { if err := m.TrySetFieldByNumber(tagNumber, val); err != nil { panic(err.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 (m *Message) TrySetFieldByNumber(tagNumber int, val interface{}) error { fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return UnknownTagNumberError } return m.setField(fd, val) } func (m *Message) setField(fd *desc.FieldDescriptor, val interface{}) error { var err error if val, err = validFieldValue(fd, val); err != nil { return err } m.internalSetField(fd, val) return nil } func (m *Message) internalSetField(fd *desc.FieldDescriptor, val interface{}) { if fd.IsRepeated() { // Unset fields and zero-length fields are indistinguishable, in both // proto2 and proto3 syntax if reflect.ValueOf(val).Len() == 0 { if m.values != nil { delete(m.values, fd.GetNumber()) } return } } else if m.md.IsProto3() && fd.GetOneOf() == nil { // proto3 considers fields that are set to their zero value as unset // (we already handled repeated fields above) var equal bool if b, ok := val.([]byte); ok { // can't compare slices, so we have to special-case []byte values equal = ok && bytes.Equal(b, fd.GetDefaultValue().([]byte)) } else { defVal := fd.GetDefaultValue() equal = defVal == val if !equal && defVal == nil { // above just checks if value is the nil interface, // but we should also test if the given value is a // nil pointer rv := reflect.ValueOf(val) if rv.Kind() == reflect.Ptr && rv.IsNil() { equal = true } } } if equal { if m.values != nil { delete(m.values, fd.GetNumber()) } return } } if m.values == nil { m.values = map[int32]interface{}{} } m.values[fd.GetNumber()] = val // if this field is part of a one-of, make sure all other one-of choices are cleared od := fd.GetOneOf() if od != nil { for _, other := range od.GetChoices() { if other.GetNumber() != fd.GetNumber() { delete(m.values, other.GetNumber()) } } } // also clear any unknown fields if m.unknownFields != nil { delete(m.unknownFields, fd.GetNumber()) } // and add this field if it was previously unknown if existing := m.FindFieldDescriptor(fd.GetNumber()); existing == nil { m.addField(fd) } } func (m *Message) addField(fd *desc.FieldDescriptor) { if m.extraFields == nil { m.extraFields = map[int32]*desc.FieldDescriptor{} } m.extraFields[fd.GetNumber()] = fd } // ClearField removes any value for the given field. It panics if an error is // encountered. See TryClearField. func (m *Message) ClearField(fd *desc.FieldDescriptor) { if err := m.TryClearField(fd); err != nil { panic(err.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 (m *Message) TryClearField(fd *desc.FieldDescriptor) error { if err := m.checkField(fd); err != nil { return err } m.clearField(fd) return nil } // ClearFieldByName removes any value for the field with the given name. It // panics if an error is encountered. See TryClearFieldByName. func (m *Message) ClearFieldByName(name string) { if err := m.TryClearFieldByName(name); err != nil { panic(err.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 (m *Message) TryClearFieldByName(name string) error { fd := m.FindFieldDescriptorByName(name) if fd == nil { return UnknownFieldNameError } m.clearField(fd) return nil } // ClearFieldByNumber removes any value for the field with the given tag number. // It panics if an error is encountered. See TryClearFieldByNumber. func (m *Message) ClearFieldByNumber(tagNumber int) { if err := m.TryClearFieldByNumber(tagNumber); err != nil { panic(err.Error()) } } // TryClearFieldByNumber removes any value for the field with the given tag // number. An error is returned if the given tag is unknown. func (m *Message) TryClearFieldByNumber(tagNumber int) error { fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return UnknownTagNumberError } m.clearField(fd) return nil } func (m *Message) clearField(fd *desc.FieldDescriptor) { // clear value if m.values != nil { delete(m.values, fd.GetNumber()) } // also clear any unknown fields if m.unknownFields != nil { delete(m.unknownFields, fd.GetNumber()) } // and add this field if it was previously unknown if existing := m.FindFieldDescriptor(fd.GetNumber()); existing == nil { m.addField(fd) } } // 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 (m *Message) GetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{}) { if fd, val, err := m.TryGetOneOfField(od); err != nil { panic(err.Error()) } else { return fd, val } } // 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 (m *Message) TryGetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{}, error) { if od.GetOwner().GetFullyQualifiedName() != m.md.GetFullyQualifiedName() { return nil, nil, fmt.Errorf("given one-of, %s, is for wrong message type: %s; expecting %s", od.GetName(), od.GetOwner().GetFullyQualifiedName(), m.md.GetFullyQualifiedName()) } for _, fd := range od.GetChoices() { val, err := m.doGetField(fd, true) if err != nil { return nil, nil, err } if val != nil { return fd, val, nil } } return nil, nil, nil } // ClearOneOfField removes any value for any of the given one-of's fields. It // panics if an error is encountered. See TryClearOneOfField. func (m *Message) ClearOneOfField(od *desc.OneOfDescriptor) { if err := m.TryClearOneOfField(od); err != nil { panic(err.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 (m *Message) TryClearOneOfField(od *desc.OneOfDescriptor) error { if od.GetOwner().GetFullyQualifiedName() != m.md.GetFullyQualifiedName() { return fmt.Errorf("given one-of, %s, is for wrong message type: %s; expecting %s", od.GetName(), od.GetOwner().GetFullyQualifiedName(), m.md.GetFullyQualifiedName()) } for _, fd := range od.GetChoices() { m.clearField(fd) } return nil } // GetMapField returns the value for the given map field descriptor and given // key. It panics if an error is encountered. See TryGetMapField. func (m *Message) GetMapField(fd *desc.FieldDescriptor, key interface{}) interface{} { if v, err := m.TryGetMapField(fd, key); err != nil { panic(err.Error()) } else { return v } } // 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 (m *Message) TryGetMapField(fd *desc.FieldDescriptor, key interface{}) (interface{}, error) { if err := m.checkField(fd); err != nil { return nil, err } return m.getMapField(fd, key) } // 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 (m *Message) GetMapFieldByName(name string, key interface{}) interface{} { if v, err := m.TryGetMapFieldByName(name, key); err != nil { panic(err.Error()) } else { return v } } // 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 (m *Message) TryGetMapFieldByName(name string, key interface{}) (interface{}, error) { fd := m.FindFieldDescriptorByName(name) if fd == nil { return nil, UnknownFieldNameError } return m.getMapField(fd, key) } // 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 (m *Message) GetMapFieldByNumber(tagNumber int, key interface{}) interface{} { if v, err := m.TryGetMapFieldByNumber(tagNumber, key); err != nil { panic(err.Error()) } else { return v } } // 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 (m *Message) TryGetMapFieldByNumber(tagNumber int, key interface{}) (interface{}, error) { fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return nil, UnknownTagNumberError } return m.getMapField(fd, key) } func (m *Message) getMapField(fd *desc.FieldDescriptor, key interface{}) (interface{}, error) { if !fd.IsMap() { return nil, FieldIsNotMapError } kfd := fd.GetMessageType().GetFields()[0] ki, err := validElementFieldValue(kfd, key, false) if err != nil { return nil, err } mp := m.values[fd.GetNumber()] if mp == nil { if mp, err = m.parseUnknownField(fd); err != nil { return nil, err } else if mp == nil { return nil, nil } } return mp.(map[interface{}]interface{})[ki], nil } // 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 (m *Message) ForEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) { if err := m.TryForEachMapFieldEntry(fd, fn); err != nil { panic(err.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 (m *Message) TryForEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) error { if err := m.checkField(fd); err != nil { return err } return m.forEachMapFieldEntry(fd, fn) } // 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 (m *Message) ForEachMapFieldEntryByName(name string, fn func(key, val interface{}) bool) { if err := m.TryForEachMapFieldEntryByName(name, fn); err != nil { panic(err.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 (m *Message) TryForEachMapFieldEntryByName(name string, fn func(key, val interface{}) bool) error { fd := m.FindFieldDescriptorByName(name) if fd == nil { return UnknownFieldNameError } return m.forEachMapFieldEntry(fd, fn) } // 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 (m *Message) ForEachMapFieldEntryByNumber(tagNumber int, fn func(key, val interface{}) bool) { if err := m.TryForEachMapFieldEntryByNumber(tagNumber, fn); err != nil { panic(err.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 (m *Message) TryForEachMapFieldEntryByNumber(tagNumber int, fn func(key, val interface{}) bool) error { fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return UnknownTagNumberError } return m.forEachMapFieldEntry(fd, fn) } func (m *Message) forEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) error { if !fd.IsMap() { return FieldIsNotMapError } mp := m.values[fd.GetNumber()] if mp == nil { if mp, err := m.parseUnknownField(fd); err != nil { return err } else if mp == nil { return nil } } for k, v := range mp.(map[interface{}]interface{}) { if !fn(k, v) { break } } return nil } // 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 (m *Message) PutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) { if err := m.TryPutMapField(fd, key, val); err != nil { panic(err.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 (m *Message) TryPutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) error { if err := m.checkField(fd); err != nil { return err } return m.putMapField(fd, key, val) } // 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 (m *Message) PutMapFieldByName(name string, key interface{}, val interface{}) { if err := m.TryPutMapFieldByName(name, key, val); err != nil { panic(err.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 (m *Message) TryPutMapFieldByName(name string, key interface{}, val interface{}) error { fd := m.FindFieldDescriptorByName(name) if fd == nil { return UnknownFieldNameError } return m.putMapField(fd, key, val) } // 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 (m *Message) PutMapFieldByNumber(tagNumber int, key interface{}, val interface{}) { if err := m.TryPutMapFieldByNumber(tagNumber, key, val); err != nil { panic(err.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 (m *Message) TryPutMapFieldByNumber(tagNumber int, key interface{}, val interface{}) error { fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return UnknownTagNumberError } return m.putMapField(fd, key, val) } func (m *Message) putMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) error { if !fd.IsMap() { return FieldIsNotMapError } kfd := fd.GetMessageType().GetFields()[0] ki, err := validElementFieldValue(kfd, key, false) if err != nil { return err } vfd := fd.GetMessageType().GetFields()[1] vi, err := validElementFieldValue(vfd, val, true) if err != nil { return err } mp := m.values[fd.GetNumber()] if mp == nil { if mp, err = m.parseUnknownField(fd); err != nil { return err } else if mp == nil { m.internalSetField(fd, map[interface{}]interface{}{ki: vi}) return nil } } mp.(map[interface{}]interface{})[ki] = vi return nil } // 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 (m *Message) RemoveMapField(fd *desc.FieldDescriptor, key interface{}) { if err := m.TryRemoveMapField(fd, key); err != nil { panic(err.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 (m *Message) TryRemoveMapField(fd *desc.FieldDescriptor, key interface{}) error { if err := m.checkField(fd); err != nil { return err } return m.removeMapField(fd, key) } // 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 (m *Message) RemoveMapFieldByName(name string, key interface{}) { if err := m.TryRemoveMapFieldByName(name, key); err != nil { panic(err.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 (m *Message) TryRemoveMapFieldByName(name string, key interface{}) error { fd := m.FindFieldDescriptorByName(name) if fd == nil { return UnknownFieldNameError } return m.removeMapField(fd, key) } // 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 (m *Message) RemoveMapFieldByNumber(tagNumber int, key interface{}) { if err := m.TryRemoveMapFieldByNumber(tagNumber, key); err != nil { panic(err.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 (m *Message) TryRemoveMapFieldByNumber(tagNumber int, key interface{}) error { fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return UnknownTagNumberError } return m.removeMapField(fd, key) } func (m *Message) removeMapField(fd *desc.FieldDescriptor, key interface{}) error { if !fd.IsMap() { return FieldIsNotMapError } kfd := fd.GetMessageType().GetFields()[0] ki, err := validElementFieldValue(kfd, key, false) if err != nil { return err } mp := m.values[fd.GetNumber()] if mp == nil { if mp, err = m.parseUnknownField(fd); err != nil { return err } else if mp == nil { return nil } } res := mp.(map[interface{}]interface{}) delete(res, ki) if len(res) == 0 { delete(m.values, fd.GetNumber()) } return nil } // FieldLength returns the number of elements in this message for the given // field descriptor. It panics if an error is encountered. See TryFieldLength. func (m *Message) FieldLength(fd *desc.FieldDescriptor) int { l, err := m.TryFieldLength(fd) if err != nil { panic(err.Error()) } return l } // 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 (m *Message) TryFieldLength(fd *desc.FieldDescriptor) (int, error) { if err := m.checkField(fd); err != nil { return 0, err } return m.fieldLength(fd) } // 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 (m *Message) FieldLengthByName(name string) int { l, err := m.TryFieldLengthByName(name) if err != nil { panic(err.Error()) } return l } // 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 (m *Message) TryFieldLengthByName(name string) (int, error) { fd := m.FindFieldDescriptorByName(name) if fd == nil { return 0, UnknownFieldNameError } return m.fieldLength(fd) } // 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 (m *Message) FieldLengthByNumber(tagNumber int32) int { l, err := m.TryFieldLengthByNumber(tagNumber) if err != nil { panic(err.Error()) } return l } // 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 (m *Message) TryFieldLengthByNumber(tagNumber int32) (int, error) { fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return 0, UnknownTagNumberError } return m.fieldLength(fd) } func (m *Message) fieldLength(fd *desc.FieldDescriptor) (int, error) { if !fd.IsRepeated() { return 0, FieldIsNotRepeatedError } val := m.values[fd.GetNumber()] if val == nil { var err error if val, err = m.parseUnknownField(fd); err != nil { return 0, err } else if val == nil { return 0, nil } } if sl, ok := val.([]interface{}); ok { return len(sl), nil } else if mp, ok := val.(map[interface{}]interface{}); ok { return len(mp), nil } return 0, nil } // GetRepeatedField returns the value for the given repeated field descriptor at // the given index. It panics if an error is encountered. See // TryGetRepeatedField. func (m *Message) GetRepeatedField(fd *desc.FieldDescriptor, index int) interface{} { if v, err := m.TryGetRepeatedField(fd, index); err != nil { panic(err.Error()) } else { return v } } // 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 (m *Message) TryGetRepeatedField(fd *desc.FieldDescriptor, index int) (interface{}, error) { if index < 0 { return nil, IndexOutOfRangeError } if err := m.checkField(fd); err != nil { return nil, err } return m.getRepeatedField(fd, index) } // 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 (m *Message) GetRepeatedFieldByName(name string, index int) interface{} { if v, err := m.TryGetRepeatedFieldByName(name, index); err != nil { panic(err.Error()) } else { return v } } // 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 (m *Message) TryGetRepeatedFieldByName(name string, index int) (interface{}, error) { if index < 0 { return nil, IndexOutOfRangeError } fd := m.FindFieldDescriptorByName(name) if fd == nil { return nil, UnknownFieldNameError } return m.getRepeatedField(fd, index) } // 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 (m *Message) GetRepeatedFieldByNumber(tagNumber int, index int) interface{} { if v, err := m.TryGetRepeatedFieldByNumber(tagNumber, index); err != nil { panic(err.Error()) } else { return v } } // 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 (m *Message) TryGetRepeatedFieldByNumber(tagNumber int, index int) (interface{}, error) { if index < 0 { return nil, IndexOutOfRangeError } fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return nil, UnknownTagNumberError } return m.getRepeatedField(fd, index) } func (m *Message) getRepeatedField(fd *desc.FieldDescriptor, index int) (interface{}, error) { if fd.IsMap() || !fd.IsRepeated() { return nil, FieldIsNotRepeatedError } sl := m.values[fd.GetNumber()] if sl == nil { var err error if sl, err = m.parseUnknownField(fd); err != nil { return nil, err } else if sl == nil { return nil, IndexOutOfRangeError } } res := sl.([]interface{}) if index >= len(res) { return nil, IndexOutOfRangeError } return res[index], nil } // AddRepeatedField appends the given value to the given repeated field. It // panics if an error is encountered. See TryAddRepeatedField. func (m *Message) AddRepeatedField(fd *desc.FieldDescriptor, val interface{}) { if err := m.TryAddRepeatedField(fd, val); err != nil { panic(err.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 (m *Message) TryAddRepeatedField(fd *desc.FieldDescriptor, val interface{}) error { if err := m.checkField(fd); err != nil { return err } return m.addRepeatedField(fd, val) } // AddRepeatedFieldByName appends the given value to the repeated field with the // given name. It panics if an error is encountered. See // TryAddRepeatedFieldByName. func (m *Message) AddRepeatedFieldByName(name string, val interface{}) { if err := m.TryAddRepeatedFieldByName(name, val); err != nil { panic(err.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 (m *Message) TryAddRepeatedFieldByName(name string, val interface{}) error { fd := m.FindFieldDescriptorByName(name) if fd == nil { return UnknownFieldNameError } return m.addRepeatedField(fd, val) } // AddRepeatedFieldByNumber appends the given value to the repeated field with // the given tag number. It panics if an error is encountered. See // TryAddRepeatedFieldByNumber. func (m *Message) AddRepeatedFieldByNumber(tagNumber int, val interface{}) { if err := m.TryAddRepeatedFieldByNumber(tagNumber, val); err != nil { panic(err.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 (m *Message) TryAddRepeatedFieldByNumber(tagNumber int, val interface{}) error { fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return UnknownTagNumberError } return m.addRepeatedField(fd, val) } func (m *Message) addRepeatedField(fd *desc.FieldDescriptor, val interface{}) error { if !fd.IsRepeated() { return FieldIsNotRepeatedError } val, err := validElementFieldValue(fd, val, false) if err != nil { return err } if fd.IsMap() { // We're lenient. Just as we allow setting a map field to a slice of entry messages, we also allow // adding entries one at a time (as if the field were a normal repeated field). msg := val.(proto.Message) dm, err := asDynamicMessage(msg, fd.GetMessageType(), m.mf) if err != nil { return err } k, err := dm.TryGetFieldByNumber(1) if err != nil { return err } v, err := dm.TryGetFieldByNumber(2) if err != nil { return err } return m.putMapField(fd, k, v) } sl := m.values[fd.GetNumber()] if sl == nil { if sl, err = m.parseUnknownField(fd); err != nil { return err } else if sl == nil { sl = []interface{}{} } } res := sl.([]interface{}) res = append(res, val) m.internalSetField(fd, res) return nil } // 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 (m *Message) SetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) { if err := m.TrySetRepeatedField(fd, index, val); err != nil { panic(err.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 (m *Message) TrySetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) error { if index < 0 { return IndexOutOfRangeError } if err := m.checkField(fd); err != nil { return err } return m.setRepeatedField(fd, index, val) } // 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 (m *Message) SetRepeatedFieldByName(name string, index int, val interface{}) { if err := m.TrySetRepeatedFieldByName(name, index, val); err != nil { panic(err.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 (m *Message) TrySetRepeatedFieldByName(name string, index int, val interface{}) error { if index < 0 { return IndexOutOfRangeError } fd := m.FindFieldDescriptorByName(name) if fd == nil { return UnknownFieldNameError } return m.setRepeatedField(fd, index, val) } // 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 (m *Message) SetRepeatedFieldByNumber(tagNumber int, index int, val interface{}) { if err := m.TrySetRepeatedFieldByNumber(tagNumber, index, val); err != nil { panic(err.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 (m *Message) TrySetRepeatedFieldByNumber(tagNumber int, index int, val interface{}) error { if index < 0 { return IndexOutOfRangeError } fd := m.FindFieldDescriptor(int32(tagNumber)) if fd == nil { return UnknownTagNumberError } return m.setRepeatedField(fd, index, val) } func (m *Message) setRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) error { if fd.IsMap() || !fd.IsRepeated() { return FieldIsNotRepeatedError } val, err := validElementFieldValue(fd, val, false) if err != nil { return err } sl := m.values[fd.GetNumber()] if sl == nil { if sl, err = m.parseUnknownField(fd); err != nil { return err } else if sl == nil { return IndexOutOfRangeError } } res := sl.([]interface{}) if index >= len(res) { return IndexOutOfRangeError } res[index] = val return nil } // 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 (m *Message) GetUnknownField(tagNumber int32) []UnknownField { if u, ok := m.unknownFields[tagNumber]; ok { return u } else { return nil } } func (m *Message) parseUnknownField(fd *desc.FieldDescriptor) (interface{}, error) { unks, ok := m.unknownFields[fd.GetNumber()] if !ok { return nil, nil } var v interface{} var sl []interface{} var mp map[interface{}]interface{} if fd.IsMap() { mp = map[interface{}]interface{}{} } var err error for _, unk := range unks { var val interface{} if unk.Encoding == proto.WireBytes || unk.Encoding == proto.WireStartGroup { val, err = codec.DecodeLengthDelimitedField(fd, unk.Contents, m.mf) } else { val, err = codec.DecodeScalarField(fd, unk.Value) } if err != nil { return nil, err } if fd.IsMap() { newEntry := val.(*Message) kk, err := newEntry.TryGetFieldByNumber(1) if err != nil { return nil, err } vv, err := newEntry.TryGetFieldByNumber(2) if err != nil { return nil, err } mp[kk] = vv v = mp } else if fd.IsRepeated() { t := reflect.TypeOf(val) if t.Kind() == reflect.Slice && t != typeOfBytes { // append slices if we unmarshalled a packed repeated field newVals := val.([]interface{}) sl = append(sl, newVals...) } else { sl = append(sl, val) } v = sl } else { v = val } } m.internalSetField(fd, v) return v, nil } func validFieldValue(fd *desc.FieldDescriptor, val interface{}) (interface{}, error) { return validFieldValueForRv(fd, reflect.ValueOf(val)) } func validFieldValueForRv(fd *desc.FieldDescriptor, val reflect.Value) (interface{}, error) { if fd.IsMap() && val.Kind() == reflect.Map { return validFieldValueForMapField(fd, val) } if fd.IsRepeated() { // this will also catch map fields where given value was not a map if val.Kind() != reflect.Array && val.Kind() != reflect.Slice { if fd.IsMap() { return nil, fmt.Errorf("value for map field must be a map; instead was %v", val.Type()) } else { return nil, fmt.Errorf("value for repeated field must be a slice; instead was %v", val.Type()) } } if fd.IsMap() { // value should be a slice of entry messages that we need convert into a map[interface{}]interface{} m := map[interface{}]interface{}{} for i := 0; i < val.Len(); i++ { e, err := validElementFieldValue(fd, val.Index(i).Interface(), false) if err != nil { return nil, err } msg := e.(proto.Message) dm, err := asDynamicMessage(msg, fd.GetMessageType(), nil) if err != nil { return nil, err } k, err := dm.TryGetFieldByNumber(1) if err != nil { return nil, err } v, err := dm.TryGetFieldByNumber(2) if err != nil { return nil, err } m[k] = v } return m, nil } // make a defensive copy while checking contents (also converts to []interface{}) s := make([]interface{}, val.Len()) for i := 0; i < val.Len(); i++ { ev := val.Index(i) if ev.Kind() == reflect.Interface { // unwrap it ev = reflect.ValueOf(ev.Interface()) } e, err := validElementFieldValueForRv(fd, ev, false) if err != nil { return nil, err } s[i] = e } return s, nil } return validElementFieldValueForRv(fd, val, false) } func asDynamicMessage(m proto.Message, md *desc.MessageDescriptor, mf *MessageFactory) (*Message, error) { if dm, ok := m.(*Message); ok { return dm, nil } dm := NewMessageWithMessageFactory(md, mf) if err := dm.mergeFrom(m); err != nil { return nil, err } return dm, nil } func validElementFieldValue(fd *desc.FieldDescriptor, val interface{}, allowNilMessage bool) (interface{}, error) { return validElementFieldValueForRv(fd, reflect.ValueOf(val), allowNilMessage) } func validElementFieldValueForRv(fd *desc.FieldDescriptor, val reflect.Value, allowNilMessage bool) (interface{}, error) { t := fd.GetType() if !val.IsValid() { return nil, typeError(fd, nil) } switch t { case descriptor.FieldDescriptorProto_TYPE_SFIXED32, descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_ENUM: return toInt32(reflect.Indirect(val), fd) case descriptor.FieldDescriptorProto_TYPE_SFIXED64, descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_SINT64: return toInt64(reflect.Indirect(val), fd) case descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_UINT32: return toUint32(reflect.Indirect(val), fd) case descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_UINT64: return toUint64(reflect.Indirect(val), fd) case descriptor.FieldDescriptorProto_TYPE_FLOAT: return toFloat32(reflect.Indirect(val), fd) case descriptor.FieldDescriptorProto_TYPE_DOUBLE: return toFloat64(reflect.Indirect(val), fd) case descriptor.FieldDescriptorProto_TYPE_BOOL: return toBool(reflect.Indirect(val), fd) case descriptor.FieldDescriptorProto_TYPE_BYTES: return toBytes(reflect.Indirect(val), fd) case descriptor.FieldDescriptorProto_TYPE_STRING: return toString(reflect.Indirect(val), fd) case descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_GROUP: m, err := asMessage(val, fd.GetFullyQualifiedName()) // check that message is correct type if err != nil { return nil, err } var msgType string if dm, ok := m.(*Message); ok { if allowNilMessage && dm == nil { // if dm == nil, we'll panic below, so early out if that is allowed // (only allowed for map values, to indicate an entry w/ no value) return m, nil } msgType = dm.GetMessageDescriptor().GetFullyQualifiedName() } else { msgType = proto.MessageName(m) } if msgType != fd.GetMessageType().GetFullyQualifiedName() { return nil, fmt.Errorf("message field %s requires value of type %s; received %s", fd.GetFullyQualifiedName(), fd.GetMessageType().GetFullyQualifiedName(), msgType) } return m, nil default: return nil, fmt.Errorf("unable to handle unrecognized field type: %v", fd.GetType()) } } func toInt32(v reflect.Value, fd *desc.FieldDescriptor) (int32, error) { if v.Kind() == reflect.Int32 { return int32(v.Int()), nil } return 0, typeError(fd, v.Type()) } func toUint32(v reflect.Value, fd *desc.FieldDescriptor) (uint32, error) { if v.Kind() == reflect.Uint32 { return uint32(v.Uint()), nil } return 0, typeError(fd, v.Type()) } func toFloat32(v reflect.Value, fd *desc.FieldDescriptor) (float32, error) { if v.Kind() == reflect.Float32 { return float32(v.Float()), nil } return 0, typeError(fd, v.Type()) } func toInt64(v reflect.Value, fd *desc.FieldDescriptor) (int64, error) { if v.Kind() == reflect.Int64 || v.Kind() == reflect.Int || v.Kind() == reflect.Int32 { return v.Int(), nil } return 0, typeError(fd, v.Type()) } func toUint64(v reflect.Value, fd *desc.FieldDescriptor) (uint64, error) { if v.Kind() == reflect.Uint64 || v.Kind() == reflect.Uint || v.Kind() == reflect.Uint32 { return v.Uint(), nil } return 0, typeError(fd, v.Type()) } func toFloat64(v reflect.Value, fd *desc.FieldDescriptor) (float64, error) { if v.Kind() == reflect.Float64 || v.Kind() == reflect.Float32 { return v.Float(), nil } return 0, typeError(fd, v.Type()) } func toBool(v reflect.Value, fd *desc.FieldDescriptor) (bool, error) { if v.Kind() == reflect.Bool { return v.Bool(), nil } return false, typeError(fd, v.Type()) } func toBytes(v reflect.Value, fd *desc.FieldDescriptor) ([]byte, error) { if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 { return v.Bytes(), nil } return nil, typeError(fd, v.Type()) } func toString(v reflect.Value, fd *desc.FieldDescriptor) (string, error) { if v.Kind() == reflect.String { return v.String(), nil } return "", typeError(fd, v.Type()) } func typeError(fd *desc.FieldDescriptor, t reflect.Type) error { return fmt.Errorf( "%s field %s is not compatible with value of type %v", getTypeString(fd), fd.GetFullyQualifiedName(), t) } func getTypeString(fd *desc.FieldDescriptor) string { return strings.ToLower(fd.GetType().String()) } func asMessage(v reflect.Value, fieldName string) (proto.Message, error) { t := v.Type() // we need a pointer to a struct that implements proto.Message if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct || !t.Implements(typeOfProtoMessage) { return nil, fmt.Errorf("message field %s requires is not compatible with value of type %v", fieldName, v.Type()) } return v.Interface().(proto.Message), nil } // Reset resets this message to an empty message. It removes all values set in // the message. func (m *Message) Reset() { for k := range m.values { delete(m.values, k) } for k := range m.unknownFields { delete(m.unknownFields, k) } } // String returns this message rendered in compact text format. func (m *Message) String() string { b, err := m.MarshalText() if err != nil { panic(fmt.Sprintf("Failed to create string representation of message: %s", err.Error())) } return string(b) } // ProtoMessage is present to satisfy the proto.Message interface. func (m *Message) ProtoMessage() { } // ConvertTo converts this dynamic message into the given message. This is // shorthand for resetting then merging: // target.Reset() // m.MergeInto(target) func (m *Message) ConvertTo(target proto.Message) error { if err := m.checkType(target); err != nil { return err } target.Reset() return m.mergeInto(target, defaultDeterminism) } // ConvertToDeterministic converts this dynamic message into the given message. // It is just like ConvertTo, but it attempts to produce deterministic results. // That means that if the target is a generated message (not another dynamic // message) and the current runtime is unaware of any fields or extensions that // are present in m, they will be serialized into the target's unrecognized // fields deterministically. func (m *Message) ConvertToDeterministic(target proto.Message) error { if err := m.checkType(target); err != nil { return err } target.Reset() return m.mergeInto(target, true) } // ConvertFrom converts the given message into this dynamic message. This is // shorthand for resetting then merging: // m.Reset() // m.MergeFrom(target) func (m *Message) ConvertFrom(target proto.Message) error { if err := m.checkType(target); err != nil { return err } m.Reset() return m.mergeFrom(target) } // 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 (m *Message) MergeInto(target proto.Message) error { if err := m.checkType(target); err != nil { return err } return m.mergeInto(target, defaultDeterminism) } // MergeIntoDeterministic merges this dynamic message into the given message. // It is just like MergeInto, but it attempts to produce deterministic results. // That means that if the target is a generated message (not another dynamic // message) and the current runtime is unaware of any fields or extensions that // are present in m, they will be serialized into the target's unrecognized // fields deterministically. func (m *Message) MergeIntoDeterministic(target proto.Message) error { if err := m.checkType(target); err != nil { return err } return m.mergeInto(target, true) } // 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 (m *Message) MergeFrom(source proto.Message) error { if err := m.checkType(source); err != nil { return err } return m.mergeFrom(source) } // 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 (m *Message) Merge(source proto.Message) { if m.md == nil { // To support proto.Clone, initialize the descriptor from the source. if dm, ok := source.(*Message); ok { m.md = dm.md // also make sure the clone uses the same message factory and // extensions and also knows about the same extra fields (if any) m.mf = dm.mf m.er = dm.er m.extraFields = dm.extraFields } else if md, err := desc.LoadMessageDescriptorForMessage(source); err != nil { panic(err.Error()) } else { m.md = md } } if err := m.MergeFrom(source); err != nil { panic(err.Error()) } } func (m *Message) checkType(target proto.Message) error { if dm, ok := target.(*Message); ok { if dm.md.GetFullyQualifiedName() != m.md.GetFullyQualifiedName() { return fmt.Errorf("given message has wrong type: %q; expecting %q", dm.md.GetFullyQualifiedName(), m.md.GetFullyQualifiedName()) } return nil } msgName := proto.MessageName(target) if msgName != m.md.GetFullyQualifiedName() { return fmt.Errorf("given message has wrong type: %q; expecting %q", msgName, m.md.GetFullyQualifiedName()) } return nil } func (m *Message) mergeInto(pm proto.Message, deterministic bool) error { if dm, ok := pm.(*Message); ok { return dm.mergeFrom(m) } target := reflect.ValueOf(pm) if target.Kind() == reflect.Ptr { target = target.Elem() } // track tags for which the dynamic message has data but the given // message doesn't know about it unknownTags := map[int32]struct{}{} for tag := range m.values { unknownTags[tag] = struct{}{} } // check that we can successfully do the merge structProps := proto.GetProperties(reflect.TypeOf(pm).Elem()) for _, prop := range structProps.Prop { if prop.Tag == 0 { continue // one-of or special field (such as XXX_unrecognized, etc.) } tag := int32(prop.Tag) v, ok := m.values[tag] if !ok { continue } if unknownTags != nil { delete(unknownTags, tag) } f := target.FieldByName(prop.Name) ft := f.Type() val := reflect.ValueOf(v) if !canConvert(val, ft) { return fmt.Errorf("cannot convert %v to %v", val.Type(), ft) } } // check one-of fields for _, oop := range structProps.OneofTypes { prop := oop.Prop tag := int32(prop.Tag) v, ok := m.values[tag] if !ok { continue } if unknownTags != nil { delete(unknownTags, tag) } stf, ok := oop.Type.Elem().FieldByName(prop.Name) if !ok { return fmt.Errorf("one-of field indicates struct field name %s, but type %v has no such field", prop.Name, oop.Type.Elem()) } ft := stf.Type val := reflect.ValueOf(v) if !canConvert(val, ft) { return fmt.Errorf("cannot convert %v to %v", val.Type(), ft) } } // and check extensions, too for tag, ext := range proto.RegisteredExtensions(pm) { v, ok := m.values[tag] if !ok { continue } if unknownTags != nil { delete(unknownTags, tag) } ft := reflect.TypeOf(ext.ExtensionType) val := reflect.ValueOf(v) if !canConvert(val, ft) { return fmt.Errorf("cannot convert %v to %v", val.Type(), ft) } } // now actually perform the merge for _, prop := range structProps.Prop { v, ok := m.values[int32(prop.Tag)] if !ok { continue } f := target.FieldByName(prop.Name) if err := mergeVal(reflect.ValueOf(v), f, deterministic); err != nil { return err } } // merge one-ofs for _, oop := range structProps.OneofTypes { prop := oop.Prop tag := int32(prop.Tag) v, ok := m.values[tag] if !ok { continue } oov := reflect.New(oop.Type.Elem()) f := oov.Elem().FieldByName(prop.Name) if err := mergeVal(reflect.ValueOf(v), f, deterministic); err != nil { return err } target.Field(oop.Field).Set(oov) } // merge extensions, too for tag, ext := range proto.RegisteredExtensions(pm) { v, ok := m.values[tag] if !ok { continue } e := reflect.New(reflect.TypeOf(ext.ExtensionType)).Elem() if err := mergeVal(reflect.ValueOf(v), e, deterministic); err != nil { return err } if err := proto.SetExtension(pm, ext, e.Interface()); err != nil { // shouldn't happen since we already checked that the extension type was compatible above return err } } // if we have fields that the given message doesn't know about, add to its unknown fields if len(unknownTags) > 0 { var b codec.Buffer b.SetDeterministic(deterministic) if deterministic { // if we need to emit things deterministically, sort the // extensions by their tag number sortedUnknownTags := make([]int32, 0, len(unknownTags)) for tag := range unknownTags { sortedUnknownTags = append(sortedUnknownTags, tag) } sort.Slice(sortedUnknownTags, func(i, j int) bool { return sortedUnknownTags[i] < sortedUnknownTags[j] }) for _, tag := range sortedUnknownTags { fd := m.FindFieldDescriptor(tag) if err := b.EncodeFieldValue(fd, m.values[tag]); err != nil { return err } } } else { for tag := range unknownTags { fd := m.FindFieldDescriptor(tag) if err := b.EncodeFieldValue(fd, m.values[tag]); err != nil { return err } } } internal.SetUnrecognized(pm, b.Bytes()) } // finally, convey unknown fields into the given message by letting it unmarshal them // (this will append to its unknown fields if not known; if somehow the given message recognizes // a field even though the dynamic message did not, it will get correctly unmarshalled) if unknownTags != nil && len(m.unknownFields) > 0 { var b codec.Buffer _ = m.marshalUnknownFields(&b) _ = proto.UnmarshalMerge(b.Bytes(), pm) } return nil } func canConvert(src reflect.Value, target reflect.Type) bool { if src.Kind() == reflect.Interface { src = reflect.ValueOf(src.Interface()) } srcType := src.Type() // we allow convertible types instead of requiring exact types so that calling // code can, for example, assign an enum constant to an enum field. In that case, // one type is the enum type (a sub-type of int32) and the other may be the int32 // type. So we automatically do the conversion in that case. if srcType.ConvertibleTo(target) { return true } else if target.Kind() == reflect.Ptr && srcType.ConvertibleTo(target.Elem()) { return true } else if target.Kind() == reflect.Slice { if srcType.Kind() != reflect.Slice { return false } et := target.Elem() for i := 0; i < src.Len(); i++ { if !canConvert(src.Index(i), et) { return false } } return true } else if target.Kind() == reflect.Map { if srcType.Kind() != reflect.Map { return false } return canConvertMap(src, target) } else if srcType == typeOfDynamicMessage && target.Implements(typeOfProtoMessage) { z := reflect.Zero(target).Interface() msgType := proto.MessageName(z.(proto.Message)) return msgType == src.Interface().(*Message).GetMessageDescriptor().GetFullyQualifiedName() } else { return false } } func mergeVal(src, target reflect.Value, deterministic bool) error { if src.Kind() == reflect.Interface && !src.IsNil() { src = src.Elem() } srcType := src.Type() targetType := target.Type() if srcType.ConvertibleTo(targetType) { if targetType.Implements(typeOfProtoMessage) && !target.IsNil() { Merge(target.Interface().(proto.Message), src.Convert(targetType).Interface().(proto.Message)) } else { target.Set(src.Convert(targetType)) } } else if targetType.Kind() == reflect.Ptr && srcType.ConvertibleTo(targetType.Elem()) { if !src.CanAddr() { target.Set(reflect.New(targetType.Elem())) target.Elem().Set(src.Convert(targetType.Elem())) } else { target.Set(src.Addr().Convert(targetType)) } } else if targetType.Kind() == reflect.Slice { l := target.Len() newL := l + src.Len() if target.Cap() < newL { // expand capacity of the slice and copy newSl := reflect.MakeSlice(targetType, newL, newL) for i := 0; i < target.Len(); i++ { newSl.Index(i).Set(target.Index(i)) } target.Set(newSl) } else { target.SetLen(newL) } for i := 0; i < src.Len(); i++ { dest := target.Index(l + i) if dest.Kind() == reflect.Ptr { dest.Set(reflect.New(dest.Type().Elem())) } if err := mergeVal(src.Index(i), dest, deterministic); err != nil { return err } } } else if targetType.Kind() == reflect.Map { return mergeMapVal(src, target, targetType, deterministic) } else if srcType == typeOfDynamicMessage && targetType.Implements(typeOfProtoMessage) { dm := src.Interface().(*Message) if target.IsNil() { target.Set(reflect.New(targetType.Elem())) } m := target.Interface().(proto.Message) if err := dm.mergeInto(m, deterministic); err != nil { return err } } else { return fmt.Errorf("cannot convert %v to %v", srcType, targetType) } return nil } func (m *Message) mergeFrom(pm proto.Message) error { if dm, ok := pm.(*Message); ok { // if given message is also a dynamic message, we merge differently for tag, v := range dm.values { fd := m.FindFieldDescriptor(tag) if fd == nil { fd = dm.FindFieldDescriptor(tag) } if err := mergeField(m, fd, v); err != nil { return err } } return nil } pmrv := reflect.ValueOf(pm) if pmrv.IsNil() { // nil is an empty message, so nothing to do return nil } // check that we can successfully do the merge src := pmrv.Elem() values := map[*desc.FieldDescriptor]interface{}{} props := proto.GetProperties(reflect.TypeOf(pm).Elem()) if props == nil { return fmt.Errorf("could not determine message properties to merge for %v", reflect.TypeOf(pm).Elem()) } // regular fields for _, prop := range props.Prop { if prop.Tag == 0 { continue // one-of or special field (such as XXX_unrecognized, etc.) } fd := m.FindFieldDescriptor(int32(prop.Tag)) if fd == nil { // Our descriptor has different fields than this message object. So // try to reflect on the message object's fields. md, err := desc.LoadMessageDescriptorForMessage(pm) if err != nil { return err } fd = md.FindFieldByNumber(int32(prop.Tag)) if fd == nil { return fmt.Errorf("message descriptor %q did not contain field for tag %d (%q)", md.GetFullyQualifiedName(), prop.Tag, prop.Name) } } rv := src.FieldByName(prop.Name) if (rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Slice) && rv.IsNil() { continue } if v, err := validFieldValueForRv(fd, rv); err != nil { return err } else { values[fd] = v } } // one-of fields for _, oop := range props.OneofTypes { oov := src.Field(oop.Field).Elem() if !oov.IsValid() || oov.Type() != oop.Type { // this field is unset (in other words, one-of message field is not currently set to this option) continue } prop := oop.Prop rv := oov.Elem().FieldByName(prop.Name) fd := m.FindFieldDescriptor(int32(prop.Tag)) if fd == nil { // Our descriptor has different fields than this message object. So // try to reflect on the message object's fields. md, err := desc.LoadMessageDescriptorForMessage(pm) if err != nil { return err } fd = md.FindFieldByNumber(int32(prop.Tag)) if fd == nil { return fmt.Errorf("message descriptor %q did not contain field for tag %d (%q in one-of %q)", md.GetFullyQualifiedName(), prop.Tag, prop.Name, src.Type().Field(oop.Field).Name) } } if v, err := validFieldValueForRv(fd, rv); err != nil { return err } else { values[fd] = v } } // extension fields rexts, _ := proto.ExtensionDescs(pm) for _, ed := range rexts { v, _ := proto.GetExtension(pm, ed) if v == nil { continue } if ed.ExtensionType == nil { // unrecognized extension: we'll handle that below when we // handle other unrecognized fields continue } fd := m.er.FindExtension(m.md.GetFullyQualifiedName(), ed.Field) if fd == nil { var err error if fd, err = desc.LoadFieldDescriptorForExtension(ed); err != nil { return err } } if v, err := validFieldValue(fd, v); err != nil { return err } else { values[fd] = v } } // now actually perform the merge for fd, v := range values { if err := mergeField(m, fd, v); err != nil { return err } } data := internal.GetUnrecognized(pm) if len(data) > 0 { // ignore any error returned: pulling in unknown fields is best-effort _ = m.UnmarshalMerge(data) } return nil } // Validate checks that all required fields are present. It returns an error if any are absent. func (m *Message) Validate() error { missingFields := m.findMissingFields() if len(missingFields) == 0 { return nil } return fmt.Errorf("some required fields missing: %v", strings.Join(missingFields, ", ")) } func (m *Message) findMissingFields() []string { if m.md.IsProto3() { // proto3 does not allow required fields return nil } var missingFields []string for _, fd := range m.md.GetFields() { if fd.IsRequired() { if _, ok := m.values[fd.GetNumber()]; !ok { missingFields = append(missingFields, fd.GetName()) } } } return missingFields } // 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 (m *Message) ValidateRecursive() error { return m.validateRecursive("") } func (m *Message) validateRecursive(prefix string) error { if missingFields := m.findMissingFields(); len(missingFields) > 0 { for i := range missingFields { missingFields[i] = fmt.Sprintf("%s%s", prefix, missingFields[i]) } return fmt.Errorf("some required fields missing: %v", strings.Join(missingFields, ", ")) } for tag, fld := range m.values { fd := m.FindFieldDescriptor(tag) var chprefix string var md *desc.MessageDescriptor checkMsg := func(pm proto.Message) error { var dm *Message if d, ok := pm.(*Message); ok { dm = d } else if pm != nil { dm = m.mf.NewDynamicMessage(md) if err := dm.ConvertFrom(pm); err != nil { return nil } } if dm == nil { return nil } if err := dm.validateRecursive(chprefix); err != nil { return err } return nil } isMap := fd.IsMap() if isMap && fd.GetMapValueType().GetMessageType() != nil { md = fd.GetMapValueType().GetMessageType() mp := fld.(map[interface{}]interface{}) for k, v := range mp { chprefix = fmt.Sprintf("%s%s[%v].", prefix, getName(fd), k) if err := checkMsg(v.(proto.Message)); err != nil { return err } } } else if !isMap && fd.GetMessageType() != nil { md = fd.GetMessageType() if fd.IsRepeated() { sl := fld.([]interface{}) for i, v := range sl { chprefix = fmt.Sprintf("%s%s[%d].", prefix, getName(fd), i) if err := checkMsg(v.(proto.Message)); err != nil { return err } } } else { chprefix = fmt.Sprintf("%s%s.", prefix, getName(fd)) if err := checkMsg(fld.(proto.Message)); err != nil { return err } } } } return nil } func getName(fd *desc.FieldDescriptor) string { if fd.IsExtension() { return fmt.Sprintf("(%s)", fd.GetFullyQualifiedName()) } else { return fd.GetName() } } // knownFieldTags return tags of present and recognized fields, in sorted order. func (m *Message) knownFieldTags() []int { if len(m.values) == 0 { return []int(nil) } keys := make([]int, len(m.values)) i := 0 for k := range m.values { keys[i] = int(k) i++ } sort.Ints(keys) return keys } // allKnownFieldTags return tags of present and recognized fields, including // those that are unset, in sorted order. This only includes extensions that are // present. Known but not-present extensions are not included in the returned // set of tags. func (m *Message) allKnownFieldTags() []int { fds := m.md.GetFields() keys := make([]int, 0, len(fds)+len(m.extraFields)) for k := range m.values { keys = append(keys, int(k)) } // also include known fields that are not present for _, fd := range fds { if _, ok := m.values[fd.GetNumber()]; !ok { keys = append(keys, int(fd.GetNumber())) } } for _, fd := range m.extraFields { if !fd.IsExtension() { // skip extensions that are not present if _, ok := m.values[fd.GetNumber()]; !ok { keys = append(keys, int(fd.GetNumber())) } } } sort.Ints(keys) return keys } // unknownFieldTags return tags of present but unrecognized fields, in sorted order. func (m *Message) unknownFieldTags() []int { if len(m.unknownFields) == 0 { return []int(nil) } keys := make([]int, len(m.unknownFields)) i := 0 for k := range m.unknownFields { keys[i] = int(k) i++ } sort.Ints(keys) return keys }