123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- // Copyright 2019 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- // Package dynamicpb creates protocol buffer messages using runtime type information.
- package dynamicpb
- import (
- "math"
- "google.golang.org/protobuf/internal/errors"
- pref "google.golang.org/protobuf/reflect/protoreflect"
- protoimpl "google.golang.org/protobuf/runtime/protoimpl"
- )
- // A Message is a dynamically constructed protocol buffer message.
- //
- // Message implements the proto.Message interface, and may be used with all
- // standard proto package functions such as Marshal, Unmarshal, and so forth.
- //
- // Message also implements the protoreflect.Message interface. See the protoreflect
- // package documentation for that interface for how to get and set fields and
- // otherwise interact with the contents of a Message.
- //
- // Reflection API functions which construct messages, such as NewField,
- // return new dynamic messages of the appropriate type. Functions which take
- // messages, such as Set for a message-value field, will accept any message
- // with a compatible type.
- //
- // Operations which modify a Message are not safe for concurrent use.
- type Message struct {
- typ messageType
- known map[pref.FieldNumber]pref.Value
- ext map[pref.FieldNumber]pref.FieldDescriptor
- unknown pref.RawFields
- }
- // NewMessage creates a new message with the provided descriptor.
- func NewMessage(desc pref.MessageDescriptor) *Message {
- return &Message{
- typ: messageType{desc},
- known: make(map[pref.FieldNumber]pref.Value),
- ext: make(map[pref.FieldNumber]pref.FieldDescriptor),
- }
- }
- // ProtoReflect implements the protoreflect.ProtoMessage interface.
- func (m *Message) ProtoReflect() pref.Message {
- return m
- }
- // String returns a string representation of a message.
- func (m *Message) String() string {
- return protoimpl.X.MessageStringOf(m)
- }
- // Descriptor returns the message descriptor.
- func (m *Message) Descriptor() pref.MessageDescriptor {
- return m.typ.desc
- }
- // Type returns the message type.
- func (m *Message) Type() pref.MessageType {
- return m.typ
- }
- // New returns a newly allocated empty message with the same descriptor.
- // See protoreflect.Message for details.
- func (m *Message) New() pref.Message {
- return m.Type().New()
- }
- // Interface returns the message.
- // See protoreflect.Message for details.
- func (m *Message) Interface() pref.ProtoMessage {
- return m
- }
- // Range visits every populated field in undefined order.
- // See protoreflect.Message for details.
- func (m *Message) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
- for num, v := range m.known {
- fd := m.ext[num]
- if fd == nil {
- fd = m.Descriptor().Fields().ByNumber(num)
- if !isSet(fd, v) {
- continue
- }
- }
- if !f(fd, v) {
- return
- }
- }
- }
- // Range reports whether a field is populated.
- // See protoreflect.Message for details.
- func (m *Message) Has(fd pref.FieldDescriptor) bool {
- m.checkField(fd)
- if fd.IsExtension() {
- return m.ext[fd.Number()] == fd
- }
- v, ok := m.known[fd.Number()]
- if !ok {
- return false
- }
- return isSet(fd, v)
- }
- // Clear clears a field.
- // See protoreflect.Message for details.
- func (m *Message) Clear(fd pref.FieldDescriptor) {
- m.checkField(fd)
- num := fd.Number()
- delete(m.known, num)
- delete(m.ext, num)
- }
- // Get returns the value of a field.
- // See protoreflect.Message for details.
- func (m *Message) Get(fd pref.FieldDescriptor) pref.Value {
- m.checkField(fd)
- num := fd.Number()
- if fd.IsExtension() {
- if fd != m.ext[num] {
- return fd.(pref.ExtensionTypeDescriptor).Type().Zero()
- }
- return m.known[num]
- }
- if v, ok := m.known[num]; ok {
- return v
- }
- switch {
- case fd.IsMap():
- return pref.ValueOfMap(&dynamicMap{desc: fd})
- case fd.IsList():
- return pref.ValueOfList(emptyList{desc: fd})
- case fd.Message() != nil:
- return pref.ValueOfMessage(&Message{typ: messageType{fd.Message()}})
- case fd.Kind() == pref.BytesKind:
- return pref.ValueOfBytes(append([]byte(nil), fd.Default().Bytes()...))
- default:
- return fd.Default()
- }
- }
- // Mutable returns a mutable reference to a repeated, map, or message field.
- // See protoreflect.Message for details.
- func (m *Message) Mutable(fd pref.FieldDescriptor) pref.Value {
- m.checkField(fd)
- if !fd.IsMap() && !fd.IsList() && fd.Message() == nil {
- panic(errors.New("%v: getting mutable reference to non-composite type", fd.FullName()))
- }
- if m.known == nil {
- panic(errors.New("%v: modification of read-only message", fd.FullName()))
- }
- num := fd.Number()
- if fd.IsExtension() {
- if fd != m.ext[num] {
- m.ext[num] = fd
- m.known[num] = fd.(pref.ExtensionTypeDescriptor).Type().New()
- }
- return m.known[num]
- }
- if v, ok := m.known[num]; ok {
- return v
- }
- m.clearOtherOneofFields(fd)
- m.known[num] = m.NewField(fd)
- if fd.IsExtension() {
- m.ext[num] = fd
- }
- return m.known[num]
- }
- // Set stores a value in a field.
- // See protoreflect.Message for details.
- func (m *Message) Set(fd pref.FieldDescriptor, v pref.Value) {
- m.checkField(fd)
- if m.known == nil {
- panic(errors.New("%v: modification of read-only message", fd.FullName()))
- }
- if fd.IsExtension() {
- if !fd.(pref.ExtensionTypeDescriptor).Type().IsValidValue(v) {
- panic(errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface()))
- }
- m.ext[fd.Number()] = fd
- } else {
- typecheck(fd, v)
- }
- m.clearOtherOneofFields(fd)
- m.known[fd.Number()] = v
- }
- func (m *Message) clearOtherOneofFields(fd pref.FieldDescriptor) {
- od := fd.ContainingOneof()
- if od == nil {
- return
- }
- num := fd.Number()
- for i := 0; i < od.Fields().Len(); i++ {
- if n := od.Fields().Get(i).Number(); n != num {
- delete(m.known, n)
- }
- }
- }
- // NewField returns a new value for assignable to the field of a given descriptor.
- // See protoreflect.Message for details.
- func (m *Message) NewField(fd pref.FieldDescriptor) pref.Value {
- m.checkField(fd)
- switch {
- case fd.IsExtension():
- return fd.(pref.ExtensionTypeDescriptor).Type().New()
- case fd.IsMap():
- return pref.ValueOfMap(&dynamicMap{
- desc: fd,
- mapv: make(map[interface{}]pref.Value),
- })
- case fd.IsList():
- return pref.ValueOfList(&dynamicList{desc: fd})
- case fd.Message() != nil:
- return pref.ValueOfMessage(NewMessage(fd.Message()).ProtoReflect())
- default:
- return fd.Default()
- }
- }
- // WhichOneof reports which field in a oneof is populated, returning nil if none are populated.
- // See protoreflect.Message for details.
- func (m *Message) WhichOneof(od pref.OneofDescriptor) pref.FieldDescriptor {
- for i := 0; i < od.Fields().Len(); i++ {
- fd := od.Fields().Get(i)
- if m.Has(fd) {
- return fd
- }
- }
- return nil
- }
- // GetUnknown returns the raw unknown fields.
- // See protoreflect.Message for details.
- func (m *Message) GetUnknown() pref.RawFields {
- return m.unknown
- }
- // SetUnknown sets the raw unknown fields.
- // See protoreflect.Message for details.
- func (m *Message) SetUnknown(r pref.RawFields) {
- if m.known == nil {
- panic(errors.New("%v: modification of read-only message", m.typ.desc.FullName()))
- }
- m.unknown = r
- }
- func (m *Message) checkField(fd pref.FieldDescriptor) {
- if fd.IsExtension() && fd.ContainingMessage().FullName() == m.Descriptor().FullName() {
- if _, ok := fd.(pref.ExtensionTypeDescriptor); !ok {
- panic(errors.New("%v: extension field descriptor does not implement ExtensionTypeDescriptor", fd.FullName()))
- }
- return
- }
- if fd.Parent() == m.Descriptor() {
- return
- }
- fields := m.Descriptor().Fields()
- index := fd.Index()
- if index >= fields.Len() || fields.Get(index) != fd {
- panic(errors.New("%v: field descriptor does not belong to this message", fd.FullName()))
- }
- }
- type messageType struct {
- desc pref.MessageDescriptor
- }
- // NewMessageType creates a new MessageType with the provided descriptor.
- //
- // MessageTypes created by this package are equal if their descriptors are equal.
- // That is, if md1 == md2, then NewMessageType(md1) == NewMessageType(md2).
- func NewMessageType(desc pref.MessageDescriptor) pref.MessageType {
- return messageType{desc}
- }
- func (mt messageType) New() pref.Message { return NewMessage(mt.desc) }
- func (mt messageType) Zero() pref.Message { return NewMessage(mt.desc) }
- func (mt messageType) Descriptor() pref.MessageDescriptor { return mt.desc }
- type emptyList struct {
- desc pref.FieldDescriptor
- }
- func (x emptyList) Len() int { return 0 }
- func (x emptyList) Get(n int) pref.Value { panic(errors.New("out of range")) }
- func (x emptyList) Set(n int, v pref.Value) { panic(errors.New("modification of immutable list")) }
- func (x emptyList) Append(v pref.Value) { panic(errors.New("modification of immutable list")) }
- func (x emptyList) Truncate(n int) { panic(errors.New("modification of immutable list")) }
- func (x emptyList) NewElement() pref.Value {
- return newListEntry(x.desc)
- }
- type dynamicList struct {
- desc pref.FieldDescriptor
- list []pref.Value
- }
- func (x *dynamicList) Len() int {
- return len(x.list)
- }
- func (x *dynamicList) Get(n int) pref.Value {
- return x.list[n]
- }
- func (x *dynamicList) Set(n int, v pref.Value) {
- typecheckSingular(x.desc, v)
- x.list[n] = v
- }
- func (x *dynamicList) Append(v pref.Value) {
- typecheckSingular(x.desc, v)
- x.list = append(x.list, v)
- }
- func (x *dynamicList) Truncate(n int) {
- // Zero truncated elements to avoid keeping data live.
- for i := n; i < len(x.list); i++ {
- x.list[i] = pref.Value{}
- }
- x.list = x.list[:n]
- }
- func (x *dynamicList) NewElement() pref.Value {
- return newListEntry(x.desc)
- }
- type dynamicMap struct {
- desc pref.FieldDescriptor
- mapv map[interface{}]pref.Value
- }
- func (x *dynamicMap) Get(k pref.MapKey) pref.Value { return x.mapv[k.Interface()] }
- func (x *dynamicMap) Set(k pref.MapKey, v pref.Value) {
- typecheckSingular(x.desc.MapKey(), k.Value())
- typecheckSingular(x.desc.MapValue(), v)
- x.mapv[k.Interface()] = v
- }
- func (x *dynamicMap) Has(k pref.MapKey) bool { return x.Get(k).IsValid() }
- func (x *dynamicMap) Clear(k pref.MapKey) { delete(x.mapv, k.Interface()) }
- func (x *dynamicMap) Len() int { return len(x.mapv) }
- func (x *dynamicMap) NewValue() pref.Value {
- if md := x.desc.MapValue().Message(); md != nil {
- return pref.ValueOfMessage(NewMessage(md).ProtoReflect())
- }
- return x.desc.MapValue().Default()
- }
- func (x *dynamicMap) Range(f func(pref.MapKey, pref.Value) bool) {
- for k, v := range x.mapv {
- if !f(pref.ValueOf(k).MapKey(), v) {
- return
- }
- }
- }
- func isSet(fd pref.FieldDescriptor, v pref.Value) bool {
- switch {
- case fd.IsMap():
- return v.Map().Len() > 0
- case fd.IsList():
- return v.List().Len() > 0
- case fd.ContainingOneof() != nil:
- return true
- case fd.Syntax() == pref.Proto3:
- switch fd.Kind() {
- case pref.BoolKind:
- return v.Bool()
- case pref.EnumKind:
- return v.Enum() != 0
- case pref.Int32Kind, pref.Sint32Kind, pref.Int64Kind, pref.Sint64Kind, pref.Sfixed32Kind, pref.Sfixed64Kind:
- return v.Int() != 0
- case pref.Uint32Kind, pref.Uint64Kind, pref.Fixed32Kind, pref.Fixed64Kind:
- return v.Uint() != 0
- case pref.FloatKind, pref.DoubleKind:
- return v.Float() != 0 || math.Signbit(v.Float())
- case pref.StringKind:
- return v.String() != ""
- case pref.BytesKind:
- return len(v.Bytes()) > 0
- }
- }
- return true
- }
- func typecheck(fd pref.FieldDescriptor, v pref.Value) {
- if err := typeIsValid(fd, v); err != nil {
- panic(err)
- }
- }
- func typeIsValid(fd pref.FieldDescriptor, v pref.Value) error {
- switch {
- case fd.IsMap():
- if mapv, ok := v.Interface().(*dynamicMap); !ok || mapv.desc != fd {
- return errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface())
- }
- return nil
- case fd.IsList():
- switch list := v.Interface().(type) {
- case *dynamicList:
- if list.desc == fd {
- return nil
- }
- case emptyList:
- if list.desc == fd {
- return nil
- }
- }
- return errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface())
- default:
- return singularTypeIsValid(fd, v)
- }
- }
- func typecheckSingular(fd pref.FieldDescriptor, v pref.Value) {
- if err := singularTypeIsValid(fd, v); err != nil {
- panic(err)
- }
- }
- func singularTypeIsValid(fd pref.FieldDescriptor, v pref.Value) error {
- vi := v.Interface()
- var ok bool
- switch fd.Kind() {
- case pref.BoolKind:
- _, ok = vi.(bool)
- case pref.EnumKind:
- // We could check against the valid set of enum values, but do not.
- _, ok = vi.(pref.EnumNumber)
- case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
- _, ok = vi.(int32)
- case pref.Uint32Kind, pref.Fixed32Kind:
- _, ok = vi.(uint32)
- case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
- _, ok = vi.(int64)
- case pref.Uint64Kind, pref.Fixed64Kind:
- _, ok = vi.(uint64)
- case pref.FloatKind:
- _, ok = vi.(float32)
- case pref.DoubleKind:
- _, ok = vi.(float64)
- case pref.StringKind:
- _, ok = vi.(string)
- case pref.BytesKind:
- _, ok = vi.([]byte)
- case pref.MessageKind, pref.GroupKind:
- var m pref.Message
- m, ok = vi.(pref.Message)
- if ok && m.Descriptor().FullName() != fd.Message().FullName() {
- return errors.New("%v: assigning invalid message type %v", fd.FullName(), m.Descriptor().FullName())
- }
- if dm, ok := vi.(*Message); ok && dm.known == nil {
- return errors.New("%v: assigning invalid zero-value message", fd.FullName())
- }
- }
- if !ok {
- return errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface())
- }
- return nil
- }
- func newListEntry(fd pref.FieldDescriptor) pref.Value {
- switch fd.Kind() {
- case pref.BoolKind:
- return pref.ValueOfBool(false)
- case pref.EnumKind:
- return pref.ValueOfEnum(fd.Enum().Values().Get(0).Number())
- case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
- return pref.ValueOfInt32(0)
- case pref.Uint32Kind, pref.Fixed32Kind:
- return pref.ValueOfUint32(0)
- case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
- return pref.ValueOfInt64(0)
- case pref.Uint64Kind, pref.Fixed64Kind:
- return pref.ValueOfUint64(0)
- case pref.FloatKind:
- return pref.ValueOfFloat32(0)
- case pref.DoubleKind:
- return pref.ValueOfFloat64(0)
- case pref.StringKind:
- return pref.ValueOfString("")
- case pref.BytesKind:
- return pref.ValueOfBytes(nil)
- case pref.MessageKind, pref.GroupKind:
- return pref.ValueOfMessage(NewMessage(fd.Message()).ProtoReflect())
- }
- panic(errors.New("%v: unknown kind %v", fd.FullName(), fd.Kind()))
- }
- // extensionType is a dynamic protoreflect.ExtensionType.
- type extensionType struct {
- desc extensionTypeDescriptor
- }
- // NewExtensionType creates a new ExtensionType with the provided descriptor.
- //
- // Dynamic ExtensionTypes with the same descriptor compare as equal. That is,
- // if xd1 == xd2, then NewExtensionType(xd1) == NewExtensionType(xd2).
- //
- // The InterfaceOf and ValueOf methods of the extension type are defined as:
- //
- // func (xt extensionType) ValueOf(iv interface{}) protoreflect.Value {
- // return protoreflect.ValueOf(iv)
- // }
- //
- // func (xt extensionType) InterfaceOf(v protoreflect.Value) interface{} {
- // return v.Interface()
- // }
- //
- // The Go type used by the proto.GetExtension and proto.SetExtension functions
- // is determined by these methods, and is therefore equivalent to the Go type
- // used to represent a protoreflect.Value. See the protoreflect.Value
- // documentation for more details.
- func NewExtensionType(desc pref.ExtensionDescriptor) pref.ExtensionType {
- if xt, ok := desc.(pref.ExtensionTypeDescriptor); ok {
- desc = xt.Descriptor()
- }
- return extensionType{extensionTypeDescriptor{desc}}
- }
- func (xt extensionType) New() pref.Value {
- switch {
- case xt.desc.IsMap():
- return pref.ValueOfMap(&dynamicMap{
- desc: xt.desc,
- mapv: make(map[interface{}]pref.Value),
- })
- case xt.desc.IsList():
- return pref.ValueOfList(&dynamicList{desc: xt.desc})
- case xt.desc.Message() != nil:
- return pref.ValueOfMessage(NewMessage(xt.desc.Message()))
- default:
- return xt.desc.Default()
- }
- }
- func (xt extensionType) Zero() pref.Value {
- switch {
- case xt.desc.IsMap():
- return pref.ValueOfMap(&dynamicMap{desc: xt.desc})
- case xt.desc.Cardinality() == pref.Repeated:
- return pref.ValueOfList(emptyList{desc: xt.desc})
- case xt.desc.Message() != nil:
- return pref.ValueOfMessage(&Message{typ: messageType{xt.desc.Message()}})
- default:
- return xt.desc.Default()
- }
- }
- func (xt extensionType) TypeDescriptor() pref.ExtensionTypeDescriptor {
- return xt.desc
- }
- func (xt extensionType) ValueOf(iv interface{}) pref.Value {
- v := pref.ValueOf(iv)
- typecheck(xt.desc, v)
- return v
- }
- func (xt extensionType) InterfaceOf(v pref.Value) interface{} {
- typecheck(xt.desc, v)
- return v.Interface()
- }
- func (xt extensionType) IsValidInterface(iv interface{}) bool {
- return typeIsValid(xt.desc, pref.ValueOf(iv)) == nil
- }
- func (xt extensionType) IsValidValue(v pref.Value) bool {
- return typeIsValid(xt.desc, v) == nil
- }
- type extensionTypeDescriptor struct {
- pref.ExtensionDescriptor
- }
- func (xt extensionTypeDescriptor) Type() pref.ExtensionType {
- return extensionType{xt}
- }
- func (xt extensionTypeDescriptor) Descriptor() pref.ExtensionDescriptor {
- return xt.ExtensionDescriptor
- }
|