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