xref: /aosp_15_r20/external/golang-protobuf/internal/impl/codec_reflect.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
1*1c12ee1eSDan Willemsen// Copyright 2019 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 Willemsen//go:build purego || appengine
6*1c12ee1eSDan Willemsen// +build purego appengine
7*1c12ee1eSDan Willemsen
8*1c12ee1eSDan Willemsenpackage impl
9*1c12ee1eSDan Willemsen
10*1c12ee1eSDan Willemsenimport (
11*1c12ee1eSDan Willemsen	"reflect"
12*1c12ee1eSDan Willemsen
13*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/encoding/protowire"
14*1c12ee1eSDan Willemsen)
15*1c12ee1eSDan Willemsen
16*1c12ee1eSDan Willemsenfunc sizeEnum(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
17*1c12ee1eSDan Willemsen	v := p.v.Elem().Int()
18*1c12ee1eSDan Willemsen	return f.tagsize + protowire.SizeVarint(uint64(v))
19*1c12ee1eSDan Willemsen}
20*1c12ee1eSDan Willemsen
21*1c12ee1eSDan Willemsenfunc appendEnum(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
22*1c12ee1eSDan Willemsen	v := p.v.Elem().Int()
23*1c12ee1eSDan Willemsen	b = protowire.AppendVarint(b, f.wiretag)
24*1c12ee1eSDan Willemsen	b = protowire.AppendVarint(b, uint64(v))
25*1c12ee1eSDan Willemsen	return b, nil
26*1c12ee1eSDan Willemsen}
27*1c12ee1eSDan Willemsen
28*1c12ee1eSDan Willemsenfunc consumeEnum(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
29*1c12ee1eSDan Willemsen	if wtyp != protowire.VarintType {
30*1c12ee1eSDan Willemsen		return out, errUnknown
31*1c12ee1eSDan Willemsen	}
32*1c12ee1eSDan Willemsen	v, n := protowire.ConsumeVarint(b)
33*1c12ee1eSDan Willemsen	if n < 0 {
34*1c12ee1eSDan Willemsen		return out, errDecode
35*1c12ee1eSDan Willemsen	}
36*1c12ee1eSDan Willemsen	p.v.Elem().SetInt(int64(v))
37*1c12ee1eSDan Willemsen	out.n = n
38*1c12ee1eSDan Willemsen	return out, nil
39*1c12ee1eSDan Willemsen}
40*1c12ee1eSDan Willemsen
41*1c12ee1eSDan Willemsenfunc mergeEnum(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
42*1c12ee1eSDan Willemsen	dst.v.Elem().Set(src.v.Elem())
43*1c12ee1eSDan Willemsen}
44*1c12ee1eSDan Willemsen
45*1c12ee1eSDan Willemsenvar coderEnum = pointerCoderFuncs{
46*1c12ee1eSDan Willemsen	size:      sizeEnum,
47*1c12ee1eSDan Willemsen	marshal:   appendEnum,
48*1c12ee1eSDan Willemsen	unmarshal: consumeEnum,
49*1c12ee1eSDan Willemsen	merge:     mergeEnum,
50*1c12ee1eSDan Willemsen}
51*1c12ee1eSDan Willemsen
52*1c12ee1eSDan Willemsenfunc sizeEnumNoZero(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
53*1c12ee1eSDan Willemsen	if p.v.Elem().Int() == 0 {
54*1c12ee1eSDan Willemsen		return 0
55*1c12ee1eSDan Willemsen	}
56*1c12ee1eSDan Willemsen	return sizeEnum(p, f, opts)
57*1c12ee1eSDan Willemsen}
58*1c12ee1eSDan Willemsen
59*1c12ee1eSDan Willemsenfunc appendEnumNoZero(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
60*1c12ee1eSDan Willemsen	if p.v.Elem().Int() == 0 {
61*1c12ee1eSDan Willemsen		return b, nil
62*1c12ee1eSDan Willemsen	}
63*1c12ee1eSDan Willemsen	return appendEnum(b, p, f, opts)
64*1c12ee1eSDan Willemsen}
65*1c12ee1eSDan Willemsen
66*1c12ee1eSDan Willemsenfunc mergeEnumNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
67*1c12ee1eSDan Willemsen	if src.v.Elem().Int() != 0 {
68*1c12ee1eSDan Willemsen		dst.v.Elem().Set(src.v.Elem())
69*1c12ee1eSDan Willemsen	}
70*1c12ee1eSDan Willemsen}
71*1c12ee1eSDan Willemsen
72*1c12ee1eSDan Willemsenvar coderEnumNoZero = pointerCoderFuncs{
73*1c12ee1eSDan Willemsen	size:      sizeEnumNoZero,
74*1c12ee1eSDan Willemsen	marshal:   appendEnumNoZero,
75*1c12ee1eSDan Willemsen	unmarshal: consumeEnum,
76*1c12ee1eSDan Willemsen	merge:     mergeEnumNoZero,
77*1c12ee1eSDan Willemsen}
78*1c12ee1eSDan Willemsen
79*1c12ee1eSDan Willemsenfunc sizeEnumPtr(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
80*1c12ee1eSDan Willemsen	return sizeEnum(pointer{p.v.Elem()}, f, opts)
81*1c12ee1eSDan Willemsen}
82*1c12ee1eSDan Willemsen
83*1c12ee1eSDan Willemsenfunc appendEnumPtr(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
84*1c12ee1eSDan Willemsen	return appendEnum(b, pointer{p.v.Elem()}, f, opts)
85*1c12ee1eSDan Willemsen}
86*1c12ee1eSDan Willemsen
87*1c12ee1eSDan Willemsenfunc consumeEnumPtr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
88*1c12ee1eSDan Willemsen	if wtyp != protowire.VarintType {
89*1c12ee1eSDan Willemsen		return out, errUnknown
90*1c12ee1eSDan Willemsen	}
91*1c12ee1eSDan Willemsen	if p.v.Elem().IsNil() {
92*1c12ee1eSDan Willemsen		p.v.Elem().Set(reflect.New(p.v.Elem().Type().Elem()))
93*1c12ee1eSDan Willemsen	}
94*1c12ee1eSDan Willemsen	return consumeEnum(b, pointer{p.v.Elem()}, wtyp, f, opts)
95*1c12ee1eSDan Willemsen}
96*1c12ee1eSDan Willemsen
97*1c12ee1eSDan Willemsenfunc mergeEnumPtr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
98*1c12ee1eSDan Willemsen	if !src.v.Elem().IsNil() {
99*1c12ee1eSDan Willemsen		v := reflect.New(dst.v.Type().Elem().Elem())
100*1c12ee1eSDan Willemsen		v.Elem().Set(src.v.Elem().Elem())
101*1c12ee1eSDan Willemsen		dst.v.Elem().Set(v)
102*1c12ee1eSDan Willemsen	}
103*1c12ee1eSDan Willemsen}
104*1c12ee1eSDan Willemsen
105*1c12ee1eSDan Willemsenvar coderEnumPtr = pointerCoderFuncs{
106*1c12ee1eSDan Willemsen	size:      sizeEnumPtr,
107*1c12ee1eSDan Willemsen	marshal:   appendEnumPtr,
108*1c12ee1eSDan Willemsen	unmarshal: consumeEnumPtr,
109*1c12ee1eSDan Willemsen	merge:     mergeEnumPtr,
110*1c12ee1eSDan Willemsen}
111*1c12ee1eSDan Willemsen
112*1c12ee1eSDan Willemsenfunc sizeEnumSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
113*1c12ee1eSDan Willemsen	s := p.v.Elem()
114*1c12ee1eSDan Willemsen	for i, llen := 0, s.Len(); i < llen; i++ {
115*1c12ee1eSDan Willemsen		size += protowire.SizeVarint(uint64(s.Index(i).Int())) + f.tagsize
116*1c12ee1eSDan Willemsen	}
117*1c12ee1eSDan Willemsen	return size
118*1c12ee1eSDan Willemsen}
119*1c12ee1eSDan Willemsen
120*1c12ee1eSDan Willemsenfunc appendEnumSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
121*1c12ee1eSDan Willemsen	s := p.v.Elem()
122*1c12ee1eSDan Willemsen	for i, llen := 0, s.Len(); i < llen; i++ {
123*1c12ee1eSDan Willemsen		b = protowire.AppendVarint(b, f.wiretag)
124*1c12ee1eSDan Willemsen		b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
125*1c12ee1eSDan Willemsen	}
126*1c12ee1eSDan Willemsen	return b, nil
127*1c12ee1eSDan Willemsen}
128*1c12ee1eSDan Willemsen
129*1c12ee1eSDan Willemsenfunc consumeEnumSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
130*1c12ee1eSDan Willemsen	s := p.v.Elem()
131*1c12ee1eSDan Willemsen	if wtyp == protowire.BytesType {
132*1c12ee1eSDan Willemsen		b, n := protowire.ConsumeBytes(b)
133*1c12ee1eSDan Willemsen		if n < 0 {
134*1c12ee1eSDan Willemsen			return out, errDecode
135*1c12ee1eSDan Willemsen		}
136*1c12ee1eSDan Willemsen		for len(b) > 0 {
137*1c12ee1eSDan Willemsen			v, n := protowire.ConsumeVarint(b)
138*1c12ee1eSDan Willemsen			if n < 0 {
139*1c12ee1eSDan Willemsen				return out, errDecode
140*1c12ee1eSDan Willemsen			}
141*1c12ee1eSDan Willemsen			rv := reflect.New(s.Type().Elem()).Elem()
142*1c12ee1eSDan Willemsen			rv.SetInt(int64(v))
143*1c12ee1eSDan Willemsen			s.Set(reflect.Append(s, rv))
144*1c12ee1eSDan Willemsen			b = b[n:]
145*1c12ee1eSDan Willemsen		}
146*1c12ee1eSDan Willemsen		out.n = n
147*1c12ee1eSDan Willemsen		return out, nil
148*1c12ee1eSDan Willemsen	}
149*1c12ee1eSDan Willemsen	if wtyp != protowire.VarintType {
150*1c12ee1eSDan Willemsen		return out, errUnknown
151*1c12ee1eSDan Willemsen	}
152*1c12ee1eSDan Willemsen	v, n := protowire.ConsumeVarint(b)
153*1c12ee1eSDan Willemsen	if n < 0 {
154*1c12ee1eSDan Willemsen		return out, errDecode
155*1c12ee1eSDan Willemsen	}
156*1c12ee1eSDan Willemsen	rv := reflect.New(s.Type().Elem()).Elem()
157*1c12ee1eSDan Willemsen	rv.SetInt(int64(v))
158*1c12ee1eSDan Willemsen	s.Set(reflect.Append(s, rv))
159*1c12ee1eSDan Willemsen	out.n = n
160*1c12ee1eSDan Willemsen	return out, nil
161*1c12ee1eSDan Willemsen}
162*1c12ee1eSDan Willemsen
163*1c12ee1eSDan Willemsenfunc mergeEnumSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
164*1c12ee1eSDan Willemsen	dst.v.Elem().Set(reflect.AppendSlice(dst.v.Elem(), src.v.Elem()))
165*1c12ee1eSDan Willemsen}
166*1c12ee1eSDan Willemsen
167*1c12ee1eSDan Willemsenvar coderEnumSlice = pointerCoderFuncs{
168*1c12ee1eSDan Willemsen	size:      sizeEnumSlice,
169*1c12ee1eSDan Willemsen	marshal:   appendEnumSlice,
170*1c12ee1eSDan Willemsen	unmarshal: consumeEnumSlice,
171*1c12ee1eSDan Willemsen	merge:     mergeEnumSlice,
172*1c12ee1eSDan Willemsen}
173*1c12ee1eSDan Willemsen
174*1c12ee1eSDan Willemsenfunc sizeEnumPackedSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
175*1c12ee1eSDan Willemsen	s := p.v.Elem()
176*1c12ee1eSDan Willemsen	llen := s.Len()
177*1c12ee1eSDan Willemsen	if llen == 0 {
178*1c12ee1eSDan Willemsen		return 0
179*1c12ee1eSDan Willemsen	}
180*1c12ee1eSDan Willemsen	n := 0
181*1c12ee1eSDan Willemsen	for i := 0; i < llen; i++ {
182*1c12ee1eSDan Willemsen		n += protowire.SizeVarint(uint64(s.Index(i).Int()))
183*1c12ee1eSDan Willemsen	}
184*1c12ee1eSDan Willemsen	return f.tagsize + protowire.SizeBytes(n)
185*1c12ee1eSDan Willemsen}
186*1c12ee1eSDan Willemsen
187*1c12ee1eSDan Willemsenfunc appendEnumPackedSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
188*1c12ee1eSDan Willemsen	s := p.v.Elem()
189*1c12ee1eSDan Willemsen	llen := s.Len()
190*1c12ee1eSDan Willemsen	if llen == 0 {
191*1c12ee1eSDan Willemsen		return b, nil
192*1c12ee1eSDan Willemsen	}
193*1c12ee1eSDan Willemsen	b = protowire.AppendVarint(b, f.wiretag)
194*1c12ee1eSDan Willemsen	n := 0
195*1c12ee1eSDan Willemsen	for i := 0; i < llen; i++ {
196*1c12ee1eSDan Willemsen		n += protowire.SizeVarint(uint64(s.Index(i).Int()))
197*1c12ee1eSDan Willemsen	}
198*1c12ee1eSDan Willemsen	b = protowire.AppendVarint(b, uint64(n))
199*1c12ee1eSDan Willemsen	for i := 0; i < llen; i++ {
200*1c12ee1eSDan Willemsen		b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
201*1c12ee1eSDan Willemsen	}
202*1c12ee1eSDan Willemsen	return b, nil
203*1c12ee1eSDan Willemsen}
204*1c12ee1eSDan Willemsen
205*1c12ee1eSDan Willemsenvar coderEnumPackedSlice = pointerCoderFuncs{
206*1c12ee1eSDan Willemsen	size:      sizeEnumPackedSlice,
207*1c12ee1eSDan Willemsen	marshal:   appendEnumPackedSlice,
208*1c12ee1eSDan Willemsen	unmarshal: consumeEnumSlice,
209*1c12ee1eSDan Willemsen	merge:     mergeEnumSlice,
210*1c12ee1eSDan Willemsen}
211