xref: /aosp_15_r20/external/golang-protobuf/testing/protocmp/reflect.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
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