blob: 700ae27b085f183e2bbf0fa352bbd3b113ad48ed [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 main
6
7import (
8 "text/template"
9)
10
Damien Neiledf7bdd2019-07-08 12:46:01 -070011func generateImplCodec() string {
12 return mustExecute(implCodecTemplate, ProtoKinds)
Damien Neilc37adef2019-04-01 13:49:56 -070013}
14
Damien Neiledf7bdd2019-07-08 12:46:01 -070015var implCodecTemplate = template.Must(template.New("").Parse(`
Damien Neilc37adef2019-04-01 13:49:56 -070016{{- /*
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 -}}
34wire.Size{{.WireType}}()
35{{- else if eq .WireType "Bytes" -}}
36wire.SizeBytes(len({{.FromGoType}}))
37{{- else -}}
38wire.Size{{.WireType}}({{.FromGoType}})
39{{- end -}}
40{{- end -}}
41
Damien Neil68b81c32019-08-22 11:41:32 -070042{{- define "SizeValue" -}}
43{{- if .WireType.ConstSize -}}
44wire.Size{{.WireType}}()
45{{- else if eq .WireType "Bytes" -}}
46wire.SizeBytes(len({{.FromValue}}))
47{{- else -}}
48wire.Size{{.WireType}}({{.FromValue}})
49{{- end -}}
50{{- end -}}
51
Damien Neilc37adef2019-04-01 13:49:56 -070052{{- /*
53 Append is a set of statements appending 'v' to 'b'.
54*/ -}}
55{{- define "Append" -}}
Damien Neilcedb5952019-06-21 12:04:07 -070056{{- if eq .Name "String" -}}
57b = wire.AppendString(b, {{.FromGoType}})
58{{- else -}}
Damien Neilc37adef2019-04-01 13:49:56 -070059b = wire.Append{{.WireType}}(b, {{.FromGoType}})
60{{- end -}}
Damien Neilcedb5952019-06-21 12:04:07 -070061{{- end -}}
Damien Neilc37adef2019-04-01 13:49:56 -070062
Damien Neil68b81c32019-08-22 11:41:32 -070063{{- define "AppendValue" -}}
64{{- if eq .Name "String" -}}
65b = wire.AppendString(b, {{.FromValue}})
66{{- else -}}
67b = wire.Append{{.WireType}}(b, {{.FromValue}})
68{{- end -}}
69{{- end -}}
70
Damien Neile91877d2019-06-27 10:54:42 -070071{{- define "Consume" -}}
72{{- if eq .Name "String" -}}
73wire.ConsumeString(b)
74{{- else -}}
75wire.Consume{{.WireType}}(b)
76{{- end -}}
77{{- end -}}
78
Damien Neilc37adef2019-04-01 13:49:56 -070079{{- range .}}
Damien Neil68b81c32019-08-22 11:41:32 -070080
Damien Neilc37adef2019-04-01 13:49:56 -070081{{- if .FromGoType }}
82// size{{.Name}} returns the size of wire encoding a {{.GoType}} pointer as a {{.Name}}.
83func size{{.Name}}(p pointer, tagsize int, _ marshalOptions) (size int) {
84 {{if not .WireType.ConstSize -}}
85 v := *p.{{.GoType.PointerMethod}}()
86 {{- end}}
87 return tagsize + {{template "Size" .}}
88}
89
90// append{{.Name}} wire encodes a {{.GoType}} pointer as a {{.Name}}.
91func append{{.Name}}(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
92 v := *p.{{.GoType.PointerMethod}}()
93 b = wire.AppendVarint(b, wiretag)
94 {{template "Append" .}}
95 return b, nil
96}
97
Damien Neile91877d2019-06-27 10:54:42 -070098// consume{{.Name}} wire decodes a {{.GoType}} pointer as a {{.Name}}.
99func consume{{.Name}}(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) {
100 if wtyp != {{.WireType.Expr}} {
101 return 0, errUnknown
102 }
103 v, n := {{template "Consume" .}}
104 if n < 0 {
105 return 0, wire.ParseError(n)
106 }
107 *p.{{.GoType.PointerMethod}}() = {{.ToGoType}}
108 return n, nil
109}
110
Damien Neilc37adef2019-04-01 13:49:56 -0700111var coder{{.Name}} = pointerCoderFuncs{
Damien Neile91877d2019-06-27 10:54:42 -0700112 size: size{{.Name}},
113 marshal: append{{.Name}},
114 unmarshal: consume{{.Name}},
Damien Neilc37adef2019-04-01 13:49:56 -0700115}
116
Joe Tsaic51e2e02019-07-13 00:44:41 -0700117{{if or (eq .Name "Bytes") (eq .Name "String")}}
118// append{{.Name}}ValidateUTF8 wire encodes a {{.GoType}} pointer as a {{.Name}}.
119func append{{.Name}}ValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
120 v := *p.{{.GoType.PointerMethod}}()
121 b = wire.AppendVarint(b, wiretag)
122 {{template "Append" .}}
123 if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
124 return b, errInvalidUTF8{}
125 }
126 return b, nil
127}
128
129// consume{{.Name}}ValidateUTF8 wire decodes a {{.GoType}} pointer as a {{.Name}}.
130func consume{{.Name}}ValidateUTF8(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) {
131 if wtyp != {{.WireType.Expr}} {
132 return 0, errUnknown
133 }
134 v, n := {{template "Consume" .}}
135 if n < 0 {
136 return 0, wire.ParseError(n)
137 }
138 if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
139 return 0, errInvalidUTF8{}
140 }
141 *p.{{.GoType.PointerMethod}}() = {{.ToGoType}}
142 return n, nil
143}
144
145var coder{{.Name}}ValidateUTF8 = pointerCoderFuncs{
146 size: size{{.Name}},
147 marshal: append{{.Name}}ValidateUTF8,
148 unmarshal: consume{{.Name}}ValidateUTF8,
149}
150{{end}}
151
152// size{{.Name}}NoZero returns the size of wire encoding a {{.GoType}} pointer as a {{.Name}}.
Damien Neilc37adef2019-04-01 13:49:56 -0700153// The zero value is not encoded.
154func size{{.Name}}NoZero(p pointer, tagsize int, _ marshalOptions) (size int) {
155 v := *p.{{.GoType.PointerMethod}}()
156 if {{template "IsZero" .}} {
157 return 0
158 }
159 return tagsize + {{template "Size" .}}
160}
161
Joe Tsaic51e2e02019-07-13 00:44:41 -0700162// append{{.Name}}NoZero wire encodes a {{.GoType}} pointer as a {{.Name}}.
Damien Neilc37adef2019-04-01 13:49:56 -0700163// The zero value is not encoded.
164func append{{.Name}}NoZero(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
165 v := *p.{{.GoType.PointerMethod}}()
166 if {{template "IsZero" .}} {
167 return b, nil
168 }
169 b = wire.AppendVarint(b, wiretag)
170 {{template "Append" .}}
171 return b, nil
172}
173
Damien Neil8003f082019-08-02 15:13:00 -0700174{{if .ToGoTypeNoZero}}
175// consume{{.Name}}NoZero wire decodes a {{.GoType}} pointer as a {{.Name}}.
176// The zero value is not decoded.
177func consume{{.Name}}NoZero(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) {
178 if wtyp != {{.WireType.Expr}} {
179 return 0, errUnknown
180 }
181 v, n := {{template "Consume" .}}
182 if n < 0 {
183 return 0, wire.ParseError(n)
184 }
185 *p.{{.GoType.PointerMethod}}() = {{.ToGoTypeNoZero}}
186 return n, nil
187}
188{{end}}
189
Damien Neilc37adef2019-04-01 13:49:56 -0700190var coder{{.Name}}NoZero = pointerCoderFuncs{
Damien Neile91877d2019-06-27 10:54:42 -0700191 size: size{{.Name}}NoZero,
192 marshal: append{{.Name}}NoZero,
Damien Neil8003f082019-08-02 15:13:00 -0700193 unmarshal: consume{{.Name}}{{if .ToGoTypeNoZero}}NoZero{{end}},
Damien Neilc37adef2019-04-01 13:49:56 -0700194}
195
Joe Tsaic51e2e02019-07-13 00:44:41 -0700196{{if or (eq .Name "Bytes") (eq .Name "String")}}
197// append{{.Name}}NoZeroValidateUTF8 wire encodes a {{.GoType}} pointer as a {{.Name}}.
198// The zero value is not encoded.
199func append{{.Name}}NoZeroValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
200 v := *p.{{.GoType.PointerMethod}}()
201 if {{template "IsZero" .}} {
202 return b, nil
203 }
204 b = wire.AppendVarint(b, wiretag)
205 {{template "Append" .}}
206 if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
207 return b, errInvalidUTF8{}
208 }
209 return b, nil
210}
211
Damien Neil8003f082019-08-02 15:13:00 -0700212{{if .ToGoTypeNoZero}}
213// consume{{.Name}}NoZeroValidateUTF8 wire decodes a {{.GoType}} pointer as a {{.Name}}.
214func consume{{.Name}}NoZeroValidateUTF8(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) {
215 if wtyp != {{.WireType.Expr}} {
216 return 0, errUnknown
217 }
218 v, n := {{template "Consume" .}}
219 if n < 0 {
220 return 0, wire.ParseError(n)
221 }
222 if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
223 return 0, errInvalidUTF8{}
224 }
225 *p.{{.GoType.PointerMethod}}() = {{.ToGoTypeNoZero}}
226 return n, nil
227}
228{{end}}
229
Joe Tsaic51e2e02019-07-13 00:44:41 -0700230var coder{{.Name}}NoZeroValidateUTF8 = pointerCoderFuncs{
231 size: size{{.Name}}NoZero,
232 marshal: append{{.Name}}NoZeroValidateUTF8,
Damien Neil8003f082019-08-02 15:13:00 -0700233 unmarshal: consume{{.Name}}{{if .ToGoTypeNoZero}}NoZero{{end}}ValidateUTF8,
Joe Tsaic51e2e02019-07-13 00:44:41 -0700234}
235{{end}}
236
Damien Neilc37adef2019-04-01 13:49:56 -0700237{{- if not .NoPointer}}
238// size{{.Name}}Ptr returns the size of wire encoding a *{{.GoType}} pointer as a {{.Name}}.
239// It panics if the pointer is nil.
240func size{{.Name}}Ptr(p pointer, tagsize int, _ marshalOptions) (size int) {
241 {{if not .WireType.ConstSize -}}
242 v := **p.{{.GoType.PointerMethod}}Ptr()
243 {{end -}}
244 return tagsize + {{template "Size" .}}
245}
246
Damien Neile91877d2019-06-27 10:54:42 -0700247// append{{.Name}}Ptr wire encodes a *{{.GoType}} pointer as a {{.Name}}.
Damien Neilc37adef2019-04-01 13:49:56 -0700248// It panics if the pointer is nil.
249func append{{.Name}}Ptr(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
250 v := **p.{{.GoType.PointerMethod}}Ptr()
251 b = wire.AppendVarint(b, wiretag)
252 {{template "Append" .}}
253 return b, nil
254}
255
Damien Neile91877d2019-06-27 10:54:42 -0700256// consume{{.Name}}Ptr wire decodes a *{{.GoType}} pointer as a {{.Name}}.
257func consume{{.Name}}Ptr(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) {
258 if wtyp != {{.WireType.Expr}} {
259 return 0, errUnknown
260 }
261 v, n := {{template "Consume" .}}
262 if n < 0 {
263 return 0, wire.ParseError(n)
264 }
265 vp := p.{{.GoType.PointerMethod}}Ptr()
266 if *vp == nil {
267 *vp = new({{.GoType}})
268 }
269 **vp = {{.ToGoType}}
270 return n, nil
271}
272
Damien Neilc37adef2019-04-01 13:49:56 -0700273var coder{{.Name}}Ptr = pointerCoderFuncs{
Damien Neile91877d2019-06-27 10:54:42 -0700274 size: size{{.Name}}Ptr,
275 marshal: append{{.Name}}Ptr,
276 unmarshal: consume{{.Name}}Ptr,
Damien Neilc37adef2019-04-01 13:49:56 -0700277}
278{{end}}
279
280// size{{.Name}}Slice returns the size of wire encoding a []{{.GoType}} pointer as a repeated {{.Name}}.
281func size{{.Name}}Slice(p pointer, tagsize int, _ marshalOptions) (size int) {
282 s := *p.{{.GoType.PointerMethod}}Slice()
283 {{if .WireType.ConstSize -}}
284 size = len(s) * (tagsize + {{template "Size" .}})
285 {{- else -}}
286 for _, v := range s {
287 size += tagsize + {{template "Size" .}}
288 }
289 {{- end}}
290 return size
291}
292
293// append{{.Name}}Slice encodes a []{{.GoType}} pointer as a repeated {{.Name}}.
294func append{{.Name}}Slice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
295 s := *p.{{.GoType.PointerMethod}}Slice()
296 for _, v := range s {
297 b = wire.AppendVarint(b, wiretag)
298 {{template "Append" .}}
299 }
300 return b, nil
301}
302
Damien Neile91877d2019-06-27 10:54:42 -0700303// consume{{.Name}}Slice wire decodes a []{{.GoType}} pointer as a repeated {{.Name}}.
304func consume{{.Name}}Slice(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) {
305 sp := p.{{.GoType.PointerMethod}}Slice()
306 {{- if .WireType.Packable}}
307 if wtyp == wire.BytesType {
308 s := *sp
309 b, n = wire.ConsumeBytes(b)
310 if n < 0 {
311 return 0, wire.ParseError(n)
312 }
313 for len(b) > 0 {
314 v, n := {{template "Consume" .}}
315 if n < 0 {
316 return 0, wire.ParseError(n)
317 }
318 s = append(s, {{.ToGoType}})
319 b = b[n:]
320 }
321 *sp = s
322 return n, nil
323 }
324 {{- end}}
325 if wtyp != {{.WireType.Expr}} {
326 return 0, errUnknown
327 }
328 v, n := {{template "Consume" .}}
329 if n < 0 {
330 return 0, wire.ParseError(n)
331 }
332 *sp = append(*sp, {{.ToGoType}})
333 return n, nil
334}
335
Damien Neilc37adef2019-04-01 13:49:56 -0700336var coder{{.Name}}Slice = pointerCoderFuncs{
Damien Neile91877d2019-06-27 10:54:42 -0700337 size: size{{.Name}}Slice,
338 marshal: append{{.Name}}Slice,
339 unmarshal: consume{{.Name}}Slice,
Damien Neilc37adef2019-04-01 13:49:56 -0700340}
341
Joe Tsaic51e2e02019-07-13 00:44:41 -0700342{{if or (eq .Name "Bytes") (eq .Name "String")}}
343// append{{.Name}}SliceValidateUTF8 encodes a []{{.GoType}} pointer as a repeated {{.Name}}.
344func append{{.Name}}SliceValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
345 s := *p.{{.GoType.PointerMethod}}Slice()
346 for _, v := range s {
347 b = wire.AppendVarint(b, wiretag)
348 {{template "Append" .}}
349 if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
350 return b, errInvalidUTF8{}
351 }
352 }
353 return b, nil
354}
355
356// consume{{.Name}}SliceValidateUTF8 wire decodes a []{{.GoType}} pointer as a repeated {{.Name}}.
357func consume{{.Name}}SliceValidateUTF8(b []byte, p pointer, wtyp wire.Type, _ unmarshalOptions) (n int, err error) {
358 sp := p.{{.GoType.PointerMethod}}Slice()
359 if wtyp != {{.WireType.Expr}} {
360 return 0, errUnknown
361 }
362 v, n := {{template "Consume" .}}
363 if n < 0 {
364 return 0, wire.ParseError(n)
365 }
366 if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
367 return 0, errInvalidUTF8{}
368 }
369 *sp = append(*sp, {{.ToGoType}})
370 return n, nil
371}
372
373var coder{{.Name}}SliceValidateUTF8 = pointerCoderFuncs{
374 size: size{{.Name}}Slice,
375 marshal: append{{.Name}}SliceValidateUTF8,
376 unmarshal: consume{{.Name}}SliceValidateUTF8,
377}
378{{end}}
379
Damien Neilc37adef2019-04-01 13:49:56 -0700380{{if or (eq .WireType "Varint") (eq .WireType "Fixed32") (eq .WireType "Fixed64")}}
381// size{{.Name}}PackedSlice returns the size of wire encoding a []{{.GoType}} pointer as a packed repeated {{.Name}}.
382func size{{.Name}}PackedSlice(p pointer, tagsize int, _ marshalOptions) (size int) {
383 s := *p.{{.GoType.PointerMethod}}Slice()
384 if len(s) == 0 {
385 return 0
386 }
387 {{if .WireType.ConstSize -}}
388 n := len(s) * {{template "Size" .}}
389 {{- else -}}
390 n := 0
391 for _, v := range s {
392 n += {{template "Size" .}}
393 }
394 {{- end}}
395 return tagsize + wire.SizeBytes(n)
396}
397
398// append{{.Name}}PackedSlice encodes a []{{.GoType}} pointer as a packed repeated {{.Name}}.
399func append{{.Name}}PackedSlice(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
400 s := *p.{{.GoType.PointerMethod}}Slice()
401 if len(s) == 0 {
402 return b, nil
403 }
404 b = wire.AppendVarint(b, wiretag)
405 {{if .WireType.ConstSize -}}
406 n := len(s) * {{template "Size" .}}
407 {{- else -}}
408 n := 0
409 for _, v := range s {
410 n += {{template "Size" .}}
411 }
412 {{- end}}
413 b = wire.AppendVarint(b, uint64(n))
414 for _, v := range s {
415 {{template "Append" .}}
416 }
417 return b, nil
418}
419
420var coder{{.Name}}PackedSlice = pointerCoderFuncs{
Damien Neile91877d2019-06-27 10:54:42 -0700421 size: size{{.Name}}PackedSlice,
422 marshal: append{{.Name}}PackedSlice,
423 unmarshal: consume{{.Name}}Slice,
Damien Neilc37adef2019-04-01 13:49:56 -0700424}
425{{end}}
426
Damien Neil68b81c32019-08-22 11:41:32 -0700427{{end -}}
428
429{{- if not .NoValueCodec}}
430// size{{.Name}}Value returns the size of wire encoding a {{.GoType}} value as a {{.Name}}.
431func size{{.Name}}Value(v protoreflect.Value, tagsize int, _ marshalOptions) int {
432 return tagsize + {{template "SizeValue" .}}
Damien Neilc37adef2019-04-01 13:49:56 -0700433}
434
Damien Neil68b81c32019-08-22 11:41:32 -0700435// append{{.Name}}Value encodes a {{.GoType}} value as a {{.Name}}.
436func append{{.Name}}Value(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
Damien Neilc37adef2019-04-01 13:49:56 -0700437 b = wire.AppendVarint(b, wiretag)
Damien Neil68b81c32019-08-22 11:41:32 -0700438 {{template "AppendValue" .}}
Damien Neilc37adef2019-04-01 13:49:56 -0700439 return b, nil
440}
441
Damien Neil68b81c32019-08-22 11:41:32 -0700442// consume{{.Name}}Value decodes a {{.GoType}} value as a {{.Name}}.
443func consume{{.Name}}Value(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
Damien Neile91877d2019-06-27 10:54:42 -0700444 if wtyp != {{.WireType.Expr}} {
Damien Neil68b81c32019-08-22 11:41:32 -0700445 return protoreflect.Value{}, 0, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700446 }
447 v, n := {{template "Consume" .}}
448 if n < 0 {
Damien Neil68b81c32019-08-22 11:41:32 -0700449 return protoreflect.Value{}, 0, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700450 }
Damien Neil68b81c32019-08-22 11:41:32 -0700451 return {{.ToValue}}, n, nil
Damien Neile91877d2019-06-27 10:54:42 -0700452}
453
Damien Neil68b81c32019-08-22 11:41:32 -0700454var coder{{.Name}}Value = valueCoderFuncs{
455 size: size{{.Name}}Value,
456 marshal: append{{.Name}}Value,
457 unmarshal: consume{{.Name}}Value,
Damien Neilc37adef2019-04-01 13:49:56 -0700458}
459
Damien Neil4b3a82f2019-09-04 19:07:00 -0700460{{if (eq .Name "String")}}
Damien Neil68b81c32019-08-22 11:41:32 -0700461// append{{.Name}}ValueValidateUTF8 encodes a {{.GoType}} value as a {{.Name}}.
462func append{{.Name}}ValueValidateUTF8(b []byte, v protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
Joe Tsaic51e2e02019-07-13 00:44:41 -0700463 b = wire.AppendVarint(b, wiretag)
Damien Neil68b81c32019-08-22 11:41:32 -0700464 {{template "AppendValue" .}}
Damien Neil4b3a82f2019-09-04 19:07:00 -0700465 if !utf8.ValidString({{.FromValue}}) {
Joe Tsaic51e2e02019-07-13 00:44:41 -0700466 return b, errInvalidUTF8{}
467 }
468 return b, nil
469}
470
Damien Neil68b81c32019-08-22 11:41:32 -0700471// consume{{.Name}}ValueValidateUTF8 decodes a {{.GoType}} value as a {{.Name}}.
472func consume{{.Name}}ValueValidateUTF8(b []byte, _ protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (protoreflect.Value, int, error) {
Joe Tsaic51e2e02019-07-13 00:44:41 -0700473 if wtyp != {{.WireType.Expr}} {
Damien Neil68b81c32019-08-22 11:41:32 -0700474 return protoreflect.Value{}, 0, errUnknown
Joe Tsaic51e2e02019-07-13 00:44:41 -0700475 }
476 v, n := {{template "Consume" .}}
477 if n < 0 {
Damien Neil68b81c32019-08-22 11:41:32 -0700478 return protoreflect.Value{}, 0, wire.ParseError(n)
Joe Tsaic51e2e02019-07-13 00:44:41 -0700479 }
Damien Neil4b3a82f2019-09-04 19:07:00 -0700480 if !utf8.ValidString(v) {
Damien Neil68b81c32019-08-22 11:41:32 -0700481 return protoreflect.Value{}, 0, errInvalidUTF8{}
Joe Tsaic51e2e02019-07-13 00:44:41 -0700482 }
Damien Neil68b81c32019-08-22 11:41:32 -0700483 return {{.ToValue}}, n, nil
Joe Tsaic51e2e02019-07-13 00:44:41 -0700484}
485
Damien Neil68b81c32019-08-22 11:41:32 -0700486var coder{{.Name}}ValueValidateUTF8 = valueCoderFuncs{
487 size: size{{.Name}}Value,
488 marshal: append{{.Name}}ValueValidateUTF8,
489 unmarshal: consume{{.Name}}ValueValidateUTF8,
Joe Tsaic51e2e02019-07-13 00:44:41 -0700490}
491{{end}}
492
Damien Neil68b81c32019-08-22 11:41:32 -0700493// size{{.Name}}SliceValue returns the size of wire encoding a []{{.GoType}} value as a repeated {{.Name}}.
494func size{{.Name}}SliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
495 list := listv.List()
Damien Neilc37adef2019-04-01 13:49:56 -0700496 {{if .WireType.ConstSize -}}
Damien Neil68b81c32019-08-22 11:41:32 -0700497 size = list.Len() * (tagsize + {{template "SizeValue" .}})
Damien Neilc37adef2019-04-01 13:49:56 -0700498 {{- else -}}
Damien Neil68b81c32019-08-22 11:41:32 -0700499 for i, llen := 0, list.Len(); i < llen; i++ {
500 v := list.Get(i)
501 size += tagsize + {{template "SizeValue" .}}
Damien Neilc37adef2019-04-01 13:49:56 -0700502 }
503 {{- end}}
504 return size
505}
506
Damien Neil68b81c32019-08-22 11:41:32 -0700507// append{{.Name}}SliceValue encodes a []{{.GoType}} value as a repeated {{.Name}}.
508func append{{.Name}}SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
509 list := listv.List()
510 for i, llen := 0, list.Len(); i < llen; i++ {
511 v := list.Get(i)
Damien Neilc37adef2019-04-01 13:49:56 -0700512 b = wire.AppendVarint(b, wiretag)
Damien Neil68b81c32019-08-22 11:41:32 -0700513 {{template "AppendValue" .}}
Damien Neilc37adef2019-04-01 13:49:56 -0700514 }
515 return b, nil
516}
517
Damien Neil68b81c32019-08-22 11:41:32 -0700518// consume{{.Name}}SliceValue wire decodes a []{{.GoType}} value as a repeated {{.Name}}.
519func consume{{.Name}}SliceValue(b []byte, listv protoreflect.Value, _ wire.Number, wtyp wire.Type, _ unmarshalOptions) (_ protoreflect.Value, n int, err error) {
520 list := listv.List()
Damien Neile91877d2019-06-27 10:54:42 -0700521 {{- if .WireType.Packable}}
522 if wtyp == wire.BytesType {
Damien Neile91877d2019-06-27 10:54:42 -0700523 b, n = wire.ConsumeBytes(b)
524 if n < 0 {
Damien Neil68b81c32019-08-22 11:41:32 -0700525 return protoreflect.Value{}, 0, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700526 }
527 for len(b) > 0 {
528 v, n := {{template "Consume" .}}
529 if n < 0 {
Damien Neil68b81c32019-08-22 11:41:32 -0700530 return protoreflect.Value{}, 0, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700531 }
Damien Neil68b81c32019-08-22 11:41:32 -0700532 list.Append({{.ToValue}})
Damien Neile91877d2019-06-27 10:54:42 -0700533 b = b[n:]
534 }
Damien Neil68b81c32019-08-22 11:41:32 -0700535 return listv, n, nil
Damien Neile91877d2019-06-27 10:54:42 -0700536 }
537 {{- end}}
538 if wtyp != {{.WireType.Expr}} {
Damien Neil68b81c32019-08-22 11:41:32 -0700539 return protoreflect.Value{}, 0, errUnknown
Damien Neile91877d2019-06-27 10:54:42 -0700540 }
541 v, n := {{template "Consume" .}}
542 if n < 0 {
Damien Neil68b81c32019-08-22 11:41:32 -0700543 return protoreflect.Value{}, 0, wire.ParseError(n)
Damien Neile91877d2019-06-27 10:54:42 -0700544 }
Damien Neil68b81c32019-08-22 11:41:32 -0700545 list.Append({{.ToValue}})
546 return listv, n, nil
Damien Neile91877d2019-06-27 10:54:42 -0700547}
548
Damien Neil68b81c32019-08-22 11:41:32 -0700549var coder{{.Name}}SliceValue = valueCoderFuncs{
550 size: size{{.Name}}SliceValue,
551 marshal: append{{.Name}}SliceValue,
552 unmarshal: consume{{.Name}}SliceValue,
Damien Neilc37adef2019-04-01 13:49:56 -0700553}
554
Damien Neil7492a092019-07-10 15:23:29 -0700555{{if or (eq .WireType "Varint") (eq .WireType "Fixed32") (eq .WireType "Fixed64")}}
Damien Neil68b81c32019-08-22 11:41:32 -0700556// size{{.Name}}PackedSliceValue returns the size of wire encoding a []{{.GoType}} value as a packed repeated {{.Name}}.
557func size{{.Name}}PackedSliceValue(listv protoreflect.Value, tagsize int, _ marshalOptions) (size int) {
558 list := listv.List()
Damien Neil7492a092019-07-10 15:23:29 -0700559 {{if .WireType.ConstSize -}}
Damien Neil68b81c32019-08-22 11:41:32 -0700560 n := list.Len() * {{template "SizeValue" .}}
Damien Neil7492a092019-07-10 15:23:29 -0700561 {{- else -}}
562 n := 0
Damien Neil68b81c32019-08-22 11:41:32 -0700563 for i, llen := 0, list.Len(); i < llen; i++ {
564 v := list.Get(i)
565 n += {{template "SizeValue" .}}
Damien Neil7492a092019-07-10 15:23:29 -0700566 }
567 {{- end}}
568 return tagsize + wire.SizeBytes(n)
569}
570
Damien Neil68b81c32019-08-22 11:41:32 -0700571// append{{.Name}}PackedSliceValue encodes a []{{.GoType}} value as a packed repeated {{.Name}}.
572func append{{.Name}}PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, _ marshalOptions) ([]byte, error) {
573 list := listv.List()
574 llen := list.Len()
575 if llen == 0 {
Damien Neil7492a092019-07-10 15:23:29 -0700576 return b, nil
577 }
578 b = wire.AppendVarint(b, wiretag)
579 {{if .WireType.ConstSize -}}
Damien Neil68b81c32019-08-22 11:41:32 -0700580 n := llen * {{template "SizeValue" .}}
Damien Neil7492a092019-07-10 15:23:29 -0700581 {{- else -}}
582 n := 0
Damien Neil68b81c32019-08-22 11:41:32 -0700583 for i := 0; i < llen; i++ {
584 v := list.Get(i)
585 n += {{template "SizeValue" .}}
Damien Neil7492a092019-07-10 15:23:29 -0700586 }
587 {{- end}}
588 b = wire.AppendVarint(b, uint64(n))
Damien Neil68b81c32019-08-22 11:41:32 -0700589 for i := 0; i < llen; i++ {
590 v := list.Get(i)
591 {{template "AppendValue" .}}
Damien Neil7492a092019-07-10 15:23:29 -0700592 }
593 return b, nil
594}
595
Damien Neil68b81c32019-08-22 11:41:32 -0700596var coder{{.Name}}PackedSliceValue = valueCoderFuncs{
597 size: size{{.Name}}PackedSliceValue,
598 marshal: append{{.Name}}PackedSliceValue,
599 unmarshal: consume{{.Name}}SliceValue,
Damien Neil7492a092019-07-10 15:23:29 -0700600}
601{{end}}
602
Damien Neil68b81c32019-08-22 11:41:32 -0700603{{- end}}{{/* if not .NoValueCodec */}}
604
Damien Neilc37adef2019-04-01 13:49:56 -0700605{{end -}}
606
Damien Neil8003f082019-08-02 15:13:00 -0700607// We append to an empty array rather than a nil []byte to get non-nil zero-length byte slices.
608var emptyBuf [0]byte
609
Damien Neilc37adef2019-04-01 13:49:56 -0700610var wireTypes = map[protoreflect.Kind]wire.Type{
611{{range . -}}
612 protoreflect.{{.Name}}Kind: {{.WireType.Expr}},
613{{end}}
614}
615`))
Joe Tsai82760ce2019-06-20 03:09:57 -0700616
617func generateImplMessage() string {
618 return mustExecute(implMessageTemplate, []string{"messageState", "messageReflectWrapper"})
619}
620
621var implMessageTemplate = template.Must(template.New("").Parse(`
622{{range . -}}
623func (m *{{.}}) Descriptor() protoreflect.MessageDescriptor {
Damien Neil16163b42019-08-06 15:43:25 -0700624 return m.messageInfo().Desc
Joe Tsai82760ce2019-06-20 03:09:57 -0700625}
Joe Tsaid4211502019-07-02 14:58:02 -0700626func (m *{{.}}) Type() protoreflect.MessageType {
Damien Neil16163b42019-08-06 15:43:25 -0700627 return m.messageInfo()
Joe Tsaid4211502019-07-02 14:58:02 -0700628}
Joe Tsai82760ce2019-06-20 03:09:57 -0700629func (m *{{.}}) New() protoreflect.Message {
Damien Neil16163b42019-08-06 15:43:25 -0700630 return m.messageInfo().New()
Joe Tsai82760ce2019-06-20 03:09:57 -0700631}
632func (m *{{.}}) Interface() protoreflect.ProtoMessage {
633 {{if eq . "messageState" -}}
Joe Tsaifd528ff2019-09-03 16:30:39 -0700634 return m.protoUnwrap().(protoreflect.ProtoMessage)
Joe Tsai82760ce2019-06-20 03:09:57 -0700635 {{- else -}}
Joe Tsaifd528ff2019-09-03 16:30:39 -0700636 if m, ok := m.protoUnwrap().(protoreflect.ProtoMessage); ok {
Joe Tsai82760ce2019-06-20 03:09:57 -0700637 return m
638 }
639 return (*messageIfaceWrapper)(m)
640 {{- end -}}
641}
Joe Tsaifd528ff2019-09-03 16:30:39 -0700642func (m *{{.}}) protoUnwrap() interface{} {
Damien Neil16163b42019-08-06 15:43:25 -0700643 return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
Joe Tsai82760ce2019-06-20 03:09:57 -0700644}
Joe Tsai0f81b382019-07-10 23:14:31 -0700645func (m *{{.}}) ProtoMethods() *protoiface.Methods {
Joe Tsai2aea6142019-07-31 12:27:30 -0700646 m.messageInfo().init()
647 return &m.messageInfo().methods
Joe Tsai0f81b382019-07-10 23:14:31 -0700648}
Joe Tsai82760ce2019-06-20 03:09:57 -0700649
Joe Tsaif647c822019-07-15 15:56:54 -0700650// ProtoMessageInfo is a pseudo-internal API for allowing the v1 code
651// to be able to retrieve a v2 MessageInfo struct.
652//
653// WARNING: This method is exempt from the compatibility promise and
654// may be removed in the future without warning.
655func (m *{{.}}) ProtoMessageInfo() *MessageInfo {
Joe Tsai2aea6142019-07-31 12:27:30 -0700656 return m.messageInfo()
Joe Tsaif647c822019-07-15 15:56:54 -0700657}
658
Joe Tsai82760ce2019-06-20 03:09:57 -0700659func (m *{{.}}) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
Joe Tsai2aea6142019-07-31 12:27:30 -0700660 m.messageInfo().init()
Joe Tsai9d637ca2019-09-18 18:08:52 -0700661 for _, ri := range m.messageInfo().rangeInfos {
662 switch ri := ri.(type) {
663 case *fieldInfo:
664 if ri.has(m.pointer()) {
665 if !f(ri.fieldDesc, ri.get(m.pointer())) {
666 return
667 }
668 }
669 case *oneofInfo:
670 if n := ri.which(m.pointer()); n > 0 {
671 fi := m.messageInfo().fields[n]
672 if !f(fi.fieldDesc, fi.get(m.pointer())) {
673 return
674 }
Joe Tsai82760ce2019-06-20 03:09:57 -0700675 }
676 }
677 }
Joe Tsai2aea6142019-07-31 12:27:30 -0700678 m.messageInfo().extensionMap(m.pointer()).Range(f)
Joe Tsai82760ce2019-06-20 03:09:57 -0700679}
680func (m *{{.}}) Has(fd protoreflect.FieldDescriptor) bool {
Joe Tsai2aea6142019-07-31 12:27:30 -0700681 m.messageInfo().init()
682 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
Joe Tsai82760ce2019-06-20 03:09:57 -0700683 return fi.has(m.pointer())
684 } else {
Joe Tsai2aea6142019-07-31 12:27:30 -0700685 return m.messageInfo().extensionMap(m.pointer()).Has(xt)
Joe Tsai82760ce2019-06-20 03:09:57 -0700686 }
687}
688func (m *{{.}}) Clear(fd protoreflect.FieldDescriptor) {
Joe Tsai2aea6142019-07-31 12:27:30 -0700689 m.messageInfo().init()
690 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
Joe Tsai82760ce2019-06-20 03:09:57 -0700691 fi.clear(m.pointer())
692 } else {
Joe Tsai2aea6142019-07-31 12:27:30 -0700693 m.messageInfo().extensionMap(m.pointer()).Clear(xt)
Joe Tsai82760ce2019-06-20 03:09:57 -0700694 }
695}
696func (m *{{.}}) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
Joe Tsai2aea6142019-07-31 12:27:30 -0700697 m.messageInfo().init()
698 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
Joe Tsai82760ce2019-06-20 03:09:57 -0700699 return fi.get(m.pointer())
700 } else {
Joe Tsai2aea6142019-07-31 12:27:30 -0700701 return m.messageInfo().extensionMap(m.pointer()).Get(xt)
Joe Tsai82760ce2019-06-20 03:09:57 -0700702 }
703}
704func (m *{{.}}) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
Joe Tsai2aea6142019-07-31 12:27:30 -0700705 m.messageInfo().init()
706 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
Joe Tsai82760ce2019-06-20 03:09:57 -0700707 fi.set(m.pointer(), v)
708 } else {
Joe Tsai2aea6142019-07-31 12:27:30 -0700709 m.messageInfo().extensionMap(m.pointer()).Set(xt, v)
Joe Tsai82760ce2019-06-20 03:09:57 -0700710 }
711}
712func (m *{{.}}) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
Joe Tsai2aea6142019-07-31 12:27:30 -0700713 m.messageInfo().init()
714 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
Joe Tsai82760ce2019-06-20 03:09:57 -0700715 return fi.mutable(m.pointer())
716 } else {
Joe Tsai2aea6142019-07-31 12:27:30 -0700717 return m.messageInfo().extensionMap(m.pointer()).Mutable(xt)
Joe Tsai82760ce2019-06-20 03:09:57 -0700718 }
719}
Damien Neilf5274512019-08-05 10:48:38 -0700720func (m *{{.}}) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
Joe Tsai2aea6142019-07-31 12:27:30 -0700721 m.messageInfo().init()
722 if fi, xt := m.messageInfo().checkField(fd); fi != nil {
Damien Neilf5274512019-08-05 10:48:38 -0700723 return fi.newField()
Joe Tsai82760ce2019-06-20 03:09:57 -0700724 } else {
Damien Neilf5274512019-08-05 10:48:38 -0700725 return xt.New()
Joe Tsai82760ce2019-06-20 03:09:57 -0700726 }
727}
728func (m *{{.}}) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
Joe Tsai2aea6142019-07-31 12:27:30 -0700729 m.messageInfo().init()
730 if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
Joe Tsai82760ce2019-06-20 03:09:57 -0700731 return od.Fields().ByNumber(oi.which(m.pointer()))
732 }
733 panic("invalid oneof descriptor")
734}
735func (m *{{.}}) GetUnknown() protoreflect.RawFields {
Joe Tsai2aea6142019-07-31 12:27:30 -0700736 m.messageInfo().init()
737 return m.messageInfo().getUnknown(m.pointer())
Joe Tsai82760ce2019-06-20 03:09:57 -0700738}
739func (m *{{.}}) SetUnknown(b protoreflect.RawFields) {
Joe Tsai2aea6142019-07-31 12:27:30 -0700740 m.messageInfo().init()
741 m.messageInfo().setUnknown(m.pointer(), b)
Joe Tsai82760ce2019-06-20 03:09:57 -0700742}
Damien Neil82886da2019-11-26 13:27:24 -0800743func (m *{{.}}) IsValid() bool {
Damien Neilb120a232019-12-16 13:23:25 -0800744 return !m.pointer().IsNil()
Damien Neil82886da2019-11-26 13:27:24 -0800745}
Joe Tsai82760ce2019-06-20 03:09:57 -0700746
747{{end}}
748`))