...

Source file src/google.golang.org/protobuf/internal/impl/codec_reflect.go

Documentation: google.golang.org/protobuf/internal/impl

     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  //go:build purego || appengine
     6  // +build purego appengine
     7  
     8  package impl
     9  
    10  import (
    11  	"reflect"
    12  
    13  	"google.golang.org/protobuf/encoding/protowire"
    14  )
    15  
    16  func sizeEnum(p pointer, f *coderFieldInfo, _ marshalOptions) (size int) {
    17  	v := p.v.Elem().Int()
    18  	return f.tagsize + protowire.SizeVarint(uint64(v))
    19  }
    20  
    21  func appendEnum(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
    22  	v := p.v.Elem().Int()
    23  	b = protowire.AppendVarint(b, f.wiretag)
    24  	b = protowire.AppendVarint(b, uint64(v))
    25  	return b, nil
    26  }
    27  
    28  func consumeEnum(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, _ unmarshalOptions) (out unmarshalOutput, err error) {
    29  	if wtyp != protowire.VarintType {
    30  		return out, errUnknown
    31  	}
    32  	v, n := protowire.ConsumeVarint(b)
    33  	if n < 0 {
    34  		return out, errDecode
    35  	}
    36  	p.v.Elem().SetInt(int64(v))
    37  	out.n = n
    38  	return out, nil
    39  }
    40  
    41  func mergeEnum(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
    42  	dst.v.Elem().Set(src.v.Elem())
    43  }
    44  
    45  var coderEnum = pointerCoderFuncs{
    46  	size:      sizeEnum,
    47  	marshal:   appendEnum,
    48  	unmarshal: consumeEnum,
    49  	merge:     mergeEnum,
    50  }
    51  
    52  func sizeEnumNoZero(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
    53  	if p.v.Elem().Int() == 0 {
    54  		return 0
    55  	}
    56  	return sizeEnum(p, f, opts)
    57  }
    58  
    59  func appendEnumNoZero(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
    60  	if p.v.Elem().Int() == 0 {
    61  		return b, nil
    62  	}
    63  	return appendEnum(b, p, f, opts)
    64  }
    65  
    66  func mergeEnumNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
    67  	if src.v.Elem().Int() != 0 {
    68  		dst.v.Elem().Set(src.v.Elem())
    69  	}
    70  }
    71  
    72  var coderEnumNoZero = pointerCoderFuncs{
    73  	size:      sizeEnumNoZero,
    74  	marshal:   appendEnumNoZero,
    75  	unmarshal: consumeEnum,
    76  	merge:     mergeEnumNoZero,
    77  }
    78  
    79  func sizeEnumPtr(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
    80  	return sizeEnum(pointer{p.v.Elem()}, f, opts)
    81  }
    82  
    83  func appendEnumPtr(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
    84  	return appendEnum(b, pointer{p.v.Elem()}, f, opts)
    85  }
    86  
    87  func consumeEnumPtr(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
    88  	if wtyp != protowire.VarintType {
    89  		return out, errUnknown
    90  	}
    91  	if p.v.Elem().IsNil() {
    92  		p.v.Elem().Set(reflect.New(p.v.Elem().Type().Elem()))
    93  	}
    94  	return consumeEnum(b, pointer{p.v.Elem()}, wtyp, f, opts)
    95  }
    96  
    97  func mergeEnumPtr(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
    98  	if !src.v.Elem().IsNil() {
    99  		v := reflect.New(dst.v.Type().Elem().Elem())
   100  		v.Elem().Set(src.v.Elem().Elem())
   101  		dst.v.Elem().Set(v)
   102  	}
   103  }
   104  
   105  var coderEnumPtr = pointerCoderFuncs{
   106  	size:      sizeEnumPtr,
   107  	marshal:   appendEnumPtr,
   108  	unmarshal: consumeEnumPtr,
   109  	merge:     mergeEnumPtr,
   110  }
   111  
   112  func sizeEnumSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
   113  	s := p.v.Elem()
   114  	for i, llen := 0, s.Len(); i < llen; i++ {
   115  		size += protowire.SizeVarint(uint64(s.Index(i).Int())) + f.tagsize
   116  	}
   117  	return size
   118  }
   119  
   120  func appendEnumSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
   121  	s := p.v.Elem()
   122  	for i, llen := 0, s.Len(); i < llen; i++ {
   123  		b = protowire.AppendVarint(b, f.wiretag)
   124  		b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
   125  	}
   126  	return b, nil
   127  }
   128  
   129  func consumeEnumSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) {
   130  	s := p.v.Elem()
   131  	if wtyp == protowire.BytesType {
   132  		b, n := protowire.ConsumeBytes(b)
   133  		if n < 0 {
   134  			return out, errDecode
   135  		}
   136  		for len(b) > 0 {
   137  			v, n := protowire.ConsumeVarint(b)
   138  			if n < 0 {
   139  				return out, errDecode
   140  			}
   141  			rv := reflect.New(s.Type().Elem()).Elem()
   142  			rv.SetInt(int64(v))
   143  			s.Set(reflect.Append(s, rv))
   144  			b = b[n:]
   145  		}
   146  		out.n = n
   147  		return out, nil
   148  	}
   149  	if wtyp != protowire.VarintType {
   150  		return out, errUnknown
   151  	}
   152  	v, n := protowire.ConsumeVarint(b)
   153  	if n < 0 {
   154  		return out, errDecode
   155  	}
   156  	rv := reflect.New(s.Type().Elem()).Elem()
   157  	rv.SetInt(int64(v))
   158  	s.Set(reflect.Append(s, rv))
   159  	out.n = n
   160  	return out, nil
   161  }
   162  
   163  func mergeEnumSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
   164  	dst.v.Elem().Set(reflect.AppendSlice(dst.v.Elem(), src.v.Elem()))
   165  }
   166  
   167  var coderEnumSlice = pointerCoderFuncs{
   168  	size:      sizeEnumSlice,
   169  	marshal:   appendEnumSlice,
   170  	unmarshal: consumeEnumSlice,
   171  	merge:     mergeEnumSlice,
   172  }
   173  
   174  func sizeEnumPackedSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) {
   175  	s := p.v.Elem()
   176  	llen := s.Len()
   177  	if llen == 0 {
   178  		return 0
   179  	}
   180  	n := 0
   181  	for i := 0; i < llen; i++ {
   182  		n += protowire.SizeVarint(uint64(s.Index(i).Int()))
   183  	}
   184  	return f.tagsize + protowire.SizeBytes(n)
   185  }
   186  
   187  func appendEnumPackedSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) {
   188  	s := p.v.Elem()
   189  	llen := s.Len()
   190  	if llen == 0 {
   191  		return b, nil
   192  	}
   193  	b = protowire.AppendVarint(b, f.wiretag)
   194  	n := 0
   195  	for i := 0; i < llen; i++ {
   196  		n += protowire.SizeVarint(uint64(s.Index(i).Int()))
   197  	}
   198  	b = protowire.AppendVarint(b, uint64(n))
   199  	for i := 0; i < llen; i++ {
   200  		b = protowire.AppendVarint(b, uint64(s.Index(i).Int()))
   201  	}
   202  	return b, nil
   203  }
   204  
   205  var coderEnumPackedSlice = pointerCoderFuncs{
   206  	size:      sizeEnumPackedSlice,
   207  	marshal:   appendEnumPackedSlice,
   208  	unmarshal: consumeEnumSlice,
   209  	merge:     mergeEnumSlice,
   210  }
   211  

View as plain text