...

Source file src/google.golang.org/protobuf/internal/cmd/generate-types/impl.go

Documentation: google.golang.org/protobuf/internal/cmd/generate-types

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

View as plain text