123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- // Copyright 2020 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 protocmp
- import (
- "reflect"
- "sort"
- "strconv"
- "strings"
- "google.golang.org/protobuf/internal/genid"
- "google.golang.org/protobuf/proto"
- "google.golang.org/protobuf/reflect/protoreflect"
- "google.golang.org/protobuf/runtime/protoiface"
- )
- func reflectValueOf(v interface{}) protoreflect.Value {
- switch v := v.(type) {
- case Enum:
- return protoreflect.ValueOfEnum(v.Number())
- case Message:
- return protoreflect.ValueOfMessage(v.ProtoReflect())
- case []byte:
- return protoreflect.ValueOfBytes(v) // avoid overlap with reflect.Slice check below
- default:
- switch rv := reflect.ValueOf(v); {
- case rv.Kind() == reflect.Slice:
- return protoreflect.ValueOfList(reflectList{rv})
- case rv.Kind() == reflect.Map:
- return protoreflect.ValueOfMap(reflectMap{rv})
- default:
- return protoreflect.ValueOf(v)
- }
- }
- }
- type reflectMessage Message
- func (m reflectMessage) stringKey(fd protoreflect.FieldDescriptor) string {
- if m.Descriptor() != fd.ContainingMessage() {
- panic("mismatching containing message")
- }
- return fd.TextName()
- }
- func (m reflectMessage) Descriptor() protoreflect.MessageDescriptor {
- return (Message)(m).Descriptor()
- }
- func (m reflectMessage) Type() protoreflect.MessageType {
- return reflectMessageType{m.Descriptor()}
- }
- func (m reflectMessage) New() protoreflect.Message {
- return m.Type().New()
- }
- func (m reflectMessage) Interface() protoreflect.ProtoMessage {
- return Message(m)
- }
- func (m reflectMessage) Range(f func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool) {
- // Range over populated known fields.
- fds := m.Descriptor().Fields()
- for i := 0; i < fds.Len(); i++ {
- fd := fds.Get(i)
- if m.Has(fd) && !f(fd, m.Get(fd)) {
- return
- }
- }
- // Range over populated extension fields.
- for _, xd := range m[messageTypeKey].(messageMeta).xds {
- if m.Has(xd) && !f(xd, m.Get(xd)) {
- return
- }
- }
- }
- func (m reflectMessage) Has(fd protoreflect.FieldDescriptor) bool {
- _, ok := m[m.stringKey(fd)]
- return ok
- }
- func (m reflectMessage) Clear(protoreflect.FieldDescriptor) {
- panic("invalid mutation of read-only message")
- }
- func (m reflectMessage) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
- v, ok := m[m.stringKey(fd)]
- if !ok {
- switch {
- case fd.IsList():
- return protoreflect.ValueOfList(reflectList{})
- case fd.IsMap():
- return protoreflect.ValueOfMap(reflectMap{})
- case fd.Message() != nil:
- return protoreflect.ValueOfMessage(reflectMessage{
- messageTypeKey: messageMeta{md: fd.Message()},
- })
- default:
- return fd.Default()
- }
- }
- // The transformation may leave Any messages in structured form.
- // If so, convert them back to a raw-encoded form.
- if fd.FullName() == genid.Any_Value_field_fullname {
- if m, ok := v.(Message); ok {
- b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
- if err != nil {
- panic("BUG: " + err.Error())
- }
- return protoreflect.ValueOfBytes(b)
- }
- }
- return reflectValueOf(v)
- }
- func (m reflectMessage) Set(protoreflect.FieldDescriptor, protoreflect.Value) {
- panic("invalid mutation of read-only message")
- }
- func (m reflectMessage) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
- panic("invalid mutation of read-only message")
- }
- func (m reflectMessage) NewField(protoreflect.FieldDescriptor) protoreflect.Value {
- panic("not implemented")
- }
- func (m reflectMessage) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
- if m.Descriptor().Oneofs().ByName(od.Name()) != od {
- panic("oneof descriptor does not belong to this message")
- }
- fds := od.Fields()
- for i := 0; i < fds.Len(); i++ {
- fd := fds.Get(i)
- if _, ok := m[m.stringKey(fd)]; ok {
- return fd
- }
- }
- return nil
- }
- func (m reflectMessage) GetUnknown() protoreflect.RawFields {
- var nums []protoreflect.FieldNumber
- for k := range m {
- if len(strings.Trim(k, "0123456789")) == 0 {
- n, _ := strconv.ParseUint(k, 10, 32)
- nums = append(nums, protoreflect.FieldNumber(n))
- }
- }
- sort.Slice(nums, func(i, j int) bool { return nums[i] < nums[j] })
- var raw protoreflect.RawFields
- for _, num := range nums {
- b, _ := m[strconv.FormatUint(uint64(num), 10)].(protoreflect.RawFields)
- raw = append(raw, b...)
- }
- return raw
- }
- func (m reflectMessage) SetUnknown(protoreflect.RawFields) {
- panic("invalid mutation of read-only message")
- }
- func (m reflectMessage) IsValid() bool {
- invalid, _ := m[messageInvalidKey].(bool)
- return !invalid
- }
- func (m reflectMessage) ProtoMethods() *protoiface.Methods {
- return nil
- }
- type reflectMessageType struct{ protoreflect.MessageDescriptor }
- func (t reflectMessageType) New() protoreflect.Message {
- panic("not implemented")
- }
- func (t reflectMessageType) Zero() protoreflect.Message {
- panic("not implemented")
- }
- func (t reflectMessageType) Descriptor() protoreflect.MessageDescriptor {
- return t.MessageDescriptor
- }
- type reflectList struct{ v reflect.Value }
- func (ls reflectList) Len() int {
- if !ls.IsValid() {
- return 0
- }
- return ls.v.Len()
- }
- func (ls reflectList) Get(i int) protoreflect.Value {
- return reflectValueOf(ls.v.Index(i).Interface())
- }
- func (ls reflectList) Set(int, protoreflect.Value) {
- panic("invalid mutation of read-only list")
- }
- func (ls reflectList) Append(protoreflect.Value) {
- panic("invalid mutation of read-only list")
- }
- func (ls reflectList) AppendMutable() protoreflect.Value {
- panic("invalid mutation of read-only list")
- }
- func (ls reflectList) Truncate(int) {
- panic("invalid mutation of read-only list")
- }
- func (ls reflectList) NewElement() protoreflect.Value {
- panic("not implemented")
- }
- func (ls reflectList) IsValid() bool {
- return ls.v.IsValid()
- }
- type reflectMap struct{ v reflect.Value }
- func (ms reflectMap) Len() int {
- if !ms.IsValid() {
- return 0
- }
- return ms.v.Len()
- }
- func (ms reflectMap) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) {
- if !ms.IsValid() {
- return
- }
- ks := ms.v.MapKeys()
- for _, k := range ks {
- pk := reflectValueOf(k.Interface()).MapKey()
- pv := reflectValueOf(ms.v.MapIndex(k).Interface())
- if !f(pk, pv) {
- return
- }
- }
- }
- func (ms reflectMap) Has(k protoreflect.MapKey) bool {
- if !ms.IsValid() {
- return false
- }
- return ms.v.MapIndex(reflect.ValueOf(k.Interface())).IsValid()
- }
- func (ms reflectMap) Clear(protoreflect.MapKey) {
- panic("invalid mutation of read-only list")
- }
- func (ms reflectMap) Get(k protoreflect.MapKey) protoreflect.Value {
- if !ms.IsValid() {
- return protoreflect.Value{}
- }
- v := ms.v.MapIndex(reflect.ValueOf(k.Interface()))
- if !v.IsValid() {
- return protoreflect.Value{}
- }
- return reflectValueOf(v.Interface())
- }
- func (ms reflectMap) Set(protoreflect.MapKey, protoreflect.Value) {
- panic("invalid mutation of read-only list")
- }
- func (ms reflectMap) Mutable(k protoreflect.MapKey) protoreflect.Value {
- panic("invalid mutation of read-only list")
- }
- func (ms reflectMap) NewValue() protoreflect.Value {
- panic("not implemented")
- }
- func (ms reflectMap) IsValid() bool {
- return ms.v.IsValid()
- }
|