1*1c12ee1eSDan Willemsen// Copyright 2018 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/reflect/protoreflect" 12*1c12ee1eSDan Willemsen) 13*1c12ee1eSDan Willemsen 14*1c12ee1eSDan Willemsen// unwrapper unwraps the value to the underlying value. 15*1c12ee1eSDan Willemsen// This is implemented by List and Map. 16*1c12ee1eSDan Willemsentype unwrapper interface { 17*1c12ee1eSDan Willemsen protoUnwrap() interface{} 18*1c12ee1eSDan Willemsen} 19*1c12ee1eSDan Willemsen 20*1c12ee1eSDan Willemsen// A Converter coverts to/from Go reflect.Value types and protobuf protoreflect.Value types. 21*1c12ee1eSDan Willemsentype Converter interface { 22*1c12ee1eSDan Willemsen // PBValueOf converts a reflect.Value to a protoreflect.Value. 23*1c12ee1eSDan Willemsen PBValueOf(reflect.Value) protoreflect.Value 24*1c12ee1eSDan Willemsen 25*1c12ee1eSDan Willemsen // GoValueOf converts a protoreflect.Value to a reflect.Value. 26*1c12ee1eSDan Willemsen GoValueOf(protoreflect.Value) reflect.Value 27*1c12ee1eSDan Willemsen 28*1c12ee1eSDan Willemsen // IsValidPB returns whether a protoreflect.Value is compatible with this type. 29*1c12ee1eSDan Willemsen IsValidPB(protoreflect.Value) bool 30*1c12ee1eSDan Willemsen 31*1c12ee1eSDan Willemsen // IsValidGo returns whether a reflect.Value is compatible with this type. 32*1c12ee1eSDan Willemsen IsValidGo(reflect.Value) bool 33*1c12ee1eSDan Willemsen 34*1c12ee1eSDan Willemsen // New returns a new field value. 35*1c12ee1eSDan Willemsen // For scalars, it returns the default value of the field. 36*1c12ee1eSDan Willemsen // For composite types, it returns a new mutable value. 37*1c12ee1eSDan Willemsen New() protoreflect.Value 38*1c12ee1eSDan Willemsen 39*1c12ee1eSDan Willemsen // Zero returns a new field value. 40*1c12ee1eSDan Willemsen // For scalars, it returns the default value of the field. 41*1c12ee1eSDan Willemsen // For composite types, it returns an immutable, empty value. 42*1c12ee1eSDan Willemsen Zero() protoreflect.Value 43*1c12ee1eSDan Willemsen} 44*1c12ee1eSDan Willemsen 45*1c12ee1eSDan Willemsen// NewConverter matches a Go type with a protobuf field and returns a Converter 46*1c12ee1eSDan Willemsen// that converts between the two. Enums must be a named int32 kind that 47*1c12ee1eSDan Willemsen// implements protoreflect.Enum, and messages must be pointer to a named 48*1c12ee1eSDan Willemsen// struct type that implements protoreflect.ProtoMessage. 49*1c12ee1eSDan Willemsen// 50*1c12ee1eSDan Willemsen// This matcher deliberately supports a wider range of Go types than what 51*1c12ee1eSDan Willemsen// protoc-gen-go historically generated to be able to automatically wrap some 52*1c12ee1eSDan Willemsen// v1 messages generated by other forks of protoc-gen-go. 53*1c12ee1eSDan Willemsenfunc NewConverter(t reflect.Type, fd protoreflect.FieldDescriptor) Converter { 54*1c12ee1eSDan Willemsen switch { 55*1c12ee1eSDan Willemsen case fd.IsList(): 56*1c12ee1eSDan Willemsen return newListConverter(t, fd) 57*1c12ee1eSDan Willemsen case fd.IsMap(): 58*1c12ee1eSDan Willemsen return newMapConverter(t, fd) 59*1c12ee1eSDan Willemsen default: 60*1c12ee1eSDan Willemsen return newSingularConverter(t, fd) 61*1c12ee1eSDan Willemsen } 62*1c12ee1eSDan Willemsen} 63*1c12ee1eSDan Willemsen 64*1c12ee1eSDan Willemsenvar ( 65*1c12ee1eSDan Willemsen boolType = reflect.TypeOf(bool(false)) 66*1c12ee1eSDan Willemsen int32Type = reflect.TypeOf(int32(0)) 67*1c12ee1eSDan Willemsen int64Type = reflect.TypeOf(int64(0)) 68*1c12ee1eSDan Willemsen uint32Type = reflect.TypeOf(uint32(0)) 69*1c12ee1eSDan Willemsen uint64Type = reflect.TypeOf(uint64(0)) 70*1c12ee1eSDan Willemsen float32Type = reflect.TypeOf(float32(0)) 71*1c12ee1eSDan Willemsen float64Type = reflect.TypeOf(float64(0)) 72*1c12ee1eSDan Willemsen stringType = reflect.TypeOf(string("")) 73*1c12ee1eSDan Willemsen bytesType = reflect.TypeOf([]byte(nil)) 74*1c12ee1eSDan Willemsen byteType = reflect.TypeOf(byte(0)) 75*1c12ee1eSDan Willemsen) 76*1c12ee1eSDan Willemsen 77*1c12ee1eSDan Willemsenvar ( 78*1c12ee1eSDan Willemsen boolZero = protoreflect.ValueOfBool(false) 79*1c12ee1eSDan Willemsen int32Zero = protoreflect.ValueOfInt32(0) 80*1c12ee1eSDan Willemsen int64Zero = protoreflect.ValueOfInt64(0) 81*1c12ee1eSDan Willemsen uint32Zero = protoreflect.ValueOfUint32(0) 82*1c12ee1eSDan Willemsen uint64Zero = protoreflect.ValueOfUint64(0) 83*1c12ee1eSDan Willemsen float32Zero = protoreflect.ValueOfFloat32(0) 84*1c12ee1eSDan Willemsen float64Zero = protoreflect.ValueOfFloat64(0) 85*1c12ee1eSDan Willemsen stringZero = protoreflect.ValueOfString("") 86*1c12ee1eSDan Willemsen bytesZero = protoreflect.ValueOfBytes(nil) 87*1c12ee1eSDan Willemsen) 88*1c12ee1eSDan Willemsen 89*1c12ee1eSDan Willemsenfunc newSingularConverter(t reflect.Type, fd protoreflect.FieldDescriptor) Converter { 90*1c12ee1eSDan Willemsen defVal := func(fd protoreflect.FieldDescriptor, zero protoreflect.Value) protoreflect.Value { 91*1c12ee1eSDan Willemsen if fd.Cardinality() == protoreflect.Repeated { 92*1c12ee1eSDan Willemsen // Default isn't defined for repeated fields. 93*1c12ee1eSDan Willemsen return zero 94*1c12ee1eSDan Willemsen } 95*1c12ee1eSDan Willemsen return fd.Default() 96*1c12ee1eSDan Willemsen } 97*1c12ee1eSDan Willemsen switch fd.Kind() { 98*1c12ee1eSDan Willemsen case protoreflect.BoolKind: 99*1c12ee1eSDan Willemsen if t.Kind() == reflect.Bool { 100*1c12ee1eSDan Willemsen return &boolConverter{t, defVal(fd, boolZero)} 101*1c12ee1eSDan Willemsen } 102*1c12ee1eSDan Willemsen case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: 103*1c12ee1eSDan Willemsen if t.Kind() == reflect.Int32 { 104*1c12ee1eSDan Willemsen return &int32Converter{t, defVal(fd, int32Zero)} 105*1c12ee1eSDan Willemsen } 106*1c12ee1eSDan Willemsen case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: 107*1c12ee1eSDan Willemsen if t.Kind() == reflect.Int64 { 108*1c12ee1eSDan Willemsen return &int64Converter{t, defVal(fd, int64Zero)} 109*1c12ee1eSDan Willemsen } 110*1c12ee1eSDan Willemsen case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: 111*1c12ee1eSDan Willemsen if t.Kind() == reflect.Uint32 { 112*1c12ee1eSDan Willemsen return &uint32Converter{t, defVal(fd, uint32Zero)} 113*1c12ee1eSDan Willemsen } 114*1c12ee1eSDan Willemsen case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: 115*1c12ee1eSDan Willemsen if t.Kind() == reflect.Uint64 { 116*1c12ee1eSDan Willemsen return &uint64Converter{t, defVal(fd, uint64Zero)} 117*1c12ee1eSDan Willemsen } 118*1c12ee1eSDan Willemsen case protoreflect.FloatKind: 119*1c12ee1eSDan Willemsen if t.Kind() == reflect.Float32 { 120*1c12ee1eSDan Willemsen return &float32Converter{t, defVal(fd, float32Zero)} 121*1c12ee1eSDan Willemsen } 122*1c12ee1eSDan Willemsen case protoreflect.DoubleKind: 123*1c12ee1eSDan Willemsen if t.Kind() == reflect.Float64 { 124*1c12ee1eSDan Willemsen return &float64Converter{t, defVal(fd, float64Zero)} 125*1c12ee1eSDan Willemsen } 126*1c12ee1eSDan Willemsen case protoreflect.StringKind: 127*1c12ee1eSDan Willemsen if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) { 128*1c12ee1eSDan Willemsen return &stringConverter{t, defVal(fd, stringZero)} 129*1c12ee1eSDan Willemsen } 130*1c12ee1eSDan Willemsen case protoreflect.BytesKind: 131*1c12ee1eSDan Willemsen if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) { 132*1c12ee1eSDan Willemsen return &bytesConverter{t, defVal(fd, bytesZero)} 133*1c12ee1eSDan Willemsen } 134*1c12ee1eSDan Willemsen case protoreflect.EnumKind: 135*1c12ee1eSDan Willemsen // Handle enums, which must be a named int32 type. 136*1c12ee1eSDan Willemsen if t.Kind() == reflect.Int32 { 137*1c12ee1eSDan Willemsen return newEnumConverter(t, fd) 138*1c12ee1eSDan Willemsen } 139*1c12ee1eSDan Willemsen case protoreflect.MessageKind, protoreflect.GroupKind: 140*1c12ee1eSDan Willemsen return newMessageConverter(t) 141*1c12ee1eSDan Willemsen } 142*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName())) 143*1c12ee1eSDan Willemsen} 144*1c12ee1eSDan Willemsen 145*1c12ee1eSDan Willemsentype boolConverter struct { 146*1c12ee1eSDan Willemsen goType reflect.Type 147*1c12ee1eSDan Willemsen def protoreflect.Value 148*1c12ee1eSDan Willemsen} 149*1c12ee1eSDan Willemsen 150*1c12ee1eSDan Willemsenfunc (c *boolConverter) PBValueOf(v reflect.Value) protoreflect.Value { 151*1c12ee1eSDan Willemsen if v.Type() != c.goType { 152*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 153*1c12ee1eSDan Willemsen } 154*1c12ee1eSDan Willemsen return protoreflect.ValueOfBool(v.Bool()) 155*1c12ee1eSDan Willemsen} 156*1c12ee1eSDan Willemsenfunc (c *boolConverter) GoValueOf(v protoreflect.Value) reflect.Value { 157*1c12ee1eSDan Willemsen return reflect.ValueOf(v.Bool()).Convert(c.goType) 158*1c12ee1eSDan Willemsen} 159*1c12ee1eSDan Willemsenfunc (c *boolConverter) IsValidPB(v protoreflect.Value) bool { 160*1c12ee1eSDan Willemsen _, ok := v.Interface().(bool) 161*1c12ee1eSDan Willemsen return ok 162*1c12ee1eSDan Willemsen} 163*1c12ee1eSDan Willemsenfunc (c *boolConverter) IsValidGo(v reflect.Value) bool { 164*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 165*1c12ee1eSDan Willemsen} 166*1c12ee1eSDan Willemsenfunc (c *boolConverter) New() protoreflect.Value { return c.def } 167*1c12ee1eSDan Willemsenfunc (c *boolConverter) Zero() protoreflect.Value { return c.def } 168*1c12ee1eSDan Willemsen 169*1c12ee1eSDan Willemsentype int32Converter struct { 170*1c12ee1eSDan Willemsen goType reflect.Type 171*1c12ee1eSDan Willemsen def protoreflect.Value 172*1c12ee1eSDan Willemsen} 173*1c12ee1eSDan Willemsen 174*1c12ee1eSDan Willemsenfunc (c *int32Converter) PBValueOf(v reflect.Value) protoreflect.Value { 175*1c12ee1eSDan Willemsen if v.Type() != c.goType { 176*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 177*1c12ee1eSDan Willemsen } 178*1c12ee1eSDan Willemsen return protoreflect.ValueOfInt32(int32(v.Int())) 179*1c12ee1eSDan Willemsen} 180*1c12ee1eSDan Willemsenfunc (c *int32Converter) GoValueOf(v protoreflect.Value) reflect.Value { 181*1c12ee1eSDan Willemsen return reflect.ValueOf(int32(v.Int())).Convert(c.goType) 182*1c12ee1eSDan Willemsen} 183*1c12ee1eSDan Willemsenfunc (c *int32Converter) IsValidPB(v protoreflect.Value) bool { 184*1c12ee1eSDan Willemsen _, ok := v.Interface().(int32) 185*1c12ee1eSDan Willemsen return ok 186*1c12ee1eSDan Willemsen} 187*1c12ee1eSDan Willemsenfunc (c *int32Converter) IsValidGo(v reflect.Value) bool { 188*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 189*1c12ee1eSDan Willemsen} 190*1c12ee1eSDan Willemsenfunc (c *int32Converter) New() protoreflect.Value { return c.def } 191*1c12ee1eSDan Willemsenfunc (c *int32Converter) Zero() protoreflect.Value { return c.def } 192*1c12ee1eSDan Willemsen 193*1c12ee1eSDan Willemsentype int64Converter struct { 194*1c12ee1eSDan Willemsen goType reflect.Type 195*1c12ee1eSDan Willemsen def protoreflect.Value 196*1c12ee1eSDan Willemsen} 197*1c12ee1eSDan Willemsen 198*1c12ee1eSDan Willemsenfunc (c *int64Converter) PBValueOf(v reflect.Value) protoreflect.Value { 199*1c12ee1eSDan Willemsen if v.Type() != c.goType { 200*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 201*1c12ee1eSDan Willemsen } 202*1c12ee1eSDan Willemsen return protoreflect.ValueOfInt64(int64(v.Int())) 203*1c12ee1eSDan Willemsen} 204*1c12ee1eSDan Willemsenfunc (c *int64Converter) GoValueOf(v protoreflect.Value) reflect.Value { 205*1c12ee1eSDan Willemsen return reflect.ValueOf(int64(v.Int())).Convert(c.goType) 206*1c12ee1eSDan Willemsen} 207*1c12ee1eSDan Willemsenfunc (c *int64Converter) IsValidPB(v protoreflect.Value) bool { 208*1c12ee1eSDan Willemsen _, ok := v.Interface().(int64) 209*1c12ee1eSDan Willemsen return ok 210*1c12ee1eSDan Willemsen} 211*1c12ee1eSDan Willemsenfunc (c *int64Converter) IsValidGo(v reflect.Value) bool { 212*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 213*1c12ee1eSDan Willemsen} 214*1c12ee1eSDan Willemsenfunc (c *int64Converter) New() protoreflect.Value { return c.def } 215*1c12ee1eSDan Willemsenfunc (c *int64Converter) Zero() protoreflect.Value { return c.def } 216*1c12ee1eSDan Willemsen 217*1c12ee1eSDan Willemsentype uint32Converter struct { 218*1c12ee1eSDan Willemsen goType reflect.Type 219*1c12ee1eSDan Willemsen def protoreflect.Value 220*1c12ee1eSDan Willemsen} 221*1c12ee1eSDan Willemsen 222*1c12ee1eSDan Willemsenfunc (c *uint32Converter) PBValueOf(v reflect.Value) protoreflect.Value { 223*1c12ee1eSDan Willemsen if v.Type() != c.goType { 224*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 225*1c12ee1eSDan Willemsen } 226*1c12ee1eSDan Willemsen return protoreflect.ValueOfUint32(uint32(v.Uint())) 227*1c12ee1eSDan Willemsen} 228*1c12ee1eSDan Willemsenfunc (c *uint32Converter) GoValueOf(v protoreflect.Value) reflect.Value { 229*1c12ee1eSDan Willemsen return reflect.ValueOf(uint32(v.Uint())).Convert(c.goType) 230*1c12ee1eSDan Willemsen} 231*1c12ee1eSDan Willemsenfunc (c *uint32Converter) IsValidPB(v protoreflect.Value) bool { 232*1c12ee1eSDan Willemsen _, ok := v.Interface().(uint32) 233*1c12ee1eSDan Willemsen return ok 234*1c12ee1eSDan Willemsen} 235*1c12ee1eSDan Willemsenfunc (c *uint32Converter) IsValidGo(v reflect.Value) bool { 236*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 237*1c12ee1eSDan Willemsen} 238*1c12ee1eSDan Willemsenfunc (c *uint32Converter) New() protoreflect.Value { return c.def } 239*1c12ee1eSDan Willemsenfunc (c *uint32Converter) Zero() protoreflect.Value { return c.def } 240*1c12ee1eSDan Willemsen 241*1c12ee1eSDan Willemsentype uint64Converter struct { 242*1c12ee1eSDan Willemsen goType reflect.Type 243*1c12ee1eSDan Willemsen def protoreflect.Value 244*1c12ee1eSDan Willemsen} 245*1c12ee1eSDan Willemsen 246*1c12ee1eSDan Willemsenfunc (c *uint64Converter) PBValueOf(v reflect.Value) protoreflect.Value { 247*1c12ee1eSDan Willemsen if v.Type() != c.goType { 248*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 249*1c12ee1eSDan Willemsen } 250*1c12ee1eSDan Willemsen return protoreflect.ValueOfUint64(uint64(v.Uint())) 251*1c12ee1eSDan Willemsen} 252*1c12ee1eSDan Willemsenfunc (c *uint64Converter) GoValueOf(v protoreflect.Value) reflect.Value { 253*1c12ee1eSDan Willemsen return reflect.ValueOf(uint64(v.Uint())).Convert(c.goType) 254*1c12ee1eSDan Willemsen} 255*1c12ee1eSDan Willemsenfunc (c *uint64Converter) IsValidPB(v protoreflect.Value) bool { 256*1c12ee1eSDan Willemsen _, ok := v.Interface().(uint64) 257*1c12ee1eSDan Willemsen return ok 258*1c12ee1eSDan Willemsen} 259*1c12ee1eSDan Willemsenfunc (c *uint64Converter) IsValidGo(v reflect.Value) bool { 260*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 261*1c12ee1eSDan Willemsen} 262*1c12ee1eSDan Willemsenfunc (c *uint64Converter) New() protoreflect.Value { return c.def } 263*1c12ee1eSDan Willemsenfunc (c *uint64Converter) Zero() protoreflect.Value { return c.def } 264*1c12ee1eSDan Willemsen 265*1c12ee1eSDan Willemsentype float32Converter struct { 266*1c12ee1eSDan Willemsen goType reflect.Type 267*1c12ee1eSDan Willemsen def protoreflect.Value 268*1c12ee1eSDan Willemsen} 269*1c12ee1eSDan Willemsen 270*1c12ee1eSDan Willemsenfunc (c *float32Converter) PBValueOf(v reflect.Value) protoreflect.Value { 271*1c12ee1eSDan Willemsen if v.Type() != c.goType { 272*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 273*1c12ee1eSDan Willemsen } 274*1c12ee1eSDan Willemsen return protoreflect.ValueOfFloat32(float32(v.Float())) 275*1c12ee1eSDan Willemsen} 276*1c12ee1eSDan Willemsenfunc (c *float32Converter) GoValueOf(v protoreflect.Value) reflect.Value { 277*1c12ee1eSDan Willemsen return reflect.ValueOf(float32(v.Float())).Convert(c.goType) 278*1c12ee1eSDan Willemsen} 279*1c12ee1eSDan Willemsenfunc (c *float32Converter) IsValidPB(v protoreflect.Value) bool { 280*1c12ee1eSDan Willemsen _, ok := v.Interface().(float32) 281*1c12ee1eSDan Willemsen return ok 282*1c12ee1eSDan Willemsen} 283*1c12ee1eSDan Willemsenfunc (c *float32Converter) IsValidGo(v reflect.Value) bool { 284*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 285*1c12ee1eSDan Willemsen} 286*1c12ee1eSDan Willemsenfunc (c *float32Converter) New() protoreflect.Value { return c.def } 287*1c12ee1eSDan Willemsenfunc (c *float32Converter) Zero() protoreflect.Value { return c.def } 288*1c12ee1eSDan Willemsen 289*1c12ee1eSDan Willemsentype float64Converter struct { 290*1c12ee1eSDan Willemsen goType reflect.Type 291*1c12ee1eSDan Willemsen def protoreflect.Value 292*1c12ee1eSDan Willemsen} 293*1c12ee1eSDan Willemsen 294*1c12ee1eSDan Willemsenfunc (c *float64Converter) PBValueOf(v reflect.Value) protoreflect.Value { 295*1c12ee1eSDan Willemsen if v.Type() != c.goType { 296*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 297*1c12ee1eSDan Willemsen } 298*1c12ee1eSDan Willemsen return protoreflect.ValueOfFloat64(float64(v.Float())) 299*1c12ee1eSDan Willemsen} 300*1c12ee1eSDan Willemsenfunc (c *float64Converter) GoValueOf(v protoreflect.Value) reflect.Value { 301*1c12ee1eSDan Willemsen return reflect.ValueOf(float64(v.Float())).Convert(c.goType) 302*1c12ee1eSDan Willemsen} 303*1c12ee1eSDan Willemsenfunc (c *float64Converter) IsValidPB(v protoreflect.Value) bool { 304*1c12ee1eSDan Willemsen _, ok := v.Interface().(float64) 305*1c12ee1eSDan Willemsen return ok 306*1c12ee1eSDan Willemsen} 307*1c12ee1eSDan Willemsenfunc (c *float64Converter) IsValidGo(v reflect.Value) bool { 308*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 309*1c12ee1eSDan Willemsen} 310*1c12ee1eSDan Willemsenfunc (c *float64Converter) New() protoreflect.Value { return c.def } 311*1c12ee1eSDan Willemsenfunc (c *float64Converter) Zero() protoreflect.Value { return c.def } 312*1c12ee1eSDan Willemsen 313*1c12ee1eSDan Willemsentype stringConverter struct { 314*1c12ee1eSDan Willemsen goType reflect.Type 315*1c12ee1eSDan Willemsen def protoreflect.Value 316*1c12ee1eSDan Willemsen} 317*1c12ee1eSDan Willemsen 318*1c12ee1eSDan Willemsenfunc (c *stringConverter) PBValueOf(v reflect.Value) protoreflect.Value { 319*1c12ee1eSDan Willemsen if v.Type() != c.goType { 320*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 321*1c12ee1eSDan Willemsen } 322*1c12ee1eSDan Willemsen return protoreflect.ValueOfString(v.Convert(stringType).String()) 323*1c12ee1eSDan Willemsen} 324*1c12ee1eSDan Willemsenfunc (c *stringConverter) GoValueOf(v protoreflect.Value) reflect.Value { 325*1c12ee1eSDan Willemsen // pref.Value.String never panics, so we go through an interface 326*1c12ee1eSDan Willemsen // conversion here to check the type. 327*1c12ee1eSDan Willemsen s := v.Interface().(string) 328*1c12ee1eSDan Willemsen if c.goType.Kind() == reflect.Slice && s == "" { 329*1c12ee1eSDan Willemsen return reflect.Zero(c.goType) // ensure empty string is []byte(nil) 330*1c12ee1eSDan Willemsen } 331*1c12ee1eSDan Willemsen return reflect.ValueOf(s).Convert(c.goType) 332*1c12ee1eSDan Willemsen} 333*1c12ee1eSDan Willemsenfunc (c *stringConverter) IsValidPB(v protoreflect.Value) bool { 334*1c12ee1eSDan Willemsen _, ok := v.Interface().(string) 335*1c12ee1eSDan Willemsen return ok 336*1c12ee1eSDan Willemsen} 337*1c12ee1eSDan Willemsenfunc (c *stringConverter) IsValidGo(v reflect.Value) bool { 338*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 339*1c12ee1eSDan Willemsen} 340*1c12ee1eSDan Willemsenfunc (c *stringConverter) New() protoreflect.Value { return c.def } 341*1c12ee1eSDan Willemsenfunc (c *stringConverter) Zero() protoreflect.Value { return c.def } 342*1c12ee1eSDan Willemsen 343*1c12ee1eSDan Willemsentype bytesConverter struct { 344*1c12ee1eSDan Willemsen goType reflect.Type 345*1c12ee1eSDan Willemsen def protoreflect.Value 346*1c12ee1eSDan Willemsen} 347*1c12ee1eSDan Willemsen 348*1c12ee1eSDan Willemsenfunc (c *bytesConverter) PBValueOf(v reflect.Value) protoreflect.Value { 349*1c12ee1eSDan Willemsen if v.Type() != c.goType { 350*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 351*1c12ee1eSDan Willemsen } 352*1c12ee1eSDan Willemsen if c.goType.Kind() == reflect.String && v.Len() == 0 { 353*1c12ee1eSDan Willemsen return protoreflect.ValueOfBytes(nil) // ensure empty string is []byte(nil) 354*1c12ee1eSDan Willemsen } 355*1c12ee1eSDan Willemsen return protoreflect.ValueOfBytes(v.Convert(bytesType).Bytes()) 356*1c12ee1eSDan Willemsen} 357*1c12ee1eSDan Willemsenfunc (c *bytesConverter) GoValueOf(v protoreflect.Value) reflect.Value { 358*1c12ee1eSDan Willemsen return reflect.ValueOf(v.Bytes()).Convert(c.goType) 359*1c12ee1eSDan Willemsen} 360*1c12ee1eSDan Willemsenfunc (c *bytesConverter) IsValidPB(v protoreflect.Value) bool { 361*1c12ee1eSDan Willemsen _, ok := v.Interface().([]byte) 362*1c12ee1eSDan Willemsen return ok 363*1c12ee1eSDan Willemsen} 364*1c12ee1eSDan Willemsenfunc (c *bytesConverter) IsValidGo(v reflect.Value) bool { 365*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 366*1c12ee1eSDan Willemsen} 367*1c12ee1eSDan Willemsenfunc (c *bytesConverter) New() protoreflect.Value { return c.def } 368*1c12ee1eSDan Willemsenfunc (c *bytesConverter) Zero() protoreflect.Value { return c.def } 369*1c12ee1eSDan Willemsen 370*1c12ee1eSDan Willemsentype enumConverter struct { 371*1c12ee1eSDan Willemsen goType reflect.Type 372*1c12ee1eSDan Willemsen def protoreflect.Value 373*1c12ee1eSDan Willemsen} 374*1c12ee1eSDan Willemsen 375*1c12ee1eSDan Willemsenfunc newEnumConverter(goType reflect.Type, fd protoreflect.FieldDescriptor) Converter { 376*1c12ee1eSDan Willemsen var def protoreflect.Value 377*1c12ee1eSDan Willemsen if fd.Cardinality() == protoreflect.Repeated { 378*1c12ee1eSDan Willemsen def = protoreflect.ValueOfEnum(fd.Enum().Values().Get(0).Number()) 379*1c12ee1eSDan Willemsen } else { 380*1c12ee1eSDan Willemsen def = fd.Default() 381*1c12ee1eSDan Willemsen } 382*1c12ee1eSDan Willemsen return &enumConverter{goType, def} 383*1c12ee1eSDan Willemsen} 384*1c12ee1eSDan Willemsen 385*1c12ee1eSDan Willemsenfunc (c *enumConverter) PBValueOf(v reflect.Value) protoreflect.Value { 386*1c12ee1eSDan Willemsen if v.Type() != c.goType { 387*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 388*1c12ee1eSDan Willemsen } 389*1c12ee1eSDan Willemsen return protoreflect.ValueOfEnum(protoreflect.EnumNumber(v.Int())) 390*1c12ee1eSDan Willemsen} 391*1c12ee1eSDan Willemsen 392*1c12ee1eSDan Willemsenfunc (c *enumConverter) GoValueOf(v protoreflect.Value) reflect.Value { 393*1c12ee1eSDan Willemsen return reflect.ValueOf(v.Enum()).Convert(c.goType) 394*1c12ee1eSDan Willemsen} 395*1c12ee1eSDan Willemsen 396*1c12ee1eSDan Willemsenfunc (c *enumConverter) IsValidPB(v protoreflect.Value) bool { 397*1c12ee1eSDan Willemsen _, ok := v.Interface().(protoreflect.EnumNumber) 398*1c12ee1eSDan Willemsen return ok 399*1c12ee1eSDan Willemsen} 400*1c12ee1eSDan Willemsen 401*1c12ee1eSDan Willemsenfunc (c *enumConverter) IsValidGo(v reflect.Value) bool { 402*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 403*1c12ee1eSDan Willemsen} 404*1c12ee1eSDan Willemsen 405*1c12ee1eSDan Willemsenfunc (c *enumConverter) New() protoreflect.Value { 406*1c12ee1eSDan Willemsen return c.def 407*1c12ee1eSDan Willemsen} 408*1c12ee1eSDan Willemsen 409*1c12ee1eSDan Willemsenfunc (c *enumConverter) Zero() protoreflect.Value { 410*1c12ee1eSDan Willemsen return c.def 411*1c12ee1eSDan Willemsen} 412*1c12ee1eSDan Willemsen 413*1c12ee1eSDan Willemsentype messageConverter struct { 414*1c12ee1eSDan Willemsen goType reflect.Type 415*1c12ee1eSDan Willemsen} 416*1c12ee1eSDan Willemsen 417*1c12ee1eSDan Willemsenfunc newMessageConverter(goType reflect.Type) Converter { 418*1c12ee1eSDan Willemsen return &messageConverter{goType} 419*1c12ee1eSDan Willemsen} 420*1c12ee1eSDan Willemsen 421*1c12ee1eSDan Willemsenfunc (c *messageConverter) PBValueOf(v reflect.Value) protoreflect.Value { 422*1c12ee1eSDan Willemsen if v.Type() != c.goType { 423*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) 424*1c12ee1eSDan Willemsen } 425*1c12ee1eSDan Willemsen if c.isNonPointer() { 426*1c12ee1eSDan Willemsen if v.CanAddr() { 427*1c12ee1eSDan Willemsen v = v.Addr() // T => *T 428*1c12ee1eSDan Willemsen } else { 429*1c12ee1eSDan Willemsen v = reflect.Zero(reflect.PtrTo(v.Type())) 430*1c12ee1eSDan Willemsen } 431*1c12ee1eSDan Willemsen } 432*1c12ee1eSDan Willemsen if m, ok := v.Interface().(protoreflect.ProtoMessage); ok { 433*1c12ee1eSDan Willemsen return protoreflect.ValueOfMessage(m.ProtoReflect()) 434*1c12ee1eSDan Willemsen } 435*1c12ee1eSDan Willemsen return protoreflect.ValueOfMessage(legacyWrapMessage(v)) 436*1c12ee1eSDan Willemsen} 437*1c12ee1eSDan Willemsen 438*1c12ee1eSDan Willemsenfunc (c *messageConverter) GoValueOf(v protoreflect.Value) reflect.Value { 439*1c12ee1eSDan Willemsen m := v.Message() 440*1c12ee1eSDan Willemsen var rv reflect.Value 441*1c12ee1eSDan Willemsen if u, ok := m.(unwrapper); ok { 442*1c12ee1eSDan Willemsen rv = reflect.ValueOf(u.protoUnwrap()) 443*1c12ee1eSDan Willemsen } else { 444*1c12ee1eSDan Willemsen rv = reflect.ValueOf(m.Interface()) 445*1c12ee1eSDan Willemsen } 446*1c12ee1eSDan Willemsen if c.isNonPointer() { 447*1c12ee1eSDan Willemsen if rv.Type() != reflect.PtrTo(c.goType) { 448*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), reflect.PtrTo(c.goType))) 449*1c12ee1eSDan Willemsen } 450*1c12ee1eSDan Willemsen if !rv.IsNil() { 451*1c12ee1eSDan Willemsen rv = rv.Elem() // *T => T 452*1c12ee1eSDan Willemsen } else { 453*1c12ee1eSDan Willemsen rv = reflect.Zero(rv.Type().Elem()) 454*1c12ee1eSDan Willemsen } 455*1c12ee1eSDan Willemsen } 456*1c12ee1eSDan Willemsen if rv.Type() != c.goType { 457*1c12ee1eSDan Willemsen panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.goType)) 458*1c12ee1eSDan Willemsen } 459*1c12ee1eSDan Willemsen return rv 460*1c12ee1eSDan Willemsen} 461*1c12ee1eSDan Willemsen 462*1c12ee1eSDan Willemsenfunc (c *messageConverter) IsValidPB(v protoreflect.Value) bool { 463*1c12ee1eSDan Willemsen m := v.Message() 464*1c12ee1eSDan Willemsen var rv reflect.Value 465*1c12ee1eSDan Willemsen if u, ok := m.(unwrapper); ok { 466*1c12ee1eSDan Willemsen rv = reflect.ValueOf(u.protoUnwrap()) 467*1c12ee1eSDan Willemsen } else { 468*1c12ee1eSDan Willemsen rv = reflect.ValueOf(m.Interface()) 469*1c12ee1eSDan Willemsen } 470*1c12ee1eSDan Willemsen if c.isNonPointer() { 471*1c12ee1eSDan Willemsen return rv.Type() == reflect.PtrTo(c.goType) 472*1c12ee1eSDan Willemsen } 473*1c12ee1eSDan Willemsen return rv.Type() == c.goType 474*1c12ee1eSDan Willemsen} 475*1c12ee1eSDan Willemsen 476*1c12ee1eSDan Willemsenfunc (c *messageConverter) IsValidGo(v reflect.Value) bool { 477*1c12ee1eSDan Willemsen return v.IsValid() && v.Type() == c.goType 478*1c12ee1eSDan Willemsen} 479*1c12ee1eSDan Willemsen 480*1c12ee1eSDan Willemsenfunc (c *messageConverter) New() protoreflect.Value { 481*1c12ee1eSDan Willemsen if c.isNonPointer() { 482*1c12ee1eSDan Willemsen return c.PBValueOf(reflect.New(c.goType).Elem()) 483*1c12ee1eSDan Willemsen } 484*1c12ee1eSDan Willemsen return c.PBValueOf(reflect.New(c.goType.Elem())) 485*1c12ee1eSDan Willemsen} 486*1c12ee1eSDan Willemsen 487*1c12ee1eSDan Willemsenfunc (c *messageConverter) Zero() protoreflect.Value { 488*1c12ee1eSDan Willemsen return c.PBValueOf(reflect.Zero(c.goType)) 489*1c12ee1eSDan Willemsen} 490*1c12ee1eSDan Willemsen 491*1c12ee1eSDan Willemsen// isNonPointer reports whether the type is a non-pointer type. 492*1c12ee1eSDan Willemsen// This never occurs for generated message types. 493*1c12ee1eSDan Willemsenfunc (c *messageConverter) isNonPointer() bool { 494*1c12ee1eSDan Willemsen return c.goType.Kind() != reflect.Ptr 495*1c12ee1eSDan Willemsen} 496