1
2
3
4
5 package impl
6
7 import (
8 "fmt"
9 "reflect"
10 "sync"
11
12 "google.golang.org/protobuf/encoding/protowire"
13 "google.golang.org/protobuf/internal/errors"
14 "google.golang.org/protobuf/proto"
15 "google.golang.org/protobuf/reflect/protoreflect"
16 "google.golang.org/protobuf/reflect/protoregistry"
17 "google.golang.org/protobuf/runtime/protoiface"
18 )
19
20 type errInvalidUTF8 struct{}
21
22 func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" }
23 func (errInvalidUTF8) InvalidUTF8() bool { return true }
24 func (errInvalidUTF8) Unwrap() error { return errors.Error }
25
26
27
28
29
30
31
32
33 func (mi *MessageInfo) initOneofFieldCoders(od protoreflect.OneofDescriptor, si structInfo) {
34 fs := si.oneofsByName[od.Name()]
35 ft := fs.Type
36 oneofFields := make(map[reflect.Type]*coderFieldInfo)
37 needIsInit := false
38 fields := od.Fields()
39 for i, lim := 0, fields.Len(); i < lim; i++ {
40 fd := od.Fields().Get(i)
41 num := fd.Number()
42
43
44
45
46
47
48 cf := *mi.coderFields[num]
49 ot := si.oneofWrappersByNumber[num]
50 cf.ft = ot.Field(0).Type
51 cf.mi, cf.funcs = fieldCoder(fd, cf.ft)
52 oneofFields[ot] = &cf
53 if cf.funcs.isInit != nil {
54 needIsInit = true
55 }
56 mi.coderFields[num].funcs.unmarshal = func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
57 var vw reflect.Value
58 vi := p.AsValueOf(ft).Elem()
59 if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
60 vw = vi.Elem()
61 } else {
62 vw = reflect.New(ot)
63 }
64 out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
65 if err != nil {
66 return out, err
67 }
68 vi.Set(vw)
69 return out, nil
70 }
71 }
72 getInfo := func(p pointer) (pointer, *coderFieldInfo) {
73 v := p.AsValueOf(ft).Elem()
74 if v.IsNil() {
75 return pointer{}, nil
76 }
77 v = v.Elem()
78 if v.IsNil() {
79 return pointer{}, nil
80 }
81 return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
82 }
83 first := mi.coderFields[od.Fields().Get(0).Number()]
84 first.funcs.size = func(p pointer, _ *coderFieldInfo, opts marshalOptions) int {
85 p, info := getInfo(p)
86 if info == nil || info.funcs.size == nil {
87 return 0
88 }
89 return info.funcs.size(p, info, opts)
90 }
91 first.funcs.marshal = func(b []byte, p pointer, _ *coderFieldInfo, opts marshalOptions) ([]byte, error) {
92 p, info := getInfo(p)
93 if info == nil || info.funcs.marshal == nil {
94 return b, nil
95 }
96 return info.funcs.marshal(b, p, info, opts)
97 }
98 first.funcs.merge = func(dst, src pointer, _ *coderFieldInfo, opts mergeOptions) {
99 srcp, srcinfo := getInfo(src)
100 if srcinfo == nil || srcinfo.funcs.merge == nil {
101 return
102 }
103 dstp, dstinfo := getInfo(dst)
104 if dstinfo != srcinfo {
105 dst.AsValueOf(ft).Elem().Set(reflect.New(src.AsValueOf(ft).Elem().Elem().Elem().Type()))
106 dstp = pointerOfValue(dst.AsValueOf(ft).Elem().Elem()).Apply(zeroOffset)
107 }
108 srcinfo.funcs.merge(dstp, srcp, srcinfo, opts)
109 }
110 if needIsInit {
111 first.funcs.isInit = func(p pointer, _ *coderFieldInfo) error {
112 p, info := getInfo(p)
113 if info == nil || info.funcs.isInit == nil {
114 return nil
115 }
116 return info.funcs.isInit(p, info)
117 }
118 }
119 }
120
121 func makeWeakMessageFieldCoder(fd protoreflect.FieldDescriptor) pointerCoderFuncs {
122 var once sync.Once
123 var messageType protoreflect.MessageType
124 lazyInit := func() {
125 once.Do(func() {
126 messageName := fd.Message().FullName()
127 messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName)
128 })
129 }
130
131 return pointerCoderFuncs{
132 size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
133 m, ok := p.WeakFields().get(f.num)
134 if !ok {
135 return 0
136 }
137 lazyInit()
138 if messageType == nil {
139 panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
140 }
141 return sizeMessage(m, f.tagsize, opts)
142 },
143 marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
144 m, ok := p.WeakFields().get(f.num)
145 if !ok {
146 return b, nil
147 }
148 lazyInit()
149 if messageType == nil {
150 panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
151 }
152 return appendMessage(b, m, f.wiretag, opts)
153 },
154 unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
155 fs := p.WeakFields()
156 m, ok := fs.get(f.num)
157 if !ok {
158 lazyInit()
159 if messageType == nil {
160 return unmarshalOutput{}, errUnknown
161 }
162 m = messageType.New().Interface()
163 fs.set(f.num, m)
164 }
165 return consumeMessage(b, m, wtyp, opts)
166 },
167 isInit: func(p pointer, f *coderFieldInfo) error {
168 m, ok := p.WeakFields().get(f.num)
169 if !ok {
170 return nil
171 }
172 return proto.CheckInitialized(m)
173 },
174 merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
175 sm, ok := src.WeakFields().get(f.num)
176 if !ok {
177 return
178 }
179 dm, ok := dst.WeakFields().get(f.num)
180 if !ok {
181 lazyInit()
182 if messageType == nil {
183 panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName()))
184 }
185 dm = messageType.New().Interface()
186 dst.WeakFields().set(f.num, dm)
187 }
188 opts.Merge(dm, sm)
189 },
190 }
191 }
192
193 func makeMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
194 if mi := getMessageInfo(ft); mi != nil {
195 funcs := pointerCoderFuncs{
196 size: sizeMessageInfo,
197 marshal: appendMessageInfo,
198 unmarshal: consumeMessageInfo,
199 merge: mergeMessage,
200 }
201 if needsInitCheck(mi.Desc) {
202 funcs.isInit = isInitMessageInfo
203 }
204 return funcs
205 } else {
206 return pointerCoderFuncs{
207 size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
208 m := asMessage(p.AsValueOf(ft).Elem())
209 return sizeMessage(m, f.tagsize, opts)
210 },
211 marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
212 m := asMessage(p.AsValueOf(ft).Elem())
213 return appendMessage(b, m, f.wiretag, opts)
214 },
215 unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
216 mp := p.AsValueOf(ft).Elem()
217 if mp.IsNil() {
218 mp.Set(reflect.New(ft.Elem()))
219 }
220 return consumeMessage(b, asMessage(mp), wtyp, opts)
221 },
222 isInit: func(p pointer, f *coderFieldInfo) error {
223 m := asMessage(p.AsValueOf(ft).Elem())
224 return proto.CheckInitialized(m)
225 },
226 merge: mergeMessage,
227 }
228 }
229 }
230
231 func sizeMessageInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
232 return protowire.SizeBytes(f.mi.sizePointer(p.Elem(), opts)) + f.tagsize
233 }
234
235 func appendMessageInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
236 calculatedSize := f.mi.sizePointer(p.Elem(), opts)
237 b = protowire.AppendVarint(b, f.wiretag)
238 b = protowire.AppendVarint(b, uint64(calculatedSize))
239 before := len(b)
240 b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
241 if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil {
242 return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize)
243 }
244 return b, err
245 }
246
247 func consumeMessageInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
248 if wtyp != protowire.BytesType {
249 return out, errUnknown
250 }
251 v, n := protowire.ConsumeBytes(b)
252 if n < 0 {
253 return out, errDecode
254 }
255 if p.Elem().IsNil() {
256 p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
257 }
258 o, err := f.mi.unmarshalPointer(v, p.Elem(), 0, opts)
259 if err != nil {
260 return out, err
261 }
262 out.n = n
263 out.initialized = o.initialized
264 return out, nil
265 }
266
267 func isInitMessageInfo(p pointer, f *coderFieldInfo) error {
268 return f.mi.checkInitializedPointer(p.Elem())
269 }
270
271 func sizeMessage(m proto.Message, tagsize int, opts marshalOptions) int {
272 return protowire.SizeBytes(opts.Options().Size(m)) + tagsize
273 }
274
275 func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
276 mopts := opts.Options()
277 calculatedSize := mopts.Size(m)
278 b = protowire.AppendVarint(b, wiretag)
279 b = protowire.AppendVarint(b, uint64(calculatedSize))
280 before := len(b)
281 b, err := mopts.MarshalAppend(b, m)
282 if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil {
283 return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize)
284 }
285 return b, err
286 }
287
288 func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
289 if wtyp != protowire.BytesType {
290 return out, errUnknown
291 }
292 v, n := protowire.ConsumeBytes(b)
293 if n < 0 {
294 return out, errDecode
295 }
296 o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
297 Buf: v,
298 Message: m.ProtoReflect(),
299 })
300 if err != nil {
301 return out, err
302 }
303 out.n = n
304 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
305 return out, nil
306 }
307
308 func sizeMessageValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
309 m := v.Message().Interface()
310 return sizeMessage(m, tagsize, opts)
311 }
312
313 func appendMessageValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
314 m := v.Message().Interface()
315 return appendMessage(b, m, wiretag, opts)
316 }
317
318 func consumeMessageValue(b []byte, v protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) {
319 m := v.Message().Interface()
320 out, err := consumeMessage(b, m, wtyp, opts)
321 return v, out, err
322 }
323
324 func isInitMessageValue(v protoreflect.Value) error {
325 m := v.Message().Interface()
326 return proto.CheckInitialized(m)
327 }
328
329 var coderMessageValue = valueCoderFuncs{
330 size: sizeMessageValue,
331 marshal: appendMessageValue,
332 unmarshal: consumeMessageValue,
333 isInit: isInitMessageValue,
334 merge: mergeMessageValue,
335 }
336
337 func sizeGroupValue(v protoreflect.Value, tagsize int, opts marshalOptions) int {
338 m := v.Message().Interface()
339 return sizeGroup(m, tagsize, opts)
340 }
341
342 func appendGroupValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
343 m := v.Message().Interface()
344 return appendGroup(b, m, wiretag, opts)
345 }
346
347 func consumeGroupValue(b []byte, v protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) {
348 m := v.Message().Interface()
349 out, err := consumeGroup(b, m, num, wtyp, opts)
350 return v, out, err
351 }
352
353 var coderGroupValue = valueCoderFuncs{
354 size: sizeGroupValue,
355 marshal: appendGroupValue,
356 unmarshal: consumeGroupValue,
357 isInit: isInitMessageValue,
358 merge: mergeMessageValue,
359 }
360
361 func makeGroupFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
362 num := fd.Number()
363 if mi := getMessageInfo(ft); mi != nil {
364 funcs := pointerCoderFuncs{
365 size: sizeGroupType,
366 marshal: appendGroupType,
367 unmarshal: consumeGroupType,
368 merge: mergeMessage,
369 }
370 if needsInitCheck(mi.Desc) {
371 funcs.isInit = isInitMessageInfo
372 }
373 return funcs
374 } else {
375 return pointerCoderFuncs{
376 size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
377 m := asMessage(p.AsValueOf(ft).Elem())
378 return sizeGroup(m, f.tagsize, opts)
379 },
380 marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
381 m := asMessage(p.AsValueOf(ft).Elem())
382 return appendGroup(b, m, f.wiretag, opts)
383 },
384 unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
385 mp := p.AsValueOf(ft).Elem()
386 if mp.IsNil() {
387 mp.Set(reflect.New(ft.Elem()))
388 }
389 return consumeGroup(b, asMessage(mp), num, wtyp, opts)
390 },
391 isInit: func(p pointer, f *coderFieldInfo) error {
392 m := asMessage(p.AsValueOf(ft).Elem())
393 return proto.CheckInitialized(m)
394 },
395 merge: mergeMessage,
396 }
397 }
398 }
399
400 func sizeGroupType(p pointer, f *coderFieldInfo, opts marshalOptions) int {
401 return 2*f.tagsize + f.mi.sizePointer(p.Elem(), opts)
402 }
403
404 func appendGroupType(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
405 b = protowire.AppendVarint(b, f.wiretag)
406 b, err := f.mi.marshalAppendPointer(b, p.Elem(), opts)
407 b = protowire.AppendVarint(b, f.wiretag+1)
408 return b, err
409 }
410
411 func consumeGroupType(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
412 if wtyp != protowire.StartGroupType {
413 return out, errUnknown
414 }
415 if p.Elem().IsNil() {
416 p.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
417 }
418 return f.mi.unmarshalPointer(b, p.Elem(), f.num, opts)
419 }
420
421 func sizeGroup(m proto.Message, tagsize int, opts marshalOptions) int {
422 return 2*tagsize + opts.Options().Size(m)
423 }
424
425 func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
426 b = protowire.AppendVarint(b, wiretag)
427 b, err := opts.Options().MarshalAppend(b, m)
428 b = protowire.AppendVarint(b, wiretag+1)
429 return b, err
430 }
431
432 func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
433 if wtyp != protowire.StartGroupType {
434 return out, errUnknown
435 }
436 b, n := protowire.ConsumeGroup(num, b)
437 if n < 0 {
438 return out, errDecode
439 }
440 o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
441 Buf: b,
442 Message: m.ProtoReflect(),
443 })
444 if err != nil {
445 return out, err
446 }
447 out.n = n
448 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
449 return out, nil
450 }
451
452 func makeMessageSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
453 if mi := getMessageInfo(ft); mi != nil {
454 funcs := pointerCoderFuncs{
455 size: sizeMessageSliceInfo,
456 marshal: appendMessageSliceInfo,
457 unmarshal: consumeMessageSliceInfo,
458 merge: mergeMessageSlice,
459 }
460 if needsInitCheck(mi.Desc) {
461 funcs.isInit = isInitMessageSliceInfo
462 }
463 return funcs
464 }
465 return pointerCoderFuncs{
466 size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
467 return sizeMessageSlice(p, ft, f.tagsize, opts)
468 },
469 marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
470 return appendMessageSlice(b, p, f.wiretag, ft, opts)
471 },
472 unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
473 return consumeMessageSlice(b, p, ft, wtyp, opts)
474 },
475 isInit: func(p pointer, f *coderFieldInfo) error {
476 return isInitMessageSlice(p, ft)
477 },
478 merge: mergeMessageSlice,
479 }
480 }
481
482 func sizeMessageSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
483 s := p.PointerSlice()
484 n := 0
485 for _, v := range s {
486 n += protowire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize
487 }
488 return n
489 }
490
491 func appendMessageSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
492 s := p.PointerSlice()
493 var err error
494 for _, v := range s {
495 b = protowire.AppendVarint(b, f.wiretag)
496 siz := f.mi.sizePointer(v, opts)
497 b = protowire.AppendVarint(b, uint64(siz))
498 before := len(b)
499 b, err = f.mi.marshalAppendPointer(b, v, opts)
500 if err != nil {
501 return b, err
502 }
503 if measuredSize := len(b) - before; siz != measuredSize {
504 return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
505 }
506 }
507 return b, nil
508 }
509
510 func consumeMessageSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
511 if wtyp != protowire.BytesType {
512 return out, errUnknown
513 }
514 v, n := protowire.ConsumeBytes(b)
515 if n < 0 {
516 return out, errDecode
517 }
518 m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
519 mp := pointerOfIface(m)
520 o, err := f.mi.unmarshalPointer(v, mp, 0, opts)
521 if err != nil {
522 return out, err
523 }
524 p.AppendPointerSlice(mp)
525 out.n = n
526 out.initialized = o.initialized
527 return out, nil
528 }
529
530 func isInitMessageSliceInfo(p pointer, f *coderFieldInfo) error {
531 s := p.PointerSlice()
532 for _, v := range s {
533 if err := f.mi.checkInitializedPointer(v); err != nil {
534 return err
535 }
536 }
537 return nil
538 }
539
540 func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, opts marshalOptions) int {
541 mopts := opts.Options()
542 s := p.PointerSlice()
543 n := 0
544 for _, v := range s {
545 m := asMessage(v.AsValueOf(goType.Elem()))
546 n += protowire.SizeBytes(mopts.Size(m)) + tagsize
547 }
548 return n
549 }
550
551 func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
552 mopts := opts.Options()
553 s := p.PointerSlice()
554 var err error
555 for _, v := range s {
556 m := asMessage(v.AsValueOf(goType.Elem()))
557 b = protowire.AppendVarint(b, wiretag)
558 siz := mopts.Size(m)
559 b = protowire.AppendVarint(b, uint64(siz))
560 before := len(b)
561 b, err = mopts.MarshalAppend(b, m)
562 if err != nil {
563 return b, err
564 }
565 if measuredSize := len(b) - before; siz != measuredSize {
566 return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
567 }
568 }
569 return b, nil
570 }
571
572 func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
573 if wtyp != protowire.BytesType {
574 return out, errUnknown
575 }
576 v, n := protowire.ConsumeBytes(b)
577 if n < 0 {
578 return out, errDecode
579 }
580 mp := reflect.New(goType.Elem())
581 o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
582 Buf: v,
583 Message: asMessage(mp).ProtoReflect(),
584 })
585 if err != nil {
586 return out, err
587 }
588 p.AppendPointerSlice(pointerOfValue(mp))
589 out.n = n
590 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
591 return out, nil
592 }
593
594 func isInitMessageSlice(p pointer, goType reflect.Type) error {
595 s := p.PointerSlice()
596 for _, v := range s {
597 m := asMessage(v.AsValueOf(goType.Elem()))
598 if err := proto.CheckInitialized(m); err != nil {
599 return err
600 }
601 }
602 return nil
603 }
604
605
606
607 func sizeMessageSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
608 mopts := opts.Options()
609 list := listv.List()
610 n := 0
611 for i, llen := 0, list.Len(); i < llen; i++ {
612 m := list.Get(i).Message().Interface()
613 n += protowire.SizeBytes(mopts.Size(m)) + tagsize
614 }
615 return n
616 }
617
618 func appendMessageSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
619 list := listv.List()
620 mopts := opts.Options()
621 for i, llen := 0, list.Len(); i < llen; i++ {
622 m := list.Get(i).Message().Interface()
623 b = protowire.AppendVarint(b, wiretag)
624 siz := mopts.Size(m)
625 b = protowire.AppendVarint(b, uint64(siz))
626 before := len(b)
627 var err error
628 b, err = mopts.MarshalAppend(b, m)
629 if err != nil {
630 return b, err
631 }
632 if measuredSize := len(b) - before; siz != measuredSize {
633 return nil, errors.MismatchedSizeCalculation(siz, measuredSize)
634 }
635 }
636 return b, nil
637 }
638
639 func consumeMessageSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
640 list := listv.List()
641 if wtyp != protowire.BytesType {
642 return protoreflect.Value{}, out, errUnknown
643 }
644 v, n := protowire.ConsumeBytes(b)
645 if n < 0 {
646 return protoreflect.Value{}, out, errDecode
647 }
648 m := list.NewElement()
649 o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
650 Buf: v,
651 Message: m.Message(),
652 })
653 if err != nil {
654 return protoreflect.Value{}, out, err
655 }
656 list.Append(m)
657 out.n = n
658 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
659 return listv, out, nil
660 }
661
662 func isInitMessageSliceValue(listv protoreflect.Value) error {
663 list := listv.List()
664 for i, llen := 0, list.Len(); i < llen; i++ {
665 m := list.Get(i).Message().Interface()
666 if err := proto.CheckInitialized(m); err != nil {
667 return err
668 }
669 }
670 return nil
671 }
672
673 var coderMessageSliceValue = valueCoderFuncs{
674 size: sizeMessageSliceValue,
675 marshal: appendMessageSliceValue,
676 unmarshal: consumeMessageSliceValue,
677 isInit: isInitMessageSliceValue,
678 merge: mergeMessageListValue,
679 }
680
681 func sizeGroupSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int {
682 mopts := opts.Options()
683 list := listv.List()
684 n := 0
685 for i, llen := 0, list.Len(); i < llen; i++ {
686 m := list.Get(i).Message().Interface()
687 n += 2*tagsize + mopts.Size(m)
688 }
689 return n
690 }
691
692 func appendGroupSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
693 list := listv.List()
694 mopts := opts.Options()
695 for i, llen := 0, list.Len(); i < llen; i++ {
696 m := list.Get(i).Message().Interface()
697 b = protowire.AppendVarint(b, wiretag)
698 var err error
699 b, err = mopts.MarshalAppend(b, m)
700 if err != nil {
701 return b, err
702 }
703 b = protowire.AppendVarint(b, wiretag+1)
704 }
705 return b, nil
706 }
707
708 func consumeGroupSliceValue(b []byte, listv protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
709 list := listv.List()
710 if wtyp != protowire.StartGroupType {
711 return protoreflect.Value{}, out, errUnknown
712 }
713 b, n := protowire.ConsumeGroup(num, b)
714 if n < 0 {
715 return protoreflect.Value{}, out, errDecode
716 }
717 m := list.NewElement()
718 o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
719 Buf: b,
720 Message: m.Message(),
721 })
722 if err != nil {
723 return protoreflect.Value{}, out, err
724 }
725 list.Append(m)
726 out.n = n
727 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
728 return listv, out, nil
729 }
730
731 var coderGroupSliceValue = valueCoderFuncs{
732 size: sizeGroupSliceValue,
733 marshal: appendGroupSliceValue,
734 unmarshal: consumeGroupSliceValue,
735 isInit: isInitMessageSliceValue,
736 merge: mergeMessageListValue,
737 }
738
739 func makeGroupSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
740 num := fd.Number()
741 if mi := getMessageInfo(ft); mi != nil {
742 funcs := pointerCoderFuncs{
743 size: sizeGroupSliceInfo,
744 marshal: appendGroupSliceInfo,
745 unmarshal: consumeGroupSliceInfo,
746 merge: mergeMessageSlice,
747 }
748 if needsInitCheck(mi.Desc) {
749 funcs.isInit = isInitMessageSliceInfo
750 }
751 return funcs
752 }
753 return pointerCoderFuncs{
754 size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int {
755 return sizeGroupSlice(p, ft, f.tagsize, opts)
756 },
757 marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
758 return appendGroupSlice(b, p, f.wiretag, ft, opts)
759 },
760 unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
761 return consumeGroupSlice(b, p, num, wtyp, ft, opts)
762 },
763 isInit: func(p pointer, f *coderFieldInfo) error {
764 return isInitMessageSlice(p, ft)
765 },
766 merge: mergeMessageSlice,
767 }
768 }
769
770 func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, opts marshalOptions) int {
771 mopts := opts.Options()
772 s := p.PointerSlice()
773 n := 0
774 for _, v := range s {
775 m := asMessage(v.AsValueOf(messageType.Elem()))
776 n += 2*tagsize + mopts.Size(m)
777 }
778 return n
779 }
780
781 func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
782 s := p.PointerSlice()
783 var err error
784 for _, v := range s {
785 m := asMessage(v.AsValueOf(messageType.Elem()))
786 b = protowire.AppendVarint(b, wiretag)
787 b, err = opts.Options().MarshalAppend(b, m)
788 if err != nil {
789 return b, err
790 }
791 b = protowire.AppendVarint(b, wiretag+1)
792 }
793 return b, nil
794 }
795
796 func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire.Type, goType reflect.Type, opts unmarshalOptions) (out unmarshalOutput, err error) {
797 if wtyp != protowire.StartGroupType {
798 return out, errUnknown
799 }
800 b, n := protowire.ConsumeGroup(num, b)
801 if n < 0 {
802 return out, errDecode
803 }
804 mp := reflect.New(goType.Elem())
805 o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{
806 Buf: b,
807 Message: asMessage(mp).ProtoReflect(),
808 })
809 if err != nil {
810 return out, err
811 }
812 p.AppendPointerSlice(pointerOfValue(mp))
813 out.n = n
814 out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0
815 return out, nil
816 }
817
818 func sizeGroupSliceInfo(p pointer, f *coderFieldInfo, opts marshalOptions) int {
819 s := p.PointerSlice()
820 n := 0
821 for _, v := range s {
822 n += 2*f.tagsize + f.mi.sizePointer(v, opts)
823 }
824 return n
825 }
826
827 func appendGroupSliceInfo(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
828 s := p.PointerSlice()
829 var err error
830 for _, v := range s {
831 b = protowire.AppendVarint(b, f.wiretag)
832 b, err = f.mi.marshalAppendPointer(b, v, opts)
833 if err != nil {
834 return b, err
835 }
836 b = protowire.AppendVarint(b, f.wiretag+1)
837 }
838 return b, nil
839 }
840
841 func consumeGroupSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
842 if wtyp != protowire.StartGroupType {
843 return unmarshalOutput{}, errUnknown
844 }
845 m := reflect.New(f.mi.GoReflectType.Elem()).Interface()
846 mp := pointerOfIface(m)
847 out, err := f.mi.unmarshalPointer(b, mp, f.num, opts)
848 if err != nil {
849 return out, err
850 }
851 p.AppendPointerSlice(mp)
852 return out, nil
853 }
854
855 func asMessage(v reflect.Value) protoreflect.ProtoMessage {
856 if m, ok := v.Interface().(protoreflect.ProtoMessage); ok {
857 return m
858 }
859 return legacyWrapMessage(v).Interface()
860 }
861
View as plain text