1// Copyright 2020 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package protocmp 6 7import ( 8 "reflect" 9 "sort" 10 "strconv" 11 "strings" 12 13 "google.golang.org/protobuf/internal/genid" 14 "google.golang.org/protobuf/proto" 15 "google.golang.org/protobuf/reflect/protoreflect" 16 "google.golang.org/protobuf/runtime/protoiface" 17) 18 19func reflectValueOf(v interface{}) protoreflect.Value { 20 switch v := v.(type) { 21 case Enum: 22 return protoreflect.ValueOfEnum(v.Number()) 23 case Message: 24 return protoreflect.ValueOfMessage(v.ProtoReflect()) 25 case []byte: 26 return protoreflect.ValueOfBytes(v) // avoid overlap with reflect.Slice check below 27 default: 28 switch rv := reflect.ValueOf(v); { 29 case rv.Kind() == reflect.Slice: 30 return protoreflect.ValueOfList(reflectList{rv}) 31 case rv.Kind() == reflect.Map: 32 return protoreflect.ValueOfMap(reflectMap{rv}) 33 default: 34 return protoreflect.ValueOf(v) 35 } 36 } 37} 38 39type reflectMessage Message 40 41func (m reflectMessage) stringKey(fd protoreflect.FieldDescriptor) string { 42 if m.Descriptor() != fd.ContainingMessage() { 43 panic("mismatching containing message") 44 } 45 return fd.TextName() 46} 47 48func (m reflectMessage) Descriptor() protoreflect.MessageDescriptor { 49 return (Message)(m).Descriptor() 50} 51func (m reflectMessage) Type() protoreflect.MessageType { 52 return reflectMessageType{m.Descriptor()} 53} 54func (m reflectMessage) New() protoreflect.Message { 55 return m.Type().New() 56} 57func (m reflectMessage) Interface() protoreflect.ProtoMessage { 58 return Message(m) 59} 60func (m reflectMessage) Range(f func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool) { 61 // Range over populated known fields. 62 fds := m.Descriptor().Fields() 63 for i := 0; i < fds.Len(); i++ { 64 fd := fds.Get(i) 65 if m.Has(fd) && !f(fd, m.Get(fd)) { 66 return 67 } 68 } 69 70 // Range over populated extension fields. 71 for _, xd := range m[messageTypeKey].(messageMeta).xds { 72 if m.Has(xd) && !f(xd, m.Get(xd)) { 73 return 74 } 75 } 76} 77func (m reflectMessage) Has(fd protoreflect.FieldDescriptor) bool { 78 _, ok := m[m.stringKey(fd)] 79 return ok 80} 81func (m reflectMessage) Clear(protoreflect.FieldDescriptor) { 82 panic("invalid mutation of read-only message") 83} 84func (m reflectMessage) Get(fd protoreflect.FieldDescriptor) protoreflect.Value { 85 v, ok := m[m.stringKey(fd)] 86 if !ok { 87 switch { 88 case fd.IsList(): 89 return protoreflect.ValueOfList(reflectList{}) 90 case fd.IsMap(): 91 return protoreflect.ValueOfMap(reflectMap{}) 92 case fd.Message() != nil: 93 return protoreflect.ValueOfMessage(reflectMessage{ 94 messageTypeKey: messageMeta{md: fd.Message()}, 95 }) 96 default: 97 return fd.Default() 98 } 99 } 100 101 // The transformation may leave Any messages in structured form. 102 // If so, convert them back to a raw-encoded form. 103 if fd.FullName() == genid.Any_Value_field_fullname { 104 if m, ok := v.(Message); ok { 105 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 106 if err != nil { 107 panic("BUG: " + err.Error()) 108 } 109 return protoreflect.ValueOfBytes(b) 110 } 111 } 112 113 return reflectValueOf(v) 114} 115func (m reflectMessage) Set(protoreflect.FieldDescriptor, protoreflect.Value) { 116 panic("invalid mutation of read-only message") 117} 118func (m reflectMessage) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { 119 panic("invalid mutation of read-only message") 120} 121func (m reflectMessage) NewField(protoreflect.FieldDescriptor) protoreflect.Value { 122 panic("not implemented") 123} 124func (m reflectMessage) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { 125 if m.Descriptor().Oneofs().ByName(od.Name()) != od { 126 panic("oneof descriptor does not belong to this message") 127 } 128 fds := od.Fields() 129 for i := 0; i < fds.Len(); i++ { 130 fd := fds.Get(i) 131 if _, ok := m[m.stringKey(fd)]; ok { 132 return fd 133 } 134 } 135 return nil 136} 137func (m reflectMessage) GetUnknown() protoreflect.RawFields { 138 var nums []protoreflect.FieldNumber 139 for k := range m { 140 if len(strings.Trim(k, "0123456789")) == 0 { 141 n, _ := strconv.ParseUint(k, 10, 32) 142 nums = append(nums, protoreflect.FieldNumber(n)) 143 } 144 } 145 sort.Slice(nums, func(i, j int) bool { return nums[i] < nums[j] }) 146 147 var raw protoreflect.RawFields 148 for _, num := range nums { 149 b, _ := m[strconv.FormatUint(uint64(num), 10)].(protoreflect.RawFields) 150 raw = append(raw, b...) 151 } 152 return raw 153} 154func (m reflectMessage) SetUnknown(protoreflect.RawFields) { 155 panic("invalid mutation of read-only message") 156} 157func (m reflectMessage) IsValid() bool { 158 invalid, _ := m[messageInvalidKey].(bool) 159 return !invalid 160} 161func (m reflectMessage) ProtoMethods() *protoiface.Methods { 162 return nil 163} 164 165type reflectMessageType struct{ protoreflect.MessageDescriptor } 166 167func (t reflectMessageType) New() protoreflect.Message { 168 panic("not implemented") 169} 170func (t reflectMessageType) Zero() protoreflect.Message { 171 panic("not implemented") 172} 173func (t reflectMessageType) Descriptor() protoreflect.MessageDescriptor { 174 return t.MessageDescriptor 175} 176 177type reflectList struct{ v reflect.Value } 178 179func (ls reflectList) Len() int { 180 if !ls.IsValid() { 181 return 0 182 } 183 return ls.v.Len() 184} 185func (ls reflectList) Get(i int) protoreflect.Value { 186 return reflectValueOf(ls.v.Index(i).Interface()) 187} 188func (ls reflectList) Set(int, protoreflect.Value) { 189 panic("invalid mutation of read-only list") 190} 191func (ls reflectList) Append(protoreflect.Value) { 192 panic("invalid mutation of read-only list") 193} 194func (ls reflectList) AppendMutable() protoreflect.Value { 195 panic("invalid mutation of read-only list") 196} 197func (ls reflectList) Truncate(int) { 198 panic("invalid mutation of read-only list") 199} 200func (ls reflectList) NewElement() protoreflect.Value { 201 panic("not implemented") 202} 203func (ls reflectList) IsValid() bool { 204 return ls.v.IsValid() 205} 206 207type reflectMap struct{ v reflect.Value } 208 209func (ms reflectMap) Len() int { 210 if !ms.IsValid() { 211 return 0 212 } 213 return ms.v.Len() 214} 215func (ms reflectMap) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { 216 if !ms.IsValid() { 217 return 218 } 219 ks := ms.v.MapKeys() 220 for _, k := range ks { 221 pk := reflectValueOf(k.Interface()).MapKey() 222 pv := reflectValueOf(ms.v.MapIndex(k).Interface()) 223 if !f(pk, pv) { 224 return 225 } 226 } 227} 228func (ms reflectMap) Has(k protoreflect.MapKey) bool { 229 if !ms.IsValid() { 230 return false 231 } 232 return ms.v.MapIndex(reflect.ValueOf(k.Interface())).IsValid() 233} 234func (ms reflectMap) Clear(protoreflect.MapKey) { 235 panic("invalid mutation of read-only list") 236} 237func (ms reflectMap) Get(k protoreflect.MapKey) protoreflect.Value { 238 if !ms.IsValid() { 239 return protoreflect.Value{} 240 } 241 v := ms.v.MapIndex(reflect.ValueOf(k.Interface())) 242 if !v.IsValid() { 243 return protoreflect.Value{} 244 } 245 return reflectValueOf(v.Interface()) 246} 247func (ms reflectMap) Set(protoreflect.MapKey, protoreflect.Value) { 248 panic("invalid mutation of read-only list") 249} 250func (ms reflectMap) Mutable(k protoreflect.MapKey) protoreflect.Value { 251 panic("invalid mutation of read-only list") 252} 253func (ms reflectMap) NewValue() protoreflect.Value { 254 panic("not implemented") 255} 256func (ms reflectMap) IsValid() bool { 257 return ms.v.IsValid() 258} 259