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