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