github.com/whiteCcinn/protobuf-go@v1.0.9/internal/cmd/generate-types/impl.go (about)

     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  
     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  		s := *sp
   371  		b, n := protowire.ConsumeBytes(b)
   372  		if n < 0 {
   373  			return out, errDecode
   374  		}
   375  		for len(b) > 0 {
   376  			{{template "Consume" .}}
   377  			if n < 0 {
   378  				return out, errDecode
   379  			}
   380  			s = append(s, {{.ToGoType}})
   381  			b = b[n:]
   382  		}
   383  		*sp = s
   384  		out.n = n
   385  		return out, nil
   386  	}
   387  	{{- end}}
   388  	if wtyp != {{.WireType.Expr}} {
   389  		return out, errUnknown
   390  	}
   391  	{{template "Consume" .}}
   392  	if n < 0 {
   393  		return out, errDecode
   394  	}
   395  	*sp = append(*sp, {{.ToGoType}})
   396  	out.n = n
   397  	return out, nil
   398  }
   399  
   400  var coder{{.Name}}Slice = pointerCoderFuncs{
   401  	size:      size{{.Name}}Slice,
   402  	marshal:   append{{.Name}}Slice,
   403  	unmarshal: consume{{.Name}}Slice,
   404  	merge:     merge{{.GoType.PointerMethod}}Slice,
   405  }
   406  
   407  {{if or (eq .Name "Bytes") (eq .Name "String")}}
   408  // append{{.Name}}SliceValidateUTF8 encodes a []{{.GoType}} pointer as a repeated {{.Name}}.
   409  func append{{.Name}}SliceValidateUTF8(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
   410  	s := *p.{{.GoType.PointerMethod}}Slice()
   411  	for _, v := range s {
   412  		b = protowire.AppendVarint(b, f.wiretag)
   413  		{{template "Append" .}}
   414  		if !utf8.Valid{{if eq .Name "String"}}String{{end}}(v) {
   415  			return b, errInvalidUTF8{}
   416  		}
   417  	}
   418  	return b, nil
   419  }
   420  
   421  // consume{{.Name}}SliceValidateUTF8 wire decodes a []{{.GoType}} pointer as a repeated {{.Name}}.
   422  func consume{{.Name}}SliceValidateUTF8(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
   423  	if wtyp != {{.WireType.Expr}} {
   424  		return out, errUnknown
   425  	}
   426  	{{template "Consume" .}}
   427  	if n < 0 {
   428  		return out, errDecode
   429  	}
   430  	if !utf8.Valid(v) {
   431  		return out, errInvalidUTF8{}
   432  	}
   433  	sp := p.{{.GoType.PointerMethod}}Slice()
   434  	*sp = append(*sp, {{.ToGoType}})
   435  	out.n = n
   436  	return out, nil
   437  }
   438  
   439  var coder{{.Name}}SliceValidateUTF8 = pointerCoderFuncs{
   440  	size:      size{{.Name}}Slice,
   441  	marshal:   append{{.Name}}SliceValidateUTF8,
   442  	unmarshal: consume{{.Name}}SliceValidateUTF8,
   443  	merge:     merge{{.GoType.PointerMethod}}Slice,
   444  }
   445  {{end}}
   446  
   447  {{if or (eq .WireType "Varint") (eq .WireType "Fixed32") (eq .WireType "Fixed64")}}
   448  // size{{.Name}}PackedSlice returns the size of wire encoding a []{{.GoType}} pointer as a packed repeated {{.Name}}.
   449  func size{{.Name}}PackedSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
   450  	s := *p.{{.GoType.PointerMethod}}Slice()
   451  	if len(s) == 0 {
   452  		return 0
   453  	}
   454  	{{if .WireType.ConstSize -}}
   455  	n := len(s) * {{template "Size" .}}
   456  	{{- else -}}
   457  	n := 0
   458  	for _, v := range s {
   459  		n += {{template "Size" .}}
   460  	}
   461  	{{- end}}
   462  	return f.tagsize + protowire.SizeBytes(n)
   463  }
   464  
   465  // append{{.Name}}PackedSlice encodes a []{{.GoType}} pointer as a packed repeated {{.Name}}.
   466  func append{{.Name}}PackedSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
   467  	s := *p.{{.GoType.PointerMethod}}Slice()
   468  	if len(s) == 0 {
   469  		return b, nil
   470  	}
   471  	b = protowire.AppendVarint(b, f.wiretag)
   472  	{{if .WireType.ConstSize -}}
   473  	n := len(s) * {{template "Size" .}}
   474  	{{- else -}}
   475  	n := 0
   476  	for _, v := range s {
   477  		n += {{template "Size" .}}
   478  	}
   479  	{{- end}}
   480  	b = protowire.AppendVarint(b, uint64(n))
   481  	for _, v := range s {
   482  		{{template "Append" .}}
   483  	}
   484  	return b, nil
   485  }
   486  
   487  var coder{{.Name}}PackedSlice = pointerCoderFuncs{
   488  	size:      size{{.Name}}PackedSlice,
   489  	marshal:   append{{.Name}}PackedSlice,
   490  	unmarshal: consume{{.Name}}Slice,
   491  	merge:     merge{{.GoType.PointerMethod}}Slice,
   492  }
   493  {{end}}
   494  
   495  {{end -}}
   496  
   497  {{- if not .NoValueCodec}}
   498  // size{{.Name}}Value returns the size of wire encoding a {{.GoType}} value as a {{.Name}}.
   499  func size{{.Name}}Value(v protoreflect.Value, tagsize int, opts marshalOptions) int {
   500  	return tagsize + {{template "SizeValue" .}}
   501  }
   502  
   503  // append{{.Name}}Value encodes a {{.GoType}} value as a {{.Name}}.
   504  func append{{.Name}}Value(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
   505  	b = protowire.AppendVarint(b, wiretag)
   506  	{{template "AppendValue" .}}
   507  	return b, nil
   508  }
   509  
   510  // consume{{.Name}}Value decodes a {{.GoType}} value as a {{.Name}}.
   511  func consume{{.Name}}Value(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
   512  	if wtyp != {{.WireType.Expr}} {
   513  		return protoreflect.Value{}, out, errUnknown
   514  	}
   515  	{{template "Consume" .}}
   516  	if n < 0 {
   517  		return protoreflect.Value{}, out, errDecode
   518  	}
   519  	out.n = n
   520  	return {{.ToValue}}, out, nil
   521  }
   522  
   523  var coder{{.Name}}Value = valueCoderFuncs{
   524  	size:      size{{.Name}}Value,
   525  	marshal:   append{{.Name}}Value,
   526  	unmarshal: consume{{.Name}}Value,
   527  {{- if (eq .Name "Bytes")}}
   528  	merge:     mergeBytesValue,
   529  {{- else}}
   530  	merge:     mergeScalarValue,
   531  {{- end}}
   532  }
   533  
   534  {{if (eq .Name "String")}}
   535  // append{{.Name}}ValueValidateUTF8 encodes a {{.GoType}} value as a {{.Name}}.
   536  func append{{.Name}}ValueValidateUTF8(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
   537  	b = protowire.AppendVarint(b, wiretag)
   538  	{{template "AppendValue" .}}
   539  	if !utf8.ValidString({{.FromValue}}) {
   540  		return b, errInvalidUTF8{}
   541  	}
   542  	return b, nil
   543  }
   544  
   545  // consume{{.Name}}ValueValidateUTF8 decodes a {{.GoType}} value as a {{.Name}}.
   546  func consume{{.Name}}ValueValidateUTF8(b []byte, _ protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
   547  	if wtyp != {{.WireType.Expr}} {
   548  		return protoreflect.Value{}, out, errUnknown
   549  	}
   550  	{{template "Consume" .}}
   551  	if n < 0 {
   552  		return protoreflect.Value{}, out, errDecode
   553  	}
   554  	if !utf8.Valid(v) {
   555  		return protoreflect.Value{}, out, errInvalidUTF8{}
   556  	}
   557  	out.n = n
   558  	return {{.ToValue}}, out, nil
   559  }
   560  
   561  var coder{{.Name}}ValueValidateUTF8 = valueCoderFuncs{
   562  	size:      size{{.Name}}Value,
   563  	marshal:   append{{.Name}}ValueValidateUTF8,
   564  	unmarshal: consume{{.Name}}ValueValidateUTF8,
   565  	merge:     mergeScalarValue,
   566  }
   567  {{end}}
   568  
   569  // size{{.Name}}SliceValue returns the size of wire encoding a []{{.GoType}} value as a repeated {{.Name}}.
   570  func size{{.Name}}SliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) (size int) {
   571  	list := listv.List()
   572  	{{if .WireType.ConstSize -}}
   573  	size = list.Len() * (tagsize + {{template "SizeValue" .}})
   574  	{{- else -}}
   575  	for i, llen := 0, list.Len(); i < llen; i++ {
   576  		v := list.Get(i)
   577  		size += tagsize + {{template "SizeValue" .}}
   578  	}
   579  	{{- end}}
   580  	return size
   581  }
   582  
   583  // append{{.Name}}SliceValue encodes a []{{.GoType}} value as a repeated {{.Name}}.
   584  func append{{.Name}}SliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
   585  	list := listv.List()
   586  	for i, llen := 0, list.Len(); i < llen; i++ {
   587  		v := list.Get(i)
   588  		b = protowire.AppendVarint(b, wiretag)
   589  		{{template "AppendValue" .}}
   590  	}
   591  	return b, nil
   592  }
   593  
   594  // consume{{.Name}}SliceValue wire decodes a []{{.GoType}} value as a repeated {{.Name}}.
   595  func consume{{.Name}}SliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) {
   596  	list := listv.List()
   597  	{{- if .WireType.Packable}}
   598  	if wtyp == protowire.BytesType {
   599  		b, n := protowire.ConsumeBytes(b)
   600  		if n < 0 {
   601  			return protoreflect.Value{}, out, errDecode
   602  		}
   603  		for len(b) > 0 {
   604  			{{template "Consume" .}}
   605  			if n < 0 {
   606  				return protoreflect.Value{}, out, errDecode
   607  			}
   608  			list.Append({{.ToValue}})
   609  			b = b[n:]
   610  		}
   611  		out.n = n
   612  		return listv, out, nil
   613  	}
   614  	{{- end}}
   615  	if wtyp != {{.WireType.Expr}} {
   616  		return protoreflect.Value{}, out, errUnknown
   617  	}
   618  	{{template "Consume" .}}
   619  	if n < 0 {
   620  		return protoreflect.Value{}, out, errDecode
   621  	}
   622  	list.Append({{.ToValue}})
   623  	out.n = n
   624  	return listv, out, nil
   625  }
   626  
   627  var coder{{.Name}}SliceValue = valueCoderFuncs{
   628  	size:      size{{.Name}}SliceValue,
   629  	marshal:   append{{.Name}}SliceValue,
   630  	unmarshal: consume{{.Name}}SliceValue,
   631  {{- if (eq .Name "Bytes")}}
   632  	merge:     mergeBytesListValue,
   633  {{- else}}
   634  	merge:     mergeListValue,
   635  {{- end}}
   636  }
   637  
   638  {{if or (eq .WireType "Varint") (eq .WireType "Fixed32") (eq .WireType "Fixed64")}}
   639  // size{{.Name}}PackedSliceValue returns the size of wire encoding a []{{.GoType}} value as a packed repeated {{.Name}}.
   640  func size{{.Name}}PackedSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) (size int) {
   641  	list := listv.List()
   642  	llen := list.Len()
   643  	if llen == 0 {
   644  		return 0
   645  	}
   646  	{{if .WireType.ConstSize -}}
   647  	n := llen * {{template "SizeValue" .}}
   648  	{{- else -}}
   649  	n := 0
   650  	for i, llen := 0, llen; i < llen; i++ {
   651  		v := list.Get(i)
   652  		n += {{template "SizeValue" .}}
   653  	}
   654  	{{- end}}
   655  	return tagsize + protowire.SizeBytes(n)
   656  }
   657  
   658  // append{{.Name}}PackedSliceValue encodes a []{{.GoType}} value as a packed repeated {{.Name}}.
   659  func append{{.Name}}PackedSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
   660  	list := listv.List()
   661  	llen := list.Len()
   662  	if llen == 0 {
   663  		return b, nil
   664  	}
   665  	b = protowire.AppendVarint(b, wiretag)
   666  	{{if .WireType.ConstSize -}}
   667  	n := llen * {{template "SizeValue" .}}
   668  	{{- else -}}
   669  	n := 0
   670  	for i := 0; i < llen; i++ {
   671  		v := list.Get(i)
   672  		n += {{template "SizeValue" .}}
   673  	}
   674  	{{- end}}
   675  	b = protowire.AppendVarint(b, uint64(n))
   676  	for i := 0; i < llen; i++ {
   677  		v := list.Get(i)
   678  		{{template "AppendValue" .}}
   679  	}
   680  	return b, nil
   681  }
   682  
   683  var coder{{.Name}}PackedSliceValue = valueCoderFuncs{
   684  	size:      size{{.Name}}PackedSliceValue,
   685  	marshal:   append{{.Name}}PackedSliceValue,
   686  	unmarshal: consume{{.Name}}SliceValue,
   687  	merge:     mergeListValue,
   688  }
   689  {{end}}
   690  
   691  {{- end}}{{/* if not .NoValueCodec */}}
   692  
   693  {{end -}}
   694  
   695  // We append to an empty array rather than a nil []byte to get non-nil zero-length byte slices.
   696  var emptyBuf [0]byte
   697  
   698  var wireTypes = map[protoreflect.Kind]protowire.Type{
   699  {{range . -}}
   700  	protoreflect.{{.Name}}Kind: {{.WireType.Expr}},
   701  {{end}}
   702  }
   703  `))
   704  
   705  func generateImplMessage() string {
   706  	return mustExecute(implMessageTemplate, []string{"messageState", "messageReflectWrapper"})
   707  }
   708  
   709  var implMessageTemplate = template.Must(template.New("").Parse(`
   710  {{range . -}}
   711  func (m *{{.}}) Descriptor() protoreflect.MessageDescriptor {
   712  	return m.messageInfo().Desc
   713  }
   714  func (m *{{.}}) Type() protoreflect.MessageType {
   715  	return m.messageInfo()
   716  }
   717  func (m *{{.}}) New() protoreflect.Message {
   718  	return m.messageInfo().New()
   719  }
   720  func (m *{{.}}) Interface() protoreflect.ProtoMessage {
   721  	{{if eq . "messageState" -}}
   722  	return m.protoUnwrap().(protoreflect.ProtoMessage)
   723  	{{- else -}}
   724  	if m, ok := m.protoUnwrap().(protoreflect.ProtoMessage); ok {
   725  		return m
   726  	}
   727  	return (*messageIfaceWrapper)(m)
   728  	{{- end -}}
   729  }
   730  func (m *{{.}}) protoUnwrap() interface{} {
   731  	return m.pointer().AsIfaceOf(m.messageInfo().GoReflectType.Elem())
   732  }
   733  func (m *{{.}}) ProtoMethods() *protoiface.Methods {
   734  	m.messageInfo().init()
   735  	return &m.messageInfo().methods
   736  }
   737  
   738  // ProtoMessageInfo is a pseudo-internal API for allowing the v1 code
   739  // to be able to retrieve a v2 MessageInfo struct.
   740  //
   741  // WARNING: This method is exempt from the compatibility promise and
   742  // may be removed in the future without warning.
   743  func (m *{{.}}) ProtoMessageInfo() *MessageInfo {
   744  	return m.messageInfo()
   745  }
   746  
   747  func (m *{{.}}) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
   748  	m.messageInfo().init()
   749  	for _, ri := range m.messageInfo().rangeInfos {
   750  		switch ri := ri.(type) {
   751  		case *fieldInfo:
   752  			if ri.has(m.pointer()) {
   753  				if !f(ri.fieldDesc, ri.get(m.pointer())) {
   754  					return
   755  				}
   756  			}
   757  		case *oneofInfo:
   758  			if n := ri.which(m.pointer()); n > 0 {
   759  				fi := m.messageInfo().fields[n]
   760  				if !f(fi.fieldDesc, fi.get(m.pointer())) {
   761  					return
   762  				}
   763  			}
   764  		}
   765  	}
   766  	m.messageInfo().extensionMap(m.pointer()).Range(f)
   767  }
   768  func (m *{{.}}) Has(fd protoreflect.FieldDescriptor) bool {
   769  	m.messageInfo().init()
   770  	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
   771  		return fi.has(m.pointer())
   772  	} else {
   773  		return m.messageInfo().extensionMap(m.pointer()).Has(xt)
   774  	}
   775  }
   776  func (m *{{.}}) Clear(fd protoreflect.FieldDescriptor) {
   777  	m.messageInfo().init()
   778  	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
   779  		fi.clear(m.pointer())
   780  	} else {
   781  		m.messageInfo().extensionMap(m.pointer()).Clear(xt)
   782  	}
   783  }
   784  func (m *{{.}}) Get(fd protoreflect.FieldDescriptor) protoreflect.Value {
   785  	m.messageInfo().init()
   786  	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
   787  		return fi.get(m.pointer())
   788  	} else {
   789  		return m.messageInfo().extensionMap(m.pointer()).Get(xt)
   790  	}
   791  }
   792  func (m *{{.}}) Set(fd protoreflect.FieldDescriptor, v protoreflect.Value) {
   793  	m.messageInfo().init()
   794  	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
   795  		fi.set(m.pointer(), v)
   796  	} else {
   797  		m.messageInfo().extensionMap(m.pointer()).Set(xt, v)
   798  	}
   799  }
   800  func (m *{{.}}) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
   801  	m.messageInfo().init()
   802  	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
   803  		return fi.mutable(m.pointer())
   804  	} else {
   805  		return m.messageInfo().extensionMap(m.pointer()).Mutable(xt)
   806  	}
   807  }
   808  func (m *{{.}}) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
   809  	m.messageInfo().init()
   810  	if fi, xt := m.messageInfo().checkField(fd); fi != nil {
   811  		return fi.newField()
   812  	} else {
   813  		return xt.New()
   814  	}
   815  }
   816  func (m *{{.}}) WhichOneof(od protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
   817  	m.messageInfo().init()
   818  	if oi := m.messageInfo().oneofs[od.Name()]; oi != nil && oi.oneofDesc == od {
   819  		return od.Fields().ByNumber(oi.which(m.pointer()))
   820  	}
   821  	panic("invalid oneof descriptor " + string(od.FullName()) + " for message " + string(m.Descriptor().FullName()))
   822  }
   823  func (m *{{.}}) GetUnknown() protoreflect.RawFields {
   824  	m.messageInfo().init()
   825  	return m.messageInfo().getUnknown(m.pointer())
   826  }
   827  func (m *{{.}}) SetUnknown(b protoreflect.RawFields) {
   828  	m.messageInfo().init()
   829  	m.messageInfo().setUnknown(m.pointer(), b)
   830  }
   831  func (m *{{.}}) IsValid() bool {
   832  	return !m.pointer().IsNil()
   833  }
   834  
   835  {{end}}
   836  `))
   837  
   838  func generateImplMerge() string {
   839  	return mustExecute(implMergeTemplate, GoTypes)
   840  }
   841  
   842  var implMergeTemplate = template.Must(template.New("").Parse(`
   843  {{range .}}
   844  {{if ne . "[]byte"}}
   845  func merge{{.PointerMethod}}(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
   846  	*dst.{{.PointerMethod}}() = *src.{{.PointerMethod}}()
   847  }
   848  
   849  func merge{{.PointerMethod}}NoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
   850  	v := *src.{{.PointerMethod}}()
   851  	if v != {{.Zero}} {
   852  		*dst.{{.PointerMethod}}() = v
   853  	}
   854  }
   855  
   856  func merge{{.PointerMethod}}Ptr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
   857  	p := *src.{{.PointerMethod}}Ptr()
   858  	if p != nil {
   859  		v := *p
   860  		*dst.{{.PointerMethod}}Ptr() = &v
   861  	}
   862  }
   863  
   864  func merge{{.PointerMethod}}Slice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
   865  	ds := dst.{{.PointerMethod}}Slice()
   866  	ss := src.{{.PointerMethod}}Slice()
   867  	*ds = append(*ds, *ss...)
   868  }
   869  
   870  {{end}}
   871  {{end}}
   872  `))