|  | // 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 any) 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() | 
|  | } |