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 Willemsenpackage impl 6*1c12ee1eSDan Willemsen 7*1c12ee1eSDan Willemsenimport ( 8*1c12ee1eSDan Willemsen "fmt" 9*1c12ee1eSDan Willemsen "reflect" 10*1c12ee1eSDan Willemsen 11*1c12ee1eSDan Willemsen "google.golang.org/protobuf/encoding/protowire" 12*1c12ee1eSDan Willemsen "google.golang.org/protobuf/internal/strs" 13*1c12ee1eSDan Willemsen "google.golang.org/protobuf/reflect/protoreflect" 14*1c12ee1eSDan Willemsen) 15*1c12ee1eSDan Willemsen 16*1c12ee1eSDan Willemsen// pointerCoderFuncs is a set of pointer encoding functions. 17*1c12ee1eSDan Willemsentype pointerCoderFuncs struct { 18*1c12ee1eSDan Willemsen mi *MessageInfo 19*1c12ee1eSDan Willemsen size func(p pointer, f *coderFieldInfo, opts marshalOptions) int 20*1c12ee1eSDan Willemsen marshal func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) 21*1c12ee1eSDan Willemsen unmarshal func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) 22*1c12ee1eSDan Willemsen isInit func(p pointer, f *coderFieldInfo) error 23*1c12ee1eSDan Willemsen merge func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) 24*1c12ee1eSDan Willemsen} 25*1c12ee1eSDan Willemsen 26*1c12ee1eSDan Willemsen// valueCoderFuncs is a set of protoreflect.Value encoding functions. 27*1c12ee1eSDan Willemsentype valueCoderFuncs struct { 28*1c12ee1eSDan Willemsen size func(v protoreflect.Value, tagsize int, opts marshalOptions) int 29*1c12ee1eSDan Willemsen marshal func(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) 30*1c12ee1eSDan Willemsen unmarshal func(b []byte, v protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) 31*1c12ee1eSDan Willemsen isInit func(v protoreflect.Value) error 32*1c12ee1eSDan Willemsen merge func(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value 33*1c12ee1eSDan Willemsen} 34*1c12ee1eSDan Willemsen 35*1c12ee1eSDan Willemsen// fieldCoder returns pointer functions for a field, used for operating on 36*1c12ee1eSDan Willemsen// struct fields. 37*1c12ee1eSDan Willemsenfunc fieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) { 38*1c12ee1eSDan Willemsen switch { 39*1c12ee1eSDan Willemsen case fd.IsMap(): 40*1c12ee1eSDan Willemsen return encoderFuncsForMap(fd, ft) 41*1c12ee1eSDan Willemsen case fd.Cardinality() == protoreflect.Repeated && !fd.IsPacked(): 42*1c12ee1eSDan Willemsen // Repeated fields (not packed). 43*1c12ee1eSDan Willemsen if ft.Kind() != reflect.Slice { 44*1c12ee1eSDan Willemsen break 45*1c12ee1eSDan Willemsen } 46*1c12ee1eSDan Willemsen ft := ft.Elem() 47*1c12ee1eSDan Willemsen switch fd.Kind() { 48*1c12ee1eSDan Willemsen case protoreflect.BoolKind: 49*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Bool { 50*1c12ee1eSDan Willemsen return nil, coderBoolSlice 51*1c12ee1eSDan Willemsen } 52*1c12ee1eSDan Willemsen case protoreflect.EnumKind: 53*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 54*1c12ee1eSDan Willemsen return nil, coderEnumSlice 55*1c12ee1eSDan Willemsen } 56*1c12ee1eSDan Willemsen case protoreflect.Int32Kind: 57*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 58*1c12ee1eSDan Willemsen return nil, coderInt32Slice 59*1c12ee1eSDan Willemsen } 60*1c12ee1eSDan Willemsen case protoreflect.Sint32Kind: 61*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 62*1c12ee1eSDan Willemsen return nil, coderSint32Slice 63*1c12ee1eSDan Willemsen } 64*1c12ee1eSDan Willemsen case protoreflect.Uint32Kind: 65*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint32 { 66*1c12ee1eSDan Willemsen return nil, coderUint32Slice 67*1c12ee1eSDan Willemsen } 68*1c12ee1eSDan Willemsen case protoreflect.Int64Kind: 69*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 70*1c12ee1eSDan Willemsen return nil, coderInt64Slice 71*1c12ee1eSDan Willemsen } 72*1c12ee1eSDan Willemsen case protoreflect.Sint64Kind: 73*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 74*1c12ee1eSDan Willemsen return nil, coderSint64Slice 75*1c12ee1eSDan Willemsen } 76*1c12ee1eSDan Willemsen case protoreflect.Uint64Kind: 77*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint64 { 78*1c12ee1eSDan Willemsen return nil, coderUint64Slice 79*1c12ee1eSDan Willemsen } 80*1c12ee1eSDan Willemsen case protoreflect.Sfixed32Kind: 81*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 82*1c12ee1eSDan Willemsen return nil, coderSfixed32Slice 83*1c12ee1eSDan Willemsen } 84*1c12ee1eSDan Willemsen case protoreflect.Fixed32Kind: 85*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint32 { 86*1c12ee1eSDan Willemsen return nil, coderFixed32Slice 87*1c12ee1eSDan Willemsen } 88*1c12ee1eSDan Willemsen case protoreflect.FloatKind: 89*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Float32 { 90*1c12ee1eSDan Willemsen return nil, coderFloatSlice 91*1c12ee1eSDan Willemsen } 92*1c12ee1eSDan Willemsen case protoreflect.Sfixed64Kind: 93*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 94*1c12ee1eSDan Willemsen return nil, coderSfixed64Slice 95*1c12ee1eSDan Willemsen } 96*1c12ee1eSDan Willemsen case protoreflect.Fixed64Kind: 97*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint64 { 98*1c12ee1eSDan Willemsen return nil, coderFixed64Slice 99*1c12ee1eSDan Willemsen } 100*1c12ee1eSDan Willemsen case protoreflect.DoubleKind: 101*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Float64 { 102*1c12ee1eSDan Willemsen return nil, coderDoubleSlice 103*1c12ee1eSDan Willemsen } 104*1c12ee1eSDan Willemsen case protoreflect.StringKind: 105*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { 106*1c12ee1eSDan Willemsen return nil, coderStringSliceValidateUTF8 107*1c12ee1eSDan Willemsen } 108*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String { 109*1c12ee1eSDan Willemsen return nil, coderStringSlice 110*1c12ee1eSDan Willemsen } 111*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) { 112*1c12ee1eSDan Willemsen return nil, coderBytesSliceValidateUTF8 113*1c12ee1eSDan Willemsen } 114*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { 115*1c12ee1eSDan Willemsen return nil, coderBytesSlice 116*1c12ee1eSDan Willemsen } 117*1c12ee1eSDan Willemsen case protoreflect.BytesKind: 118*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String { 119*1c12ee1eSDan Willemsen return nil, coderStringSlice 120*1c12ee1eSDan Willemsen } 121*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { 122*1c12ee1eSDan Willemsen return nil, coderBytesSlice 123*1c12ee1eSDan Willemsen } 124*1c12ee1eSDan Willemsen case protoreflect.MessageKind: 125*1c12ee1eSDan Willemsen return getMessageInfo(ft), makeMessageSliceFieldCoder(fd, ft) 126*1c12ee1eSDan Willemsen case protoreflect.GroupKind: 127*1c12ee1eSDan Willemsen return getMessageInfo(ft), makeGroupSliceFieldCoder(fd, ft) 128*1c12ee1eSDan Willemsen } 129*1c12ee1eSDan Willemsen case fd.Cardinality() == protoreflect.Repeated && fd.IsPacked(): 130*1c12ee1eSDan Willemsen // Packed repeated fields. 131*1c12ee1eSDan Willemsen // 132*1c12ee1eSDan Willemsen // Only repeated fields of primitive numeric types 133*1c12ee1eSDan Willemsen // (Varint, Fixed32, or Fixed64 wire type) can be packed. 134*1c12ee1eSDan Willemsen if ft.Kind() != reflect.Slice { 135*1c12ee1eSDan Willemsen break 136*1c12ee1eSDan Willemsen } 137*1c12ee1eSDan Willemsen ft := ft.Elem() 138*1c12ee1eSDan Willemsen switch fd.Kind() { 139*1c12ee1eSDan Willemsen case protoreflect.BoolKind: 140*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Bool { 141*1c12ee1eSDan Willemsen return nil, coderBoolPackedSlice 142*1c12ee1eSDan Willemsen } 143*1c12ee1eSDan Willemsen case protoreflect.EnumKind: 144*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 145*1c12ee1eSDan Willemsen return nil, coderEnumPackedSlice 146*1c12ee1eSDan Willemsen } 147*1c12ee1eSDan Willemsen case protoreflect.Int32Kind: 148*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 149*1c12ee1eSDan Willemsen return nil, coderInt32PackedSlice 150*1c12ee1eSDan Willemsen } 151*1c12ee1eSDan Willemsen case protoreflect.Sint32Kind: 152*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 153*1c12ee1eSDan Willemsen return nil, coderSint32PackedSlice 154*1c12ee1eSDan Willemsen } 155*1c12ee1eSDan Willemsen case protoreflect.Uint32Kind: 156*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint32 { 157*1c12ee1eSDan Willemsen return nil, coderUint32PackedSlice 158*1c12ee1eSDan Willemsen } 159*1c12ee1eSDan Willemsen case protoreflect.Int64Kind: 160*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 161*1c12ee1eSDan Willemsen return nil, coderInt64PackedSlice 162*1c12ee1eSDan Willemsen } 163*1c12ee1eSDan Willemsen case protoreflect.Sint64Kind: 164*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 165*1c12ee1eSDan Willemsen return nil, coderSint64PackedSlice 166*1c12ee1eSDan Willemsen } 167*1c12ee1eSDan Willemsen case protoreflect.Uint64Kind: 168*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint64 { 169*1c12ee1eSDan Willemsen return nil, coderUint64PackedSlice 170*1c12ee1eSDan Willemsen } 171*1c12ee1eSDan Willemsen case protoreflect.Sfixed32Kind: 172*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 173*1c12ee1eSDan Willemsen return nil, coderSfixed32PackedSlice 174*1c12ee1eSDan Willemsen } 175*1c12ee1eSDan Willemsen case protoreflect.Fixed32Kind: 176*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint32 { 177*1c12ee1eSDan Willemsen return nil, coderFixed32PackedSlice 178*1c12ee1eSDan Willemsen } 179*1c12ee1eSDan Willemsen case protoreflect.FloatKind: 180*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Float32 { 181*1c12ee1eSDan Willemsen return nil, coderFloatPackedSlice 182*1c12ee1eSDan Willemsen } 183*1c12ee1eSDan Willemsen case protoreflect.Sfixed64Kind: 184*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 185*1c12ee1eSDan Willemsen return nil, coderSfixed64PackedSlice 186*1c12ee1eSDan Willemsen } 187*1c12ee1eSDan Willemsen case protoreflect.Fixed64Kind: 188*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint64 { 189*1c12ee1eSDan Willemsen return nil, coderFixed64PackedSlice 190*1c12ee1eSDan Willemsen } 191*1c12ee1eSDan Willemsen case protoreflect.DoubleKind: 192*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Float64 { 193*1c12ee1eSDan Willemsen return nil, coderDoublePackedSlice 194*1c12ee1eSDan Willemsen } 195*1c12ee1eSDan Willemsen } 196*1c12ee1eSDan Willemsen case fd.Kind() == protoreflect.MessageKind: 197*1c12ee1eSDan Willemsen return getMessageInfo(ft), makeMessageFieldCoder(fd, ft) 198*1c12ee1eSDan Willemsen case fd.Kind() == protoreflect.GroupKind: 199*1c12ee1eSDan Willemsen return getMessageInfo(ft), makeGroupFieldCoder(fd, ft) 200*1c12ee1eSDan Willemsen case fd.Syntax() == protoreflect.Proto3 && fd.ContainingOneof() == nil: 201*1c12ee1eSDan Willemsen // Populated oneof fields always encode even if set to the zero value, 202*1c12ee1eSDan Willemsen // which normally are not encoded in proto3. 203*1c12ee1eSDan Willemsen switch fd.Kind() { 204*1c12ee1eSDan Willemsen case protoreflect.BoolKind: 205*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Bool { 206*1c12ee1eSDan Willemsen return nil, coderBoolNoZero 207*1c12ee1eSDan Willemsen } 208*1c12ee1eSDan Willemsen case protoreflect.EnumKind: 209*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 210*1c12ee1eSDan Willemsen return nil, coderEnumNoZero 211*1c12ee1eSDan Willemsen } 212*1c12ee1eSDan Willemsen case protoreflect.Int32Kind: 213*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 214*1c12ee1eSDan Willemsen return nil, coderInt32NoZero 215*1c12ee1eSDan Willemsen } 216*1c12ee1eSDan Willemsen case protoreflect.Sint32Kind: 217*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 218*1c12ee1eSDan Willemsen return nil, coderSint32NoZero 219*1c12ee1eSDan Willemsen } 220*1c12ee1eSDan Willemsen case protoreflect.Uint32Kind: 221*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint32 { 222*1c12ee1eSDan Willemsen return nil, coderUint32NoZero 223*1c12ee1eSDan Willemsen } 224*1c12ee1eSDan Willemsen case protoreflect.Int64Kind: 225*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 226*1c12ee1eSDan Willemsen return nil, coderInt64NoZero 227*1c12ee1eSDan Willemsen } 228*1c12ee1eSDan Willemsen case protoreflect.Sint64Kind: 229*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 230*1c12ee1eSDan Willemsen return nil, coderSint64NoZero 231*1c12ee1eSDan Willemsen } 232*1c12ee1eSDan Willemsen case protoreflect.Uint64Kind: 233*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint64 { 234*1c12ee1eSDan Willemsen return nil, coderUint64NoZero 235*1c12ee1eSDan Willemsen } 236*1c12ee1eSDan Willemsen case protoreflect.Sfixed32Kind: 237*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 238*1c12ee1eSDan Willemsen return nil, coderSfixed32NoZero 239*1c12ee1eSDan Willemsen } 240*1c12ee1eSDan Willemsen case protoreflect.Fixed32Kind: 241*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint32 { 242*1c12ee1eSDan Willemsen return nil, coderFixed32NoZero 243*1c12ee1eSDan Willemsen } 244*1c12ee1eSDan Willemsen case protoreflect.FloatKind: 245*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Float32 { 246*1c12ee1eSDan Willemsen return nil, coderFloatNoZero 247*1c12ee1eSDan Willemsen } 248*1c12ee1eSDan Willemsen case protoreflect.Sfixed64Kind: 249*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 250*1c12ee1eSDan Willemsen return nil, coderSfixed64NoZero 251*1c12ee1eSDan Willemsen } 252*1c12ee1eSDan Willemsen case protoreflect.Fixed64Kind: 253*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint64 { 254*1c12ee1eSDan Willemsen return nil, coderFixed64NoZero 255*1c12ee1eSDan Willemsen } 256*1c12ee1eSDan Willemsen case protoreflect.DoubleKind: 257*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Float64 { 258*1c12ee1eSDan Willemsen return nil, coderDoubleNoZero 259*1c12ee1eSDan Willemsen } 260*1c12ee1eSDan Willemsen case protoreflect.StringKind: 261*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { 262*1c12ee1eSDan Willemsen return nil, coderStringNoZeroValidateUTF8 263*1c12ee1eSDan Willemsen } 264*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String { 265*1c12ee1eSDan Willemsen return nil, coderStringNoZero 266*1c12ee1eSDan Willemsen } 267*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) { 268*1c12ee1eSDan Willemsen return nil, coderBytesNoZeroValidateUTF8 269*1c12ee1eSDan Willemsen } 270*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { 271*1c12ee1eSDan Willemsen return nil, coderBytesNoZero 272*1c12ee1eSDan Willemsen } 273*1c12ee1eSDan Willemsen case protoreflect.BytesKind: 274*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String { 275*1c12ee1eSDan Willemsen return nil, coderStringNoZero 276*1c12ee1eSDan Willemsen } 277*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { 278*1c12ee1eSDan Willemsen return nil, coderBytesNoZero 279*1c12ee1eSDan Willemsen } 280*1c12ee1eSDan Willemsen } 281*1c12ee1eSDan Willemsen case ft.Kind() == reflect.Ptr: 282*1c12ee1eSDan Willemsen ft := ft.Elem() 283*1c12ee1eSDan Willemsen switch fd.Kind() { 284*1c12ee1eSDan Willemsen case protoreflect.BoolKind: 285*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Bool { 286*1c12ee1eSDan Willemsen return nil, coderBoolPtr 287*1c12ee1eSDan Willemsen } 288*1c12ee1eSDan Willemsen case protoreflect.EnumKind: 289*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 290*1c12ee1eSDan Willemsen return nil, coderEnumPtr 291*1c12ee1eSDan Willemsen } 292*1c12ee1eSDan Willemsen case protoreflect.Int32Kind: 293*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 294*1c12ee1eSDan Willemsen return nil, coderInt32Ptr 295*1c12ee1eSDan Willemsen } 296*1c12ee1eSDan Willemsen case protoreflect.Sint32Kind: 297*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 298*1c12ee1eSDan Willemsen return nil, coderSint32Ptr 299*1c12ee1eSDan Willemsen } 300*1c12ee1eSDan Willemsen case protoreflect.Uint32Kind: 301*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint32 { 302*1c12ee1eSDan Willemsen return nil, coderUint32Ptr 303*1c12ee1eSDan Willemsen } 304*1c12ee1eSDan Willemsen case protoreflect.Int64Kind: 305*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 306*1c12ee1eSDan Willemsen return nil, coderInt64Ptr 307*1c12ee1eSDan Willemsen } 308*1c12ee1eSDan Willemsen case protoreflect.Sint64Kind: 309*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 310*1c12ee1eSDan Willemsen return nil, coderSint64Ptr 311*1c12ee1eSDan Willemsen } 312*1c12ee1eSDan Willemsen case protoreflect.Uint64Kind: 313*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint64 { 314*1c12ee1eSDan Willemsen return nil, coderUint64Ptr 315*1c12ee1eSDan Willemsen } 316*1c12ee1eSDan Willemsen case protoreflect.Sfixed32Kind: 317*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 318*1c12ee1eSDan Willemsen return nil, coderSfixed32Ptr 319*1c12ee1eSDan Willemsen } 320*1c12ee1eSDan Willemsen case protoreflect.Fixed32Kind: 321*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint32 { 322*1c12ee1eSDan Willemsen return nil, coderFixed32Ptr 323*1c12ee1eSDan Willemsen } 324*1c12ee1eSDan Willemsen case protoreflect.FloatKind: 325*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Float32 { 326*1c12ee1eSDan Willemsen return nil, coderFloatPtr 327*1c12ee1eSDan Willemsen } 328*1c12ee1eSDan Willemsen case protoreflect.Sfixed64Kind: 329*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 330*1c12ee1eSDan Willemsen return nil, coderSfixed64Ptr 331*1c12ee1eSDan Willemsen } 332*1c12ee1eSDan Willemsen case protoreflect.Fixed64Kind: 333*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint64 { 334*1c12ee1eSDan Willemsen return nil, coderFixed64Ptr 335*1c12ee1eSDan Willemsen } 336*1c12ee1eSDan Willemsen case protoreflect.DoubleKind: 337*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Float64 { 338*1c12ee1eSDan Willemsen return nil, coderDoublePtr 339*1c12ee1eSDan Willemsen } 340*1c12ee1eSDan Willemsen case protoreflect.StringKind: 341*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { 342*1c12ee1eSDan Willemsen return nil, coderStringPtrValidateUTF8 343*1c12ee1eSDan Willemsen } 344*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String { 345*1c12ee1eSDan Willemsen return nil, coderStringPtr 346*1c12ee1eSDan Willemsen } 347*1c12ee1eSDan Willemsen case protoreflect.BytesKind: 348*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String { 349*1c12ee1eSDan Willemsen return nil, coderStringPtr 350*1c12ee1eSDan Willemsen } 351*1c12ee1eSDan Willemsen } 352*1c12ee1eSDan Willemsen default: 353*1c12ee1eSDan Willemsen switch fd.Kind() { 354*1c12ee1eSDan Willemsen case protoreflect.BoolKind: 355*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Bool { 356*1c12ee1eSDan Willemsen return nil, coderBool 357*1c12ee1eSDan Willemsen } 358*1c12ee1eSDan Willemsen case protoreflect.EnumKind: 359*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 360*1c12ee1eSDan Willemsen return nil, coderEnum 361*1c12ee1eSDan Willemsen } 362*1c12ee1eSDan Willemsen case protoreflect.Int32Kind: 363*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 364*1c12ee1eSDan Willemsen return nil, coderInt32 365*1c12ee1eSDan Willemsen } 366*1c12ee1eSDan Willemsen case protoreflect.Sint32Kind: 367*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 368*1c12ee1eSDan Willemsen return nil, coderSint32 369*1c12ee1eSDan Willemsen } 370*1c12ee1eSDan Willemsen case protoreflect.Uint32Kind: 371*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint32 { 372*1c12ee1eSDan Willemsen return nil, coderUint32 373*1c12ee1eSDan Willemsen } 374*1c12ee1eSDan Willemsen case protoreflect.Int64Kind: 375*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 376*1c12ee1eSDan Willemsen return nil, coderInt64 377*1c12ee1eSDan Willemsen } 378*1c12ee1eSDan Willemsen case protoreflect.Sint64Kind: 379*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 380*1c12ee1eSDan Willemsen return nil, coderSint64 381*1c12ee1eSDan Willemsen } 382*1c12ee1eSDan Willemsen case protoreflect.Uint64Kind: 383*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint64 { 384*1c12ee1eSDan Willemsen return nil, coderUint64 385*1c12ee1eSDan Willemsen } 386*1c12ee1eSDan Willemsen case protoreflect.Sfixed32Kind: 387*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int32 { 388*1c12ee1eSDan Willemsen return nil, coderSfixed32 389*1c12ee1eSDan Willemsen } 390*1c12ee1eSDan Willemsen case protoreflect.Fixed32Kind: 391*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint32 { 392*1c12ee1eSDan Willemsen return nil, coderFixed32 393*1c12ee1eSDan Willemsen } 394*1c12ee1eSDan Willemsen case protoreflect.FloatKind: 395*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Float32 { 396*1c12ee1eSDan Willemsen return nil, coderFloat 397*1c12ee1eSDan Willemsen } 398*1c12ee1eSDan Willemsen case protoreflect.Sfixed64Kind: 399*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Int64 { 400*1c12ee1eSDan Willemsen return nil, coderSfixed64 401*1c12ee1eSDan Willemsen } 402*1c12ee1eSDan Willemsen case protoreflect.Fixed64Kind: 403*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Uint64 { 404*1c12ee1eSDan Willemsen return nil, coderFixed64 405*1c12ee1eSDan Willemsen } 406*1c12ee1eSDan Willemsen case protoreflect.DoubleKind: 407*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Float64 { 408*1c12ee1eSDan Willemsen return nil, coderDouble 409*1c12ee1eSDan Willemsen } 410*1c12ee1eSDan Willemsen case protoreflect.StringKind: 411*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { 412*1c12ee1eSDan Willemsen return nil, coderStringValidateUTF8 413*1c12ee1eSDan Willemsen } 414*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String { 415*1c12ee1eSDan Willemsen return nil, coderString 416*1c12ee1eSDan Willemsen } 417*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 && strs.EnforceUTF8(fd) { 418*1c12ee1eSDan Willemsen return nil, coderBytesValidateUTF8 419*1c12ee1eSDan Willemsen } 420*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { 421*1c12ee1eSDan Willemsen return nil, coderBytes 422*1c12ee1eSDan Willemsen } 423*1c12ee1eSDan Willemsen case protoreflect.BytesKind: 424*1c12ee1eSDan Willemsen if ft.Kind() == reflect.String { 425*1c12ee1eSDan Willemsen return nil, coderString 426*1c12ee1eSDan Willemsen } 427*1c12ee1eSDan Willemsen if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { 428*1c12ee1eSDan Willemsen return nil, coderBytes 429*1c12ee1eSDan Willemsen } 430*1c12ee1eSDan Willemsen } 431*1c12ee1eSDan Willemsen } 432*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft)) 433*1c12ee1eSDan Willemsen} 434*1c12ee1eSDan Willemsen 435*1c12ee1eSDan Willemsen// encoderFuncsForValue returns value functions for a field, used for 436*1c12ee1eSDan Willemsen// extension values and map encoding. 437*1c12ee1eSDan Willemsenfunc encoderFuncsForValue(fd protoreflect.FieldDescriptor) valueCoderFuncs { 438*1c12ee1eSDan Willemsen switch { 439*1c12ee1eSDan Willemsen case fd.Cardinality() == protoreflect.Repeated && !fd.IsPacked(): 440*1c12ee1eSDan Willemsen switch fd.Kind() { 441*1c12ee1eSDan Willemsen case protoreflect.BoolKind: 442*1c12ee1eSDan Willemsen return coderBoolSliceValue 443*1c12ee1eSDan Willemsen case protoreflect.EnumKind: 444*1c12ee1eSDan Willemsen return coderEnumSliceValue 445*1c12ee1eSDan Willemsen case protoreflect.Int32Kind: 446*1c12ee1eSDan Willemsen return coderInt32SliceValue 447*1c12ee1eSDan Willemsen case protoreflect.Sint32Kind: 448*1c12ee1eSDan Willemsen return coderSint32SliceValue 449*1c12ee1eSDan Willemsen case protoreflect.Uint32Kind: 450*1c12ee1eSDan Willemsen return coderUint32SliceValue 451*1c12ee1eSDan Willemsen case protoreflect.Int64Kind: 452*1c12ee1eSDan Willemsen return coderInt64SliceValue 453*1c12ee1eSDan Willemsen case protoreflect.Sint64Kind: 454*1c12ee1eSDan Willemsen return coderSint64SliceValue 455*1c12ee1eSDan Willemsen case protoreflect.Uint64Kind: 456*1c12ee1eSDan Willemsen return coderUint64SliceValue 457*1c12ee1eSDan Willemsen case protoreflect.Sfixed32Kind: 458*1c12ee1eSDan Willemsen return coderSfixed32SliceValue 459*1c12ee1eSDan Willemsen case protoreflect.Fixed32Kind: 460*1c12ee1eSDan Willemsen return coderFixed32SliceValue 461*1c12ee1eSDan Willemsen case protoreflect.FloatKind: 462*1c12ee1eSDan Willemsen return coderFloatSliceValue 463*1c12ee1eSDan Willemsen case protoreflect.Sfixed64Kind: 464*1c12ee1eSDan Willemsen return coderSfixed64SliceValue 465*1c12ee1eSDan Willemsen case protoreflect.Fixed64Kind: 466*1c12ee1eSDan Willemsen return coderFixed64SliceValue 467*1c12ee1eSDan Willemsen case protoreflect.DoubleKind: 468*1c12ee1eSDan Willemsen return coderDoubleSliceValue 469*1c12ee1eSDan Willemsen case protoreflect.StringKind: 470*1c12ee1eSDan Willemsen // We don't have a UTF-8 validating coder for repeated string fields. 471*1c12ee1eSDan Willemsen // Value coders are used for extensions and maps. 472*1c12ee1eSDan Willemsen // Extensions are never proto3, and maps never contain lists. 473*1c12ee1eSDan Willemsen return coderStringSliceValue 474*1c12ee1eSDan Willemsen case protoreflect.BytesKind: 475*1c12ee1eSDan Willemsen return coderBytesSliceValue 476*1c12ee1eSDan Willemsen case protoreflect.MessageKind: 477*1c12ee1eSDan Willemsen return coderMessageSliceValue 478*1c12ee1eSDan Willemsen case protoreflect.GroupKind: 479*1c12ee1eSDan Willemsen return coderGroupSliceValue 480*1c12ee1eSDan Willemsen } 481*1c12ee1eSDan Willemsen case fd.Cardinality() == protoreflect.Repeated && fd.IsPacked(): 482*1c12ee1eSDan Willemsen switch fd.Kind() { 483*1c12ee1eSDan Willemsen case protoreflect.BoolKind: 484*1c12ee1eSDan Willemsen return coderBoolPackedSliceValue 485*1c12ee1eSDan Willemsen case protoreflect.EnumKind: 486*1c12ee1eSDan Willemsen return coderEnumPackedSliceValue 487*1c12ee1eSDan Willemsen case protoreflect.Int32Kind: 488*1c12ee1eSDan Willemsen return coderInt32PackedSliceValue 489*1c12ee1eSDan Willemsen case protoreflect.Sint32Kind: 490*1c12ee1eSDan Willemsen return coderSint32PackedSliceValue 491*1c12ee1eSDan Willemsen case protoreflect.Uint32Kind: 492*1c12ee1eSDan Willemsen return coderUint32PackedSliceValue 493*1c12ee1eSDan Willemsen case protoreflect.Int64Kind: 494*1c12ee1eSDan Willemsen return coderInt64PackedSliceValue 495*1c12ee1eSDan Willemsen case protoreflect.Sint64Kind: 496*1c12ee1eSDan Willemsen return coderSint64PackedSliceValue 497*1c12ee1eSDan Willemsen case protoreflect.Uint64Kind: 498*1c12ee1eSDan Willemsen return coderUint64PackedSliceValue 499*1c12ee1eSDan Willemsen case protoreflect.Sfixed32Kind: 500*1c12ee1eSDan Willemsen return coderSfixed32PackedSliceValue 501*1c12ee1eSDan Willemsen case protoreflect.Fixed32Kind: 502*1c12ee1eSDan Willemsen return coderFixed32PackedSliceValue 503*1c12ee1eSDan Willemsen case protoreflect.FloatKind: 504*1c12ee1eSDan Willemsen return coderFloatPackedSliceValue 505*1c12ee1eSDan Willemsen case protoreflect.Sfixed64Kind: 506*1c12ee1eSDan Willemsen return coderSfixed64PackedSliceValue 507*1c12ee1eSDan Willemsen case protoreflect.Fixed64Kind: 508*1c12ee1eSDan Willemsen return coderFixed64PackedSliceValue 509*1c12ee1eSDan Willemsen case protoreflect.DoubleKind: 510*1c12ee1eSDan Willemsen return coderDoublePackedSliceValue 511*1c12ee1eSDan Willemsen } 512*1c12ee1eSDan Willemsen default: 513*1c12ee1eSDan Willemsen switch fd.Kind() { 514*1c12ee1eSDan Willemsen default: 515*1c12ee1eSDan Willemsen case protoreflect.BoolKind: 516*1c12ee1eSDan Willemsen return coderBoolValue 517*1c12ee1eSDan Willemsen case protoreflect.EnumKind: 518*1c12ee1eSDan Willemsen return coderEnumValue 519*1c12ee1eSDan Willemsen case protoreflect.Int32Kind: 520*1c12ee1eSDan Willemsen return coderInt32Value 521*1c12ee1eSDan Willemsen case protoreflect.Sint32Kind: 522*1c12ee1eSDan Willemsen return coderSint32Value 523*1c12ee1eSDan Willemsen case protoreflect.Uint32Kind: 524*1c12ee1eSDan Willemsen return coderUint32Value 525*1c12ee1eSDan Willemsen case protoreflect.Int64Kind: 526*1c12ee1eSDan Willemsen return coderInt64Value 527*1c12ee1eSDan Willemsen case protoreflect.Sint64Kind: 528*1c12ee1eSDan Willemsen return coderSint64Value 529*1c12ee1eSDan Willemsen case protoreflect.Uint64Kind: 530*1c12ee1eSDan Willemsen return coderUint64Value 531*1c12ee1eSDan Willemsen case protoreflect.Sfixed32Kind: 532*1c12ee1eSDan Willemsen return coderSfixed32Value 533*1c12ee1eSDan Willemsen case protoreflect.Fixed32Kind: 534*1c12ee1eSDan Willemsen return coderFixed32Value 535*1c12ee1eSDan Willemsen case protoreflect.FloatKind: 536*1c12ee1eSDan Willemsen return coderFloatValue 537*1c12ee1eSDan Willemsen case protoreflect.Sfixed64Kind: 538*1c12ee1eSDan Willemsen return coderSfixed64Value 539*1c12ee1eSDan Willemsen case protoreflect.Fixed64Kind: 540*1c12ee1eSDan Willemsen return coderFixed64Value 541*1c12ee1eSDan Willemsen case protoreflect.DoubleKind: 542*1c12ee1eSDan Willemsen return coderDoubleValue 543*1c12ee1eSDan Willemsen case protoreflect.StringKind: 544*1c12ee1eSDan Willemsen if strs.EnforceUTF8(fd) { 545*1c12ee1eSDan Willemsen return coderStringValueValidateUTF8 546*1c12ee1eSDan Willemsen } 547*1c12ee1eSDan Willemsen return coderStringValue 548*1c12ee1eSDan Willemsen case protoreflect.BytesKind: 549*1c12ee1eSDan Willemsen return coderBytesValue 550*1c12ee1eSDan Willemsen case protoreflect.MessageKind: 551*1c12ee1eSDan Willemsen return coderMessageValue 552*1c12ee1eSDan Willemsen case protoreflect.GroupKind: 553*1c12ee1eSDan Willemsen return coderGroupValue 554*1c12ee1eSDan Willemsen } 555*1c12ee1eSDan Willemsen } 556*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid field: no encoder for %v %v %v", fd.FullName(), fd.Cardinality(), fd.Kind())) 557*1c12ee1eSDan Willemsen} 558