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