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