1
2
3
4
5 package main
6
7 import (
8 "text/template"
9 )
10
11 func generateImplCodec() string {
12 return mustExecute(implCodecTemplate, ProtoKinds)
13 }
14
15 var implCodecTemplate = template.Must(template.New("").Parse(`
16 {{- /*
17 IsZero is an expression testing if 'v' is the zero value.
18 */ -}}
19 {{- define "IsZero" -}}
20 {{if eq .WireType "Bytes" -}}
21 len(v) == 0
22 {{- else if or (eq .Name "Double") (eq .Name "Float") -}}
23 v == 0 && !math.Signbit(float64(v))
24 {{- else -}}
25 v == {{.GoType.Zero}}
26 {{- end -}}
27 {{- end -}}
28
29 {{- /*
30 Size is an expression computing the size of 'v'.
31 */ -}}
32 {{- define "Size" -}}
33 {{- if .WireType.ConstSize -}}
34 protowire.Size{{.WireType}}()
35 {{- else if eq .WireType "Bytes" -}}
36 protowire.SizeBytes(len({{.FromGoType}}))
37 {{- else -}}
38 protowire.Size{{.WireType}}({{.FromGoType}})
39 {{- end -}}
40 {{- end -}}
41
42 {{- define "SizeValue" -}}
43 {{- if .WireType.ConstSize -}}
44 protowire.Size{{.WireType}}()
45 {{- else if eq .WireType "Bytes" -}}
46 protowire.SizeBytes(len({{.FromValue}}))
47 {{- else -}}
48 protowire.Size{{.WireType}}({{.FromValue}})
49 {{- end -}}
50 {{- end -}}
51
52 {{- /*
53 Append is a set of statements appending 'v' to 'b'.
54 */ -}}
55 {{- define "Append" -}}
56 {{- if eq .Name "String" -}}
57 b = protowire.AppendString(b, {{.FromGoType}})
58 {{- else -}}
59 b = protowire.Append{{.WireType}}(b, {{.FromGoType}})
60 {{- end -}}
61 {{- end -}}
62
63 {{- define "AppendValue" -}}
64 {{- if eq .Name "String" -}}
65 b = protowire.AppendString(b, {{.FromValue}})
66 {{- else -}}
67 b = protowire.Append{{.WireType}}(b, {{.FromValue}})
68 {{- end -}}
69 {{- end -}}
70
71 {{- define "Consume" -}}
72 {{- if eq .WireType "Varint" -}}
73 var v uint64
74 var n int
75 if len(b) >= 1 && b[0] < 0x80 {
76 v = uint64(b[0])
77 n = 1
78 } else if len(b) >= 2 && b[1] < 128 {
79 v = uint64(b[0]&0x7f) + uint64(b[1])<<7
80 n = 2
81 } else {
82 v, n = protowire.ConsumeVarint(b)
83 }
84 {{- else -}}
85 v, n := protowire.Consume{{.WireType}}(b)
86 {{- end -}}
87 {{- end -}}
88
89 {{- range .}}
90
91 {{- if .FromGoType }}
92 // size{{.Name}} returns the size of wire encoding a {{.GoType}} pointer as a {{.Name}}.
93 func size{{.Name}}(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
94 {{if not .WireType.ConstSize -}}
95 v := *p.{{.GoType.PointerMethod}}()
96 {{- end}}
97 return f.tagsize + {{template "Size" .}}
98 }
99
100 // append{{.Name}} wire encodes a {{.GoType}} pointer as a {{.Name}}.
101 func append{{.Name}}(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
102 v := *p.{{.GoType.PointerMethod}}()
103 b = protowire.AppendVarint(b, f.wiretag)
104 {{template "Append" .}}
105 return b, nil
106 }
107
108 // consume{{.Name}} wire decodes a {{.GoType}} pointer as a {{.Name}}.
109 func consume{{.Name}}(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
110 if wtyp != {{.WireType.Expr}} {
111 return out, errUnknown
112 }
113 {{template "Consume" .}}
114 if n < 0 {
115 return out, errDecode
116 }
117 *p.{{.GoType.PointerMethod}}() = {{.ToGoType}}
118 out.n = n
119 return out, nil
120 }
121
122 var coder{{.Name}} = pointerCoderFuncs{
123 size: size{{.Name}},
124 marshal: append{{.Name}},
125 unmarshal: consume{{.Name}},
126 merge: merge{{.GoType.PointerMethod}},
127 }
128
129 {{if or (eq .Name "Bytes") (eq .Name "String")}}
130 // append{{.Name}}ValidateUTF8 wire encodes a {{.GoType}} pointer as a {{.Name}}.
131 func append{{.Name}}ValidateUTF8(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
132 v := *p.{{.GoType.PointerMethod}}()
133 b = protowire.AppendVarint(b, f.wiretag)
134 {{template "Append" .}}
135 if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
136 return b, errInvalidUTF8{}
137 }
138 return b, nil
139 }
140
141 // consume{{.Name}}ValidateUTF8 wire decodes a {{.GoType}} pointer as a {{.Name}}.
142 func consume{{.Name}}ValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
143 if wtyp != {{.WireType.Expr}} {
144 return out, errUnknown
145 }
146 {{template "Consume" .}}
147 if n < 0 {
148 return out, errDecode
149 }
150 if !utf8.Valid(v) {
151 return out, errInvalidUTF8{}
152 }
153 *p.{{.GoType.PointerMethod}}() = {{.ToGoType}}
154 out.n = n
155 return out, nil
156 }
157
158 var coder{{.Name}}ValidateUTF8 = pointerCoderFuncs{
159 size: size{{.Name}},
160 marshal: append{{.Name}}ValidateUTF8,
161 unmarshal: consume{{.Name}}ValidateUTF8,
162 merge: merge{{.GoType.PointerMethod}},
163 }
164 {{end}}
165
166 // size{{.Name}}NoZero returns the size of wire encoding a {{.GoType}} pointer as a {{.Name}}.
167 // The zero value is not encoded.
168 func size{{.Name}}NoZero(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
169 v := *p.{{.GoType.PointerMethod}}()
170 if {{template "IsZero" .}} {
171 return 0
172 }
173 return f.tagsize + {{template "Size" .}}
174 }
175
176 // append{{.Name}}NoZero wire encodes a {{.GoType}} pointer as a {{.Name}}.
177 // The zero value is not encoded.
178 func append{{.Name}}NoZero(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
179 v := *p.{{.GoType.PointerMethod}}()
180 if {{template "IsZero" .}} {
181 return b, nil
182 }
183 b = protowire.AppendVarint(b, f.wiretag)
184 {{template "Append" .}}
185 return b, nil
186 }
187
188 {{if .ToGoTypeNoZero}}
189 // consume{{.Name}}NoZero wire decodes a {{.GoType}} pointer as a {{.Name}}.
190 // The zero value is not decoded.
191 func consume{{.Name}}NoZero(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
192 if wtyp != {{.WireType.Expr}} {
193 return out, errUnknown
194 }
195 {{template "Consume" .}}
196 if n < 0 {
197 return out, errDecode
198 }
199 *p.{{.GoType.PointerMethod}}() = {{.ToGoTypeNoZero}}
200 out.n = n
201 return out, nil
202 }
203 {{end}}
204
205 var coder{{.Name}}NoZero = pointerCoderFuncs{
206 size: size{{.Name}}NoZero,
207 marshal: append{{.Name}}NoZero,
208 unmarshal: consume{{.Name}}{{if .ToGoTypeNoZero}}NoZero{{end}},
209 merge: merge{{.GoType.PointerMethod}}NoZero,
210 }
211
212 {{if or (eq .Name "Bytes") (eq .Name "String")}}
213 // append{{.Name}}NoZeroValidateUTF8 wire encodes a {{.GoType}} pointer as a {{.Name}}.
214 // The zero value is not encoded.
215 func append{{.Name}}NoZeroValidateUTF8(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
216 v := *p.{{.GoType.PointerMethod}}()
217 if {{template "IsZero" .}} {
218 return b, nil
219 }
220 b = protowire.AppendVarint(b, f.wiretag)
221 {{template "Append" .}}
222 if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
223 return b, errInvalidUTF8{}
224 }
225 return b, nil
226 }
227
228 {{if .ToGoTypeNoZero}}
229 // consume{{.Name}}NoZeroValidateUTF8 wire decodes a {{.GoType}} pointer as a {{.Name}}.
230 func consume{{.Name}}NoZeroValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
231 if wtyp != {{.WireType.Expr}} {
232 return out, errUnknown
233 }
234 {{template "Consume" .}}
235 if n < 0 {
236 return out, errDecode
237 }
238 if !utf8.Valid(v) {
239 return out, errInvalidUTF8{}
240 }
241 *p.{{.GoType.PointerMethod}}() = {{.ToGoTypeNoZero}}
242 out.n = n
243 return out, nil
244 }
245 {{end}}
246
247 var coder{{.Name}}NoZeroValidateUTF8 = pointerCoderFuncs{
248 size: size{{.Name}}NoZero,
249 marshal: append{{.Name}}NoZeroValidateUTF8,
250 unmarshal: consume{{.Name}}{{if .ToGoTypeNoZero}}NoZero{{end}}ValidateUTF8,
251 merge: merge{{.GoType.PointerMethod}}NoZero,
252 }
253 {{end}}
254
255 {{- if not .NoPointer}}
256 // size{{.Name}}Ptr returns the size of wire encoding a *{{.GoType}} pointer as a {{.Name}}.
257 // It panics if the pointer is nil.
258 func size{{.Name}}Ptr(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
259 {{if not .WireType.ConstSize -}}
260 v := **p.{{.GoType.PointerMethod}}Ptr()
261 {{end -}}
262 return f.tagsize + {{template "Size" .}}
263 }
264
265 // append{{.Name}}Ptr wire encodes a *{{.GoType}} pointer as a {{.Name}}.
266 // It panics if the pointer is nil.
267 func append{{.Name}}Ptr(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
268 v := **p.{{.GoType.PointerMethod}}Ptr()
269 b = protowire.AppendVarint(b, f.wiretag)
270 {{template "Append" .}}
271 return b, nil
272 }
273
274 // consume{{.Name}}Ptr wire decodes a *{{.GoType}} pointer as a {{.Name}}.
275 func consume{{.Name}}Ptr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
276 if wtyp != {{.WireType.Expr}} {
277 return out, errUnknown
278 }
279 {{template "Consume" .}}
280 if n < 0 {
281 return out, errDecode
282 }
283 vp := p.{{.GoType.PointerMethod}}Ptr()
284 if *vp == nil {
285 *vp = new({{.GoType}})
286 }
287 **vp = {{.ToGoType}}
288 out.n = n
289 return out, nil
290 }
291
292 var coder{{.Name}}Ptr = pointerCoderFuncs{
293 size: size{{.Name}}Ptr,
294 marshal: append{{.Name}}Ptr,
295 unmarshal: consume{{.Name}}Ptr,
296 merge: merge{{.GoType.PointerMethod}}Ptr,
297 }
298 {{end}}
299
300 {{if (eq .Name "String")}}
301 // append{{.Name}}PtrValidateUTF8 wire encodes a *{{.GoType}} pointer as a {{.Name}}.
302 // It panics if the pointer is nil.
303 func append{{.Name}}PtrValidateUTF8(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
304 v := **p.{{.GoType.PointerMethod}}Ptr()
305 b = protowire.AppendVarint(b, f.wiretag)
306 {{template "Append" .}}
307 if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
308 return b, errInvalidUTF8{}
309 }
310 return b, nil
311 }
312
313 // consume{{.Name}}PtrValidateUTF8 wire decodes a *{{.GoType}} pointer as a {{.Name}}.
314 func consume{{.Name}}PtrValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
315 if wtyp != {{.WireType.Expr}} {
316 return out, errUnknown
317 }
318 {{template "Consume" .}}
319 if n < 0 {
320 return out, errDecode
321 }
322 if !utf8.Valid(v) {
323 return out, errInvalidUTF8{}
324 }
325 vp := p.{{.GoType.PointerMethod}}Ptr()
326 if *vp == nil {
327 *vp = new({{.GoType}})
328 }
329 **vp = {{.ToGoType}}
330 out.n = n
331 return out, nil
332 }
333
334 var coder{{.Name}}PtrValidateUTF8 = pointerCoderFuncs{
335 size: size{{.Name}}Ptr,
336 marshal: append{{.Name}}PtrValidateUTF8,
337 unmarshal: consume{{.Name}}PtrValidateUTF8,
338 merge: merge{{.GoType.PointerMethod}}Ptr,
339 }
340 {{end}}
341
342 // size{{.Name}}Slice returns the size of wire encoding a []{{.GoType}} pointer as a repeated {{.Name}}.
343 func size{{.Name}}Slice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
344 s := *p.{{.GoType.PointerMethod}}Slice()
345 {{if .WireType.ConstSize -}}
346 size = len(s) * (f.tagsize + {{template "Size" .}})
347 {{- else -}}
348 for _, v := range s {
349 size += f.tagsize + {{template "Size" .}}
350 }
351 {{- end}}
352 return size
353 }
354
355 // append{{.Name}}Slice encodes a []{{.GoType}} pointer as a repeated {{.Name}}.
356 func append{{.Name}}Slice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
357 s := *p.{{.GoType.PointerMethod}}Slice()
358 for _, v := range s {
359 b = protowire.AppendVarint(b, f.wiretag)
360 {{template "Append" .}}
361 }
362 return b, nil
363 }
364
365 // consume{{.Name}}Slice wire decodes a []{{.GoType}} pointer as a repeated {{.Name}}.
366 func consume{{.Name}}Slice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
367 sp := p.{{.GoType.PointerMethod}}Slice()
368 {{- if .WireType.Packable}}
369 if wtyp == protowire.BytesType {
370 b, n := protowire.ConsumeBytes(b)
371 if n < 0 {
372 return out, errDecode
373 }
374 {{if .WireType.ConstSize -}}
375 count := len(b) / {{template "Size" .}}
376 {{- else -}}
377 count := 0
378 for _, v := range b {
379 if v < 0x80 {
380 count++
381 }
382 }
383 {{- end}}
384 if count > 0 {
385 p.grow{{.GoType.PointerMethod}}Slice(count)
386 }
387 s := *sp
388 for len(b) > 0 {
389 {{template "Consume" .}}
390 if n < 0 {
391 return out, errDecode
392 }
393 s = append(s, {{.ToGoType}})
394 b = b[n:]
395 }
396 *sp = s
397 out.n = n
398 return out, nil
399 }
400 {{- end}}
401 if wtyp != {{.WireType.Expr}} {
402 return out, errUnknown
403 }
404 {{template "Consume" .}}
405 if n < 0 {
406 return out, errDecode
407 }
408 *sp = append(*sp, {{.ToGoType}})
409 out.n = n
410 return out, nil
411 }
412
413 var coder{{.Name}}Slice = pointerCoderFuncs{
414 size: size{{.Name}}Slice,
415 marshal: append{{.Name}}Slice,
416 unmarshal: consume{{.Name}}Slice,
417 merge: merge{{.GoType.PointerMethod}}Slice,
418 }
419
420 {{if or (eq .Name "Bytes") (eq .Name "String")}}
421 // append{{.Name}}SliceValidateUTF8 encodes a []{{.GoType}} pointer as a repeated {{.Name}}.
422 func append{{.Name}}SliceValidateUTF8(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
423 s := *p.{{.GoType.PointerMethod}}Slice()
424 for _, v := range s {
425 b = protowire.AppendVarint(b, f.wiretag)
426 {{template "Append" .}}
427 if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
428 return b, errInvalidUTF8{}
429 }
430 }
431 return b, nil
432 }
433
434 // consume{{.Name}}SliceValidateUTF8 wire decodes a []{{.GoType}} pointer as a repeated {{.Name}}.
435 func consume{{.Name}}SliceValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
436 if wtyp != {{.WireType.Expr}} {
437 return out, errUnknown
438 }
439 {{template "Consume" .}}
440 if n < 0 {
441 return out, errDecode
442 }
443 if !utf8.Valid(v) {
444 return out, errInvalidUTF8{}
445 }
446 sp := p.{{.GoType.PointerMethod}}Slice()
447 *sp = append(*sp, {{.ToGoType}})
448 out.n = n
449 return out, nil
450 }
451
452 var coder{{.Name}}SliceValidateUTF8 = pointerCoderFuncs{
453 size: size{{.Name}}Slice,
454 marshal: append{{.Name}}SliceValidateUTF8,
455 unmarshal: consume{{.Name}}SliceValidateUTF8,
456 merge: merge{{.GoType.PointerMethod}}Slice,
457 }
458 {{end}}
459
460 {{if or (eq .WireType "Varint") (eq .WireType "Fixed32") (eq .WireType "Fixed64")}}
461 // size{{.Name}}PackedSlice returns the size of wire encoding a []{{.GoType}} pointer as a packed repeated {{.Name}}.
462 func size{{.Name}}PackedSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
463 s := *p.{{.GoType.PointerMethod}}Slice()
464 if len(s) == 0 {
465 return 0
466 }
467 {{if .WireType.ConstSize -}}
468 n := len(s) * {{template "Size" .}}
469 {{- else -}}
470 n := 0
471 for _, v := range s {
472 n += {{template "Size" .}}
473 }
474 {{- end}}
475 return f.tagsize + protowire.SizeBytes(n)
476 }
477
478 // append{{.Name}}PackedSlice encodes a []{{.GoType}} pointer as a packed repeated {{.Name}}.
479 func append{{.Name}}PackedSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
480 s := *p.{{.GoType.PointerMethod}}Slice()
481 if len(s) == 0 {
482 return b, nil
483 }
484 b = protowire.AppendVarint(b, f.wiretag)
485 {{if .WireType.ConstSize -}}
486 n := len(s) * {{template "Size" .}}
487 {{- else -}}
488 n := 0
489 for _, v := range s {
490 n += {{template "Size" .}}
491 }
492 {{- end}}
493 b = protowire.AppendVarint(b, uint64(n))
494 for _, v := range s {
495 {{template "Append" .}}
496 }
497 return b, nil
498 }
499
500 var coder{{.Name}}PackedSlice = pointerCoderFuncs{
501 size: size{{.Name}}PackedSlice,
502 marshal: append{{.Name}}PackedSlice,
503 unmarshal: consume{{.Name}}Slice,
504 merge: merge{{.GoType.PointerMethod}}Slice,
505 }
506 {{end}}
507
508 {{end -}}
509
510 {{- if not .NoValueCodec}}
511 // size{{.Name}}Value returns the size of wire encoding a {{.GoType}} value as a {{.Name}}.
512 func size{{.Name}}Value(v protoreflect.Value, tagsize int, opts marshalOptions) int {
513 return tagsize + {{template "SizeValue" .}}
514 }
515
516 // append{{.Name}}Value encodes a {{.GoType}} value as a {{.Name}}.
517 func append{{.Name}}Value(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
518 b = protowire.AppendVarint(b, wiretag)
519 {{template "AppendValue" .}}
520 return b, nil
521 }
522
523 // consume{{.Name}}Value decodes a {{.GoType}} value as a {{.Name}}.
524 func consume{{.Name}}Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
525 if wtyp != {{.WireType.Expr}} {
526 return protoreflect.Value{}, out, errUnknown
527 }
528 {{template "Consume" .}}
529 if n < 0 {
530 return protoreflect.Value{}, out, errDecode
531 }
532 out.n = n
533 return {{.ToValue}}, out, nil
534 }
535
536 var coder{{.Name}}Value = valueCoderFuncs{
537 size: size{{.Name}}Value,
538 marshal: append{{.Name}}Value,
539 unmarshal: consume{{.Name}}Value,
540 {{- if (eq .Name "Bytes")}}
541 merge: mergeBytesValue,
542 {{- else}}
543 merge: mergeScalarValue,
544 {{- end}}
545 }
546
547 {{if (eq .Name "String")}}
548 // append{{.Name}}ValueValidateUTF8 encodes a {{.GoType}} value as a {{.Name}}.
549 func append{{.Name}}ValueValidateUTF8(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
550 b = protowire.AppendVarint(b, wiretag)
551 {{template "AppendValue" .}}
552 if !utf8.ValidString({{.FromValue}}) {
553 return b, errInvalidUTF8{}
554 }
555 return b, nil
556 }
557
558 // consume{{.Name}}ValueValidateUTF8 decodes a {{.GoType}} value as a {{.Name}}.
559 func consume{{.Name}}ValueValidateUTF8(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
560 if wtyp != {{.WireType.Expr}} {
561 return protoreflect.Value{}, out, errUnknown
562 }
563 {{template "Consume" .}}
564 if n < 0 {
565 return protoreflect.Value{}, out, errDecode
566 }
567 if !utf8.Valid(v) {
568 return protoreflect.Value{}, out, errInvalidUTF8{}
569 }
570 out.n = n
571 return {{.ToValue}}, out, nil
572 }
573
574 var coder{{.Name}}ValueValidateUTF8 = valueCoderFuncs{
575 size: size{{.Name}}Value,
576 marshal: append{{.Name}}ValueValidateUTF8,
577 unmarshal: consume{{.Name}}ValueValidateUTF8,
578 merge: mergeScalarValue,
579 }
580 {{end}}
581
582 // size{{.Name}}SliceValue returns the size of wire encoding a []{{.GoType}} value as a repeated {{.Name}}.
583 func size{{.Name}}SliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) (size int) {
584 list := listv.List()
585 {{if .WireType.ConstSize -}}
586 size = list.Len() * (tagsize + {{template "SizeValue" .}})
587 {{- else -}}
588 for i, llen := 0, list.Len(); i < llen; i++ {
589 v := list.Get(i)
590 size += tagsize + {{template "SizeValue" .}}
591 }
592 {{- end}}
593 return size
594 }
595
596 // append{{.Name}}SliceValue encodes a []{{.GoType}} value as a repeated {{.Name}}.
597 func append{{.Name}}SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
598 list := listv.List()
599 for i, llen := 0, list.Len(); i < llen; i++ {
600 v := list.Get(i)
601 b = protowire.AppendVarint(b, wiretag)
602 {{template "AppendValue" .}}
603 }
604 return b, nil
605 }
606
607 // consume{{.Name}}SliceValue wire decodes a []{{.GoType}} value as a repeated {{.Name}}.
608 func consume{{.Name}}SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
609 list := listv.List()
610 {{- if .WireType.Packable}}
611 if wtyp == protowire.BytesType {
612 b, n := protowire.ConsumeBytes(b)
613 if n < 0 {
614 return protoreflect.Value{}, out, errDecode
615 }
616 for len(b) > 0 {
617 {{template "Consume" .}}
618 if n < 0 {
619 return protoreflect.Value{}, out, errDecode
620 }
621 list.Append({{.ToValue}})
622 b = b[n:]
623 }
624 out.n = n
625 return listv, out, nil
626 }
627 {{- end}}
628 if wtyp != {{.WireType.Expr}} {
629 return protoreflect.Value{}, out, errUnknown
630 }
631 {{template "Consume" .}}
632 if n < 0 {
633 return protoreflect.Value{}, out, errDecode
634 }
635 list.Append({{.ToValue}})
636 out.n = n
637 return listv, out, nil
638 }
639
640 var coder{{.Name}}SliceValue = valueCoderFuncs{
641 size: size{{.Name}}SliceValue,
642 marshal: append{{.Name}}SliceValue,
643 unmarshal: consume{{.Name}}SliceValue,
644 {{- if (eq .Name "Bytes")}}
645 merge: mergeBytesListValue,
646 {{- else}}
647 merge: mergeListValue,
648 {{- end}}
649 }
650
651 {{if or (eq .WireType "Varint") (eq .WireType "Fixed32") (eq .WireType "Fixed64")}}
652 // size{{.Name}}PackedSliceValue returns the size of wire encoding a []{{.GoType}} value as a packed repeated {{.Name}}.
653 func size{{.Name}}PackedSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) (size int) {
654 list := listv.List()
655 llen := list.Len()
656 if llen == 0 {
657 return 0
658 }
659 {{if .WireType.ConstSize -}}
660 n := llen * {{template "SizeValue" .}}
661 {{- else -}}
662 n := 0
663 for i, llen := 0, llen; i < llen; i++ {
664 v := list.Get(i)
665 n += {{template "SizeValue" .}}
666 }
667 {{- end}}
668 return tagsize + protowire.SizeBytes(n)
669 }
670
671 // append{{.Name}}PackedSliceValue encodes a []{{.GoType}} value as a packed repeated {{.Name}}.
672 func append{{.Name}}PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
673 list := listv.List()
674 llen := list.Len()
675 if llen == 0 {
676 return b, nil
677 }
678 b = protowire.AppendVarint(b, wiretag)
679 {{if .WireType.ConstSize -}}
680 n := llen * {{template "SizeValue" .}}
681 {{- else -}}
682 n := 0
683 for i := 0; i < llen; i++ {
684 v := list.Get(i)
685 n += {{template "SizeValue" .}}
686 }
687 {{- end}}
688 b = protowire.AppendVarint(b, uint64(n))
689 for i := 0; i < llen; i++ {
690 v := list.Get(i)
691 {{template "AppendValue" .}}
692 }
693 return b, nil
694 }
695
696 var coder{{.Name}}PackedSliceValue = valueCoderFuncs{
697 size: size{{.Name}}PackedSliceValue,
698 marshal: append{{.Name}}PackedSliceValue,
699 unmarshal: consume{{.Name}}SliceValue,
700 merge: mergeListValue,
701 }
702 {{end}}
703
704 {{- end}}{{/* if not .NoValueCodec */}}
705
706 {{end -}}
707
708 // We append to an empty array rather than a nil []byte to get non-nil zero-length byte slices.
709 var emptyBuf [0]byte
710
711 var wireTypes = map[protoreflect.Kind]protowire.Type{
712 {{range . -}}
713 protoreflect.{{.Name}}Kind: {{.WireType.Expr}},
714 {{end}}
715 }
716 `))
717
718 func generateImplMessage() string {
719 return mustExecute(implMessageTemplate, []string{"messageState", "messageReflectWrapper"})
720 }
721
722 var implMessageTemplate = template.Must(template.New("").Parse(`
723 {{range . -}}
724 func (m *{{.}}) Descriptor() protoreflect.MessageDescriptor {
725 return m.messageInfo().Desc
726 }
727 func (m *{{.}}) Type() protoreflect.MessageType {
728 return m.messageInfo()
729 }
730 func (m *{{.}}) New() protoreflect.Message {
731 return m.messageInfo().New()
732 }
733 func (m *{{.}}) Interface() protoreflect.ProtoMessage {
734 {{if eq . "messageState" -}}
735 return m.protoUnwrap().(protoreflect.ProtoMessage)
736 {{- else -}}
737 if m, ok := m.protoUnwrap().(protoreflect.ProtoMessage); ok {
738 return m
739 }
740 return (*messageIfaceWrapper)(m)
741 {{- end -}}
742 }
743 func (m *{{.}}) protoUnwrap() interface{} {
744 return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
745 }
746 func (m *{{.}}) ProtoMethods() *protoiface.Methods {
747 m.messageInfo().init()
748 return &m.messageInfo().methods
749 }
750
751 // ProtoMessageInfo is a pseudo-internal API for allowing the v1 code
752 // to be able to retrieve a v2 MessageInfo struct.
753 //
754 // WARNING: This method is exempt from the compatibility promise and
755 // may be removed in the future without warning.
756 func (m *{{.}}) ProtoMessageInfo() *MessageInfo {
757 return m.messageInfo()
758 }
759
760 func (m *{{.}}) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
761 m.messageInfo().init()
762 for _, ri := range m.messageInfo().rangeInfos {
763 switch ri := ri.(type) {
764 case *fieldInfo:
765 if ri.has(m.pointer()) {
766 if !f(ri.fieldDesc, ri.get(m.pointer())) {
767 return
768 }
769 }
770 case *oneofInfo:
771 if n := ri.which(m.pointer()); n > 0 {
772 fi := m.messageInfo().fields[n]
773 if !f(fi.fieldDesc, fi.get(m.pointer())) {
774 return
775 }
776 }
777 }
778 }
779 m.messageInfo().extensionMap(m.pointer()).Range(f)
780 }
781 func (m *{{.}}) Has(fd protoreflect.FieldDescriptor) bool {
782 m.messageInfo().init()
783 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
784 return fi.has(m.pointer())
785 } else {
786 return m.messageInfo().extensionMap(m.pointer()).Has(xt)
787 }
788 }
789 func (m *{{.}}) Clear(fd protoreflect.FieldDescriptor) {
790 m.messageInfo().init()
791 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
792 fi.clear(m.pointer())
793 } else {
794 m.messageInfo().extensionMap(m.pointer()).Clear(xt)
795 }
796 }
797 func (m *{{.}}) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
798 m.messageInfo().init()
799 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
800 return fi.get(m.pointer())
801 } else {
802 return m.messageInfo().extensionMap(m.pointer()).Get(xt)
803 }
804 }
805 func (m *{{.}}) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
806 m.messageInfo().init()
807 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
808 fi.set(m.pointer(), v)
809 } else {
810 m.messageInfo().extensionMap(m.pointer()).Set(xt, v)
811 }
812 }
813 func (m *{{.}}) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
814 m.messageInfo().init()
815 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
816 return fi.mutable(m.pointer())
817 } else {
818 return m.messageInfo().extensionMap(m.pointer()).Mutable(xt)
819 }
820 }
821 func (m *{{.}}) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
822 m.messageInfo().init()
823 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
824 return fi.newField()
825 } else {
826 return xt.New()
827 }
828 }
829 func (m *{{.}}) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
830 m.messageInfo().init()
831 if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
832 return od.Fields().ByNumber(oi.which(m.pointer()))
833 }
834 panic("invalid oneof descriptor " + string(od.FullName()) + " for message " + string(m.Descriptor().FullName()))
835 }
836 func (m *{{.}}) GetUnknown() protoreflect.RawFields {
837 m.messageInfo().init()
838 return m.messageInfo().getUnknown(m.pointer())
839 }
840 func (m *{{.}}) SetUnknown(b protoreflect.RawFields) {
841 m.messageInfo().init()
842 m.messageInfo().setUnknown(m.pointer(), b)
843 }
844 func (m *{{.}}) IsValid() bool {
845 return !m.pointer().IsNil()
846 }
847
848 {{end}}
849 `))
850
851 func generateImplMerge() string {
852 return mustExecute(implMergeTemplate, GoTypes)
853 }
854
855 var implMergeTemplate = template.Must(template.New("").Parse(`
856 {{range .}}
857 {{if ne . "[]byte"}}
858 func merge{{.PointerMethod}}(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
859 *dst.{{.PointerMethod}}() = *src.{{.PointerMethod}}()
860 }
861
862 func merge{{.PointerMethod}}NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
863 v := *src.{{.PointerMethod}}()
864 if v != {{.Zero}} {
865 *dst.{{.PointerMethod}}() = v
866 }
867 }
868
869 func merge{{.PointerMethod}}Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
870 p := *src.{{.PointerMethod}}Ptr()
871 if p != nil {
872 v := *p
873 *dst.{{.PointerMethod}}Ptr() = &v
874 }
875 }
876
877 func merge{{.PointerMethod}}Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
878 ds := dst.{{.PointerMethod}}Slice()
879 ss := src.{{.PointerMethod}}Slice()
880 *ds = append(*ds, *ss...)
881 }
882
883 {{end}}
884 {{end}}
885 `))
886
View as plain text