blob: 15124c00601e3167261afb9d5ef016275e400b96 [file] [log] [blame]
Damien Neilc37adef2019-04-01 13:49:56 -07001// 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
5package impl
6
7import (
8 "fmt"
9 "reflect"
10 "unicode/utf8"
11
12 "google.golang.org/protobuf/internal/encoding/wire"
Damien Neilc37adef2019-04-01 13:49:56 -070013 "google.golang.org/protobuf/proto"
14 pref "google.golang.org/protobuf/reflect/protoreflect"
15)
16
17type errInvalidUTF8 struct{}
18
19func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" }
20func (errInvalidUTF8) InvalidUTF8() bool { return true }
21
22func makeOneofFieldCoder(fs reflect.StructField, od pref.OneofDescriptor, structFields map[pref.FieldNumber]reflect.StructField, otypes map[pref.FieldNumber]reflect.Type) pointerCoderFuncs {
23 type oneofFieldInfo struct {
24 wiretag uint64
25 tagsize int
26 funcs pointerCoderFuncs
27 }
28
29 oneofFieldInfos := make(map[reflect.Type]oneofFieldInfo)
30 for i, fields := 0, od.Fields(); i < fields.Len(); i++ {
31 fd := fields.Get(i)
32 ot := otypes[fd.Number()]
33 wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
34 oneofFieldInfos[ot] = oneofFieldInfo{
35 wiretag: wiretag,
36 tagsize: wire.SizeVarint(wiretag),
37 funcs: fieldCoder(fd, ot.Field(0).Type),
38 }
39 }
40 ft := fs.Type
Damien Neil5322bdb2019-04-09 15:57:05 -070041 getInfo := func(p pointer) (pointer, oneofFieldInfo) {
42 v := p.AsValueOf(ft).Elem()
43 if v.IsNil() {
44 return pointer{}, oneofFieldInfo{}
45 }
46 v = v.Elem() // interface -> *struct
47 telem := v.Elem().Type()
48 info, ok := oneofFieldInfos[telem]
49 if !ok {
50 panic(fmt.Errorf("invalid oneof type %v", telem))
51 }
52 return pointerOfValue(v).Apply(zeroOffset), info
53 }
Damien Neilc37adef2019-04-01 13:49:56 -070054 return pointerCoderFuncs{
55 size: func(p pointer, _ int, opts marshalOptions) int {
Damien Neil5322bdb2019-04-09 15:57:05 -070056 v, info := getInfo(p)
57 if info.funcs.size == nil {
Damien Neilc37adef2019-04-01 13:49:56 -070058 return 0
59 }
Damien Neil5322bdb2019-04-09 15:57:05 -070060 return info.funcs.size(v, info.tagsize, opts)
Damien Neilc37adef2019-04-01 13:49:56 -070061 },
62 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Damien Neil5322bdb2019-04-09 15:57:05 -070063 v, info := getInfo(p)
64 if info.funcs.marshal == nil {
Damien Neilc37adef2019-04-01 13:49:56 -070065 return b, nil
66 }
Damien Neil5322bdb2019-04-09 15:57:05 -070067 return info.funcs.marshal(b, v, info.wiretag, opts)
68 },
69 isInit: func(p pointer) error {
70 v, info := getInfo(p)
71 if info.funcs.isInit == nil {
72 return nil
Damien Neilc37adef2019-04-01 13:49:56 -070073 }
Damien Neil5322bdb2019-04-09 15:57:05 -070074 return info.funcs.isInit(v)
Damien Neilc37adef2019-04-01 13:49:56 -070075 },
76 }
77}
78
79func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Joe Tsai4fe96632019-05-22 05:12:36 -040080 if fi, ok := getMessageInfo(ft); ok {
Damien Neilc37adef2019-04-01 13:49:56 -070081 return pointerCoderFuncs{
82 size: func(p pointer, tagsize int, opts marshalOptions) int {
Joe Tsai4fe96632019-05-22 05:12:36 -040083 return sizeMessageInfo(p, fi, tagsize, opts)
Damien Neilc37adef2019-04-01 13:49:56 -070084 },
85 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Joe Tsai4fe96632019-05-22 05:12:36 -040086 return appendMessageInfo(b, p, wiretag, fi, opts)
Damien Neilc37adef2019-04-01 13:49:56 -070087 },
Damien Neil5322bdb2019-04-09 15:57:05 -070088 isInit: func(p pointer) error {
89 return fi.isInitializedPointer(p.Elem())
90 },
Damien Neilc37adef2019-04-01 13:49:56 -070091 }
92 } else {
93 return pointerCoderFuncs{
94 size: func(p pointer, tagsize int, opts marshalOptions) int {
Damien Neil5b6d0472019-06-14 11:54:07 -070095 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neilc37adef2019-04-01 13:49:56 -070096 return sizeMessage(m, tagsize, opts)
97 },
98 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Damien Neil5b6d0472019-06-14 11:54:07 -070099 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neilc37adef2019-04-01 13:49:56 -0700100 return appendMessage(b, m, wiretag, opts)
101 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700102 isInit: func(p pointer) error {
103 m := asMessage(p.AsValueOf(ft).Elem())
104 return proto.IsInitialized(m)
105 },
Damien Neilc37adef2019-04-01 13:49:56 -0700106 }
107 }
108}
109
Joe Tsai4fe96632019-05-22 05:12:36 -0400110func sizeMessageInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
Damien Neilc37adef2019-04-01 13:49:56 -0700111 return wire.SizeBytes(mi.sizePointer(p.Elem(), opts)) + tagsize
112}
113
Joe Tsai4fe96632019-05-22 05:12:36 -0400114func appendMessageInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700115 b = wire.AppendVarint(b, wiretag)
116 b = wire.AppendVarint(b, uint64(mi.sizePointer(p.Elem(), opts)))
117 return mi.marshalAppendPointer(b, p.Elem(), opts)
118}
119
120func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
121 return wire.SizeBytes(proto.Size(m)) + tagsize
122}
123
124func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
125 b = wire.AppendVarint(b, wiretag)
126 b = wire.AppendVarint(b, uint64(proto.Size(m)))
127 return opts.Options().MarshalAppend(b, m)
128}
129
130func sizeMessageIface(ival interface{}, tagsize int, opts marshalOptions) int {
131 m := Export{}.MessageOf(ival).Interface()
132 return sizeMessage(m, tagsize, opts)
133}
134
135func appendMessageIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
136 m := Export{}.MessageOf(ival).Interface()
137 return appendMessage(b, m, wiretag, opts)
138}
139
Damien Neil5322bdb2019-04-09 15:57:05 -0700140func isInitMessageIface(ival interface{}) error {
141 m := Export{}.MessageOf(ival).Interface()
142 return proto.IsInitialized(m)
143}
144
Damien Neilc37adef2019-04-01 13:49:56 -0700145var coderMessageIface = ifaceCoderFuncs{
146 size: sizeMessageIface,
147 marshal: appendMessageIface,
Damien Neil5322bdb2019-04-09 15:57:05 -0700148 isInit: isInitMessageIface,
Damien Neilc37adef2019-04-01 13:49:56 -0700149}
150
151func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Joe Tsai4fe96632019-05-22 05:12:36 -0400152 if fi, ok := getMessageInfo(ft); ok {
Damien Neilc37adef2019-04-01 13:49:56 -0700153 return pointerCoderFuncs{
154 size: func(p pointer, tagsize int, opts marshalOptions) int {
155 return sizeGroupType(p, fi, tagsize, opts)
156 },
157 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
158 return appendGroupType(b, p, wiretag, fi, opts)
159 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700160 isInit: func(p pointer) error {
161 return fi.isInitializedPointer(p.Elem())
162 },
Damien Neilc37adef2019-04-01 13:49:56 -0700163 }
164 } else {
165 return pointerCoderFuncs{
166 size: func(p pointer, tagsize int, opts marshalOptions) int {
Damien Neil5b6d0472019-06-14 11:54:07 -0700167 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neilc37adef2019-04-01 13:49:56 -0700168 return sizeGroup(m, tagsize, opts)
169 },
170 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
Damien Neil5b6d0472019-06-14 11:54:07 -0700171 m := asMessage(p.AsValueOf(ft).Elem())
Damien Neilc37adef2019-04-01 13:49:56 -0700172 return appendGroup(b, m, wiretag, opts)
173 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700174 isInit: func(p pointer) error {
175 m := asMessage(p.AsValueOf(ft).Elem())
176 return proto.IsInitialized(m)
177 },
Damien Neilc37adef2019-04-01 13:49:56 -0700178 }
179 }
180}
181
Joe Tsai4fe96632019-05-22 05:12:36 -0400182func sizeGroupType(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
Damien Neilc37adef2019-04-01 13:49:56 -0700183 return 2*tagsize + mi.sizePointer(p.Elem(), opts)
184}
185
Joe Tsai4fe96632019-05-22 05:12:36 -0400186func appendGroupType(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700187 b = wire.AppendVarint(b, wiretag) // start group
188 b, err := mi.marshalAppendPointer(b, p.Elem(), opts)
189 b = wire.AppendVarint(b, wiretag+1) // end group
190 return b, err
191}
192
193func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
194 return 2*tagsize + proto.Size(m)
195}
196
197func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
198 b = wire.AppendVarint(b, wiretag) // start group
199 b, err := opts.Options().MarshalAppend(b, m)
200 b = wire.AppendVarint(b, wiretag+1) // end group
201 return b, err
202}
203
204func sizeGroupIface(ival interface{}, tagsize int, opts marshalOptions) int {
205 m := Export{}.MessageOf(ival).Interface()
206 return sizeGroup(m, tagsize, opts)
207}
208
209func appendGroupIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
210 m := Export{}.MessageOf(ival).Interface()
211 return appendGroup(b, m, wiretag, opts)
212}
213
214var coderGroupIface = ifaceCoderFuncs{
215 size: sizeGroupIface,
216 marshal: appendGroupIface,
Damien Neil5322bdb2019-04-09 15:57:05 -0700217 isInit: isInitMessageIface,
Damien Neilc37adef2019-04-01 13:49:56 -0700218}
219
220func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Joe Tsai4fe96632019-05-22 05:12:36 -0400221 if fi, ok := getMessageInfo(ft); ok {
Damien Neilc37adef2019-04-01 13:49:56 -0700222 return pointerCoderFuncs{
223 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
224 return appendMessageSliceInfo(b, p, wiretag, fi, opts)
225 },
226 size: func(p pointer, tagsize int, opts marshalOptions) int {
227 return sizeMessageSliceInfo(p, fi, tagsize, opts)
228 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700229 isInit: func(p pointer) error {
230 return isInitMessageSliceInfo(p, fi)
231 },
Damien Neilc37adef2019-04-01 13:49:56 -0700232 }
233 }
234 return pointerCoderFuncs{
235 size: func(p pointer, tagsize int, opts marshalOptions) int {
236 return sizeMessageSlice(p, ft, tagsize, opts)
237 },
238 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
239 return appendMessageSlice(b, p, wiretag, ft, opts)
240 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700241 isInit: func(p pointer) error {
242 return isInitMessageSlice(p, ft)
243 },
Damien Neilc37adef2019-04-01 13:49:56 -0700244 }
245}
246
Joe Tsai4fe96632019-05-22 05:12:36 -0400247func sizeMessageSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
Damien Neilc37adef2019-04-01 13:49:56 -0700248 s := p.PointerSlice()
249 n := 0
250 for _, v := range s {
251 n += wire.SizeBytes(mi.sizePointer(v, opts)) + tagsize
252 }
253 return n
254}
255
Joe Tsai4fe96632019-05-22 05:12:36 -0400256func appendMessageSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700257 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700258 var err error
259 for _, v := range s {
260 b = wire.AppendVarint(b, wiretag)
261 siz := mi.sizePointer(v, opts)
262 b = wire.AppendVarint(b, uint64(siz))
263 b, err = mi.marshalAppendPointer(b, v, opts)
Damien Neil8c86fc52019-06-19 09:28:29 -0700264 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700265 return b, err
266 }
267 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700268 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700269}
270
Damien Neil5322bdb2019-04-09 15:57:05 -0700271func isInitMessageSliceInfo(p pointer, mi *MessageInfo) error {
272 s := p.PointerSlice()
273 for _, v := range s {
274 if err := mi.isInitializedPointer(v); err != nil {
275 return err
276 }
277 }
278 return nil
279}
280
Damien Neilc37adef2019-04-01 13:49:56 -0700281func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
282 s := p.PointerSlice()
283 n := 0
284 for _, v := range s {
285 m := Export{}.MessageOf(v.AsValueOf(goType.Elem()).Interface()).Interface()
286 n += wire.SizeBytes(proto.Size(m)) + tagsize
287 }
288 return n
289}
290
291func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
292 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700293 var err error
294 for _, v := range s {
295 m := Export{}.MessageOf(v.AsValueOf(goType.Elem()).Interface()).Interface()
296 b = wire.AppendVarint(b, wiretag)
297 siz := proto.Size(m)
298 b = wire.AppendVarint(b, uint64(siz))
299 b, err = opts.Options().MarshalAppend(b, m)
Damien Neil8c86fc52019-06-19 09:28:29 -0700300 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700301 return b, err
302 }
303 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700304 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700305}
306
Damien Neil5322bdb2019-04-09 15:57:05 -0700307func isInitMessageSlice(p pointer, goType reflect.Type) error {
308 s := p.PointerSlice()
309 for _, v := range s {
310 m := Export{}.MessageOf(v.AsValueOf(goType.Elem()).Interface()).Interface()
311 if err := proto.IsInitialized(m); err != nil {
312 return err
313 }
314 }
315 return nil
316}
317
Damien Neilc37adef2019-04-01 13:49:56 -0700318// Slices of messages
319
320func sizeMessageSliceIface(ival interface{}, tagsize int, opts marshalOptions) int {
321 p := pointerOfIface(ival)
322 return sizeMessageSlice(p, reflect.TypeOf(ival).Elem().Elem(), tagsize, opts)
323}
324
325func appendMessageSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
326 p := pointerOfIface(ival)
327 return appendMessageSlice(b, p, wiretag, reflect.TypeOf(ival).Elem().Elem(), opts)
328}
329
Damien Neil5322bdb2019-04-09 15:57:05 -0700330func isInitMessageSliceIface(ival interface{}) error {
331 p := pointerOfIface(ival)
332 return isInitMessageSlice(p, reflect.TypeOf(ival).Elem().Elem())
333}
334
Damien Neilc37adef2019-04-01 13:49:56 -0700335var coderMessageSliceIface = ifaceCoderFuncs{
336 size: sizeMessageSliceIface,
337 marshal: appendMessageSliceIface,
Damien Neil5322bdb2019-04-09 15:57:05 -0700338 isInit: isInitMessageSliceIface,
Damien Neilc37adef2019-04-01 13:49:56 -0700339}
340
341func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
Joe Tsai4fe96632019-05-22 05:12:36 -0400342 if fi, ok := getMessageInfo(ft); ok {
Damien Neilc37adef2019-04-01 13:49:56 -0700343 return pointerCoderFuncs{
344 size: func(p pointer, tagsize int, opts marshalOptions) int {
345 return sizeGroupSliceInfo(p, fi, tagsize, opts)
346 },
347 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
348 return appendGroupSliceInfo(b, p, wiretag, fi, opts)
349 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700350 isInit: func(p pointer) error {
351 return isInitMessageSliceInfo(p, fi)
352 },
Damien Neilc37adef2019-04-01 13:49:56 -0700353 }
354 }
355 return pointerCoderFuncs{
356 size: func(p pointer, tagsize int, opts marshalOptions) int {
357 return sizeGroupSlice(p, ft, tagsize, opts)
358 },
359 marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
360 return appendGroupSlice(b, p, wiretag, ft, opts)
361 },
Damien Neil5322bdb2019-04-09 15:57:05 -0700362 isInit: func(p pointer) error {
363 return isInitMessageSlice(p, ft)
364 },
Damien Neilc37adef2019-04-01 13:49:56 -0700365 }
366}
367
368func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
369 s := p.PointerSlice()
370 n := 0
371 for _, v := range s {
372 m := Export{}.MessageOf(v.AsValueOf(messageType.Elem()).Interface()).Interface()
373 n += 2*tagsize + proto.Size(m)
374 }
375 return n
376}
377
378func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
379 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700380 var err error
381 for _, v := range s {
382 m := Export{}.MessageOf(v.AsValueOf(messageType.Elem()).Interface()).Interface()
383 b = wire.AppendVarint(b, wiretag) // start group
384 b, err = opts.Options().MarshalAppend(b, m)
Damien Neil8c86fc52019-06-19 09:28:29 -0700385 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700386 return b, err
387 }
388 b = wire.AppendVarint(b, wiretag+1) // end group
389 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700390 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700391}
392
Joe Tsai4fe96632019-05-22 05:12:36 -0400393func sizeGroupSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
Damien Neilc37adef2019-04-01 13:49:56 -0700394 s := p.PointerSlice()
395 n := 0
396 for _, v := range s {
397 n += 2*tagsize + mi.sizePointer(v, opts)
398 }
399 return n
400}
401
Joe Tsai4fe96632019-05-22 05:12:36 -0400402func appendGroupSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700403 s := p.PointerSlice()
Damien Neilc37adef2019-04-01 13:49:56 -0700404 var err error
405 for _, v := range s {
406 b = wire.AppendVarint(b, wiretag) // start group
407 b, err = mi.marshalAppendPointer(b, v, opts)
Damien Neil8c86fc52019-06-19 09:28:29 -0700408 if err != nil {
Damien Neilc37adef2019-04-01 13:49:56 -0700409 return b, err
410 }
411 b = wire.AppendVarint(b, wiretag+1) // end group
412 }
Damien Neil8c86fc52019-06-19 09:28:29 -0700413 return b, nil
Damien Neilc37adef2019-04-01 13:49:56 -0700414}
415
416func sizeGroupSliceIface(ival interface{}, tagsize int, opts marshalOptions) int {
417 p := pointerOfIface(ival)
418 return sizeGroupSlice(p, reflect.TypeOf(ival).Elem().Elem(), tagsize, opts)
419}
420
421func appendGroupSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
422 p := pointerOfIface(ival)
423 return appendGroupSlice(b, p, wiretag, reflect.TypeOf(ival).Elem().Elem(), opts)
424}
425
426var coderGroupSliceIface = ifaceCoderFuncs{
427 size: sizeGroupSliceIface,
428 marshal: appendGroupSliceIface,
Damien Neil5322bdb2019-04-09 15:57:05 -0700429 isInit: isInitMessageSliceIface,
Damien Neilc37adef2019-04-01 13:49:56 -0700430}
431
432// Enums
433
434func sizeEnumIface(ival interface{}, tagsize int, _ marshalOptions) (n int) {
435 v := reflect.ValueOf(ival).Int()
436 return wire.SizeVarint(uint64(v)) + tagsize
437}
438
439func appendEnumIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
440 v := reflect.ValueOf(ival).Int()
441 b = wire.AppendVarint(b, wiretag)
442 b = wire.AppendVarint(b, uint64(v))
443 return b, nil
444}
445
446var coderEnumIface = ifaceCoderFuncs{
447 size: sizeEnumIface,
448 marshal: appendEnumIface,
449}
450
451func sizeEnumSliceIface(ival interface{}, tagsize int, opts marshalOptions) (size int) {
452 return sizeEnumSliceReflect(reflect.ValueOf(ival).Elem(), tagsize, opts)
453}
454
455func sizeEnumSliceReflect(s reflect.Value, tagsize int, _ marshalOptions) (size int) {
456 for i, llen := 0, s.Len(); i < llen; i++ {
457 size += wire.SizeVarint(uint64(s.Index(i).Int())) + tagsize
458 }
459 return size
460}
461
462func appendEnumSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
463 return appendEnumSliceReflect(b, reflect.ValueOf(ival).Elem(), wiretag, opts)
464}
465
466func appendEnumSliceReflect(b []byte, s reflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
467 for i, llen := 0, s.Len(); i < llen; i++ {
468 b = wire.AppendVarint(b, wiretag)
469 b = wire.AppendVarint(b, uint64(s.Index(i).Int()))
470 }
471 return b, nil
472}
473
474var coderEnumSliceIface = ifaceCoderFuncs{
475 size: sizeEnumSliceIface,
476 marshal: appendEnumSliceIface,
477}
478
479// Strings with UTF8 validation.
480
481func appendStringValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
482 v := *p.String()
483 b = wire.AppendVarint(b, wiretag)
Damien Neilcedb5952019-06-21 12:04:07 -0700484 b = wire.AppendString(b, v)
Damien Neilc37adef2019-04-01 13:49:56 -0700485 if !utf8.ValidString(v) {
486 return b, errInvalidUTF8{}
487 }
488 return b, nil
489}
490
491var coderStringValidateUTF8 = pointerCoderFuncs{
492 size: sizeString,
493 marshal: appendStringValidateUTF8,
494}
495
496func appendStringNoZeroValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
497 v := *p.String()
498 if len(v) == 0 {
499 return b, nil
500 }
501 b = wire.AppendVarint(b, wiretag)
Damien Neilcedb5952019-06-21 12:04:07 -0700502 b = wire.AppendString(b, v)
Damien Neilc37adef2019-04-01 13:49:56 -0700503 if !utf8.ValidString(v) {
504 return b, errInvalidUTF8{}
505 }
506 return b, nil
507}
508
509var coderStringNoZeroValidateUTF8 = pointerCoderFuncs{
510 size: sizeStringNoZero,
511 marshal: appendStringNoZeroValidateUTF8,
512}
513
514func sizeStringSliceValidateUTF8(p pointer, tagsize int, _ marshalOptions) (size int) {
515 s := *p.StringSlice()
516 for _, v := range s {
Damien Neilcedb5952019-06-21 12:04:07 -0700517 size += tagsize + wire.SizeBytes(len(v))
Damien Neilc37adef2019-04-01 13:49:56 -0700518 }
519 return size
520}
521
522func appendStringSliceValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
523 s := *p.StringSlice()
524 var err error
525 for _, v := range s {
526 b = wire.AppendVarint(b, wiretag)
Damien Neilcedb5952019-06-21 12:04:07 -0700527 b = wire.AppendString(b, v)
Damien Neilc37adef2019-04-01 13:49:56 -0700528 if !utf8.ValidString(v) {
529 err = errInvalidUTF8{}
530 }
531 }
532 return b, err
533}
534
535var coderStringSliceValidateUTF8 = pointerCoderFuncs{
536 size: sizeStringSliceValidateUTF8,
537 marshal: appendStringSliceValidateUTF8,
538}
539
540func sizeStringIfaceValidateUTF8(ival interface{}, tagsize int, _ marshalOptions) int {
541 v := ival.(string)
Damien Neilcedb5952019-06-21 12:04:07 -0700542 return tagsize + wire.SizeBytes(len(v))
Damien Neilc37adef2019-04-01 13:49:56 -0700543}
544
545func appendStringIfaceValidateUTF8(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
546 v := ival.(string)
547 b = wire.AppendVarint(b, wiretag)
Damien Neilcedb5952019-06-21 12:04:07 -0700548 b = wire.AppendString(b, v)
Damien Neilc37adef2019-04-01 13:49:56 -0700549 if !utf8.ValidString(v) {
550 return b, errInvalidUTF8{}
551 }
552 return b, nil
553}
554
555var coderStringIfaceValidateUTF8 = ifaceCoderFuncs{
556 size: sizeStringIfaceValidateUTF8,
557 marshal: appendStringIfaceValidateUTF8,
558}
Damien Neil5b6d0472019-06-14 11:54:07 -0700559
560func asMessage(v reflect.Value) pref.ProtoMessage {
561 if m, ok := v.Interface().(pref.ProtoMessage); ok {
562 return m
563 }
564 return legacyWrapMessage(v)
565}