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  }