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