convert.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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. package impl
  5. import (
  6. "fmt"
  7. "reflect"
  8. pref "google.golang.org/protobuf/reflect/protoreflect"
  9. )
  10. // Unwrapper unwraps the value to the underlying value.
  11. // This is implemented by List and Map.
  12. type Unwrapper interface {
  13. ProtoUnwrap() interface{}
  14. }
  15. // A Converter coverts to/from Go reflect.Value types and protobuf protoreflect.Value types.
  16. type Converter interface {
  17. // PBValueOf converts a reflect.Value to a protoreflect.Value.
  18. PBValueOf(reflect.Value) pref.Value
  19. // GoValueOf converts a protoreflect.Value to a reflect.Value.
  20. GoValueOf(pref.Value) reflect.Value
  21. // New returns a new field value.
  22. // For scalars, it returns the default value of the field.
  23. // For composite types, it returns a new mutable value.
  24. New() pref.Value
  25. // Zero returns a new field value.
  26. // For scalars, it returns the default value of the field.
  27. // For composite types, it returns an immutable, empty value.
  28. Zero() pref.Value
  29. }
  30. // NewConverter matches a Go type with a protobuf field and returns a Converter
  31. // that converts between the two. Enums must be a named int32 kind that
  32. // implements protoreflect.Enum, and messages must be pointer to a named
  33. // struct type that implements protoreflect.ProtoMessage.
  34. //
  35. // This matcher deliberately supports a wider range of Go types than what
  36. // protoc-gen-go historically generated to be able to automatically wrap some
  37. // v1 messages generated by other forks of protoc-gen-go.
  38. func NewConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
  39. switch {
  40. case fd.IsList():
  41. return newListConverter(t, fd)
  42. case fd.IsMap():
  43. return newMapConverter(t, fd)
  44. default:
  45. return newSingularConverter(t, fd)
  46. }
  47. panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
  48. }
  49. var (
  50. boolType = reflect.TypeOf(bool(false))
  51. int32Type = reflect.TypeOf(int32(0))
  52. int64Type = reflect.TypeOf(int64(0))
  53. uint32Type = reflect.TypeOf(uint32(0))
  54. uint64Type = reflect.TypeOf(uint64(0))
  55. float32Type = reflect.TypeOf(float32(0))
  56. float64Type = reflect.TypeOf(float64(0))
  57. stringType = reflect.TypeOf(string(""))
  58. bytesType = reflect.TypeOf([]byte(nil))
  59. byteType = reflect.TypeOf(byte(0))
  60. )
  61. var (
  62. boolZero = pref.ValueOf(bool(false))
  63. int32Zero = pref.ValueOf(int32(0))
  64. int64Zero = pref.ValueOf(int64(0))
  65. uint32Zero = pref.ValueOf(uint32(0))
  66. uint64Zero = pref.ValueOf(uint64(0))
  67. float32Zero = pref.ValueOf(float32(0))
  68. float64Zero = pref.ValueOf(float64(0))
  69. stringZero = pref.ValueOf(string(""))
  70. bytesZero = pref.ValueOf([]byte(nil))
  71. )
  72. type scalarConverter struct {
  73. goType, pbType reflect.Type
  74. def pref.Value
  75. }
  76. func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
  77. defVal := func(fd pref.FieldDescriptor, zero pref.Value) pref.Value {
  78. if fd.Cardinality() == pref.Repeated {
  79. // Default isn't defined for repeated fields.
  80. return zero
  81. }
  82. return fd.Default()
  83. }
  84. switch fd.Kind() {
  85. case pref.BoolKind:
  86. if t.Kind() == reflect.Bool {
  87. return &scalarConverter{t, boolType, defVal(fd, boolZero)}
  88. }
  89. case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
  90. if t.Kind() == reflect.Int32 {
  91. return &scalarConverter{t, int32Type, defVal(fd, int32Zero)}
  92. }
  93. case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
  94. if t.Kind() == reflect.Int64 {
  95. return &scalarConverter{t, int64Type, defVal(fd, int64Zero)}
  96. }
  97. case pref.Uint32Kind, pref.Fixed32Kind:
  98. if t.Kind() == reflect.Uint32 {
  99. return &scalarConverter{t, uint32Type, defVal(fd, uint32Zero)}
  100. }
  101. case pref.Uint64Kind, pref.Fixed64Kind:
  102. if t.Kind() == reflect.Uint64 {
  103. return &scalarConverter{t, uint64Type, defVal(fd, uint64Zero)}
  104. }
  105. case pref.FloatKind:
  106. if t.Kind() == reflect.Float32 {
  107. return &scalarConverter{t, float32Type, defVal(fd, float32Zero)}
  108. }
  109. case pref.DoubleKind:
  110. if t.Kind() == reflect.Float64 {
  111. return &scalarConverter{t, float64Type, defVal(fd, float64Zero)}
  112. }
  113. case pref.StringKind:
  114. if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
  115. return &scalarConverter{t, stringType, defVal(fd, stringZero)}
  116. }
  117. case pref.BytesKind:
  118. if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
  119. return &scalarConverter{t, bytesType, defVal(fd, bytesZero)}
  120. }
  121. case pref.EnumKind:
  122. // Handle enums, which must be a named int32 type.
  123. if t.Kind() == reflect.Int32 {
  124. return newEnumConverter(t, fd)
  125. }
  126. case pref.MessageKind, pref.GroupKind:
  127. return newMessageConverter(t)
  128. }
  129. panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
  130. }
  131. func (c *scalarConverter) PBValueOf(v reflect.Value) pref.Value {
  132. if v.Type() != c.goType {
  133. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  134. }
  135. if c.goType.Kind() == reflect.String && c.pbType.Kind() == reflect.Slice && v.Len() == 0 {
  136. return pref.ValueOf([]byte(nil)) // ensure empty string is []byte(nil)
  137. }
  138. return pref.ValueOf(v.Convert(c.pbType).Interface())
  139. }
  140. func (c *scalarConverter) GoValueOf(v pref.Value) reflect.Value {
  141. rv := reflect.ValueOf(v.Interface())
  142. if rv.Type() != c.pbType {
  143. panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.pbType))
  144. }
  145. if c.pbType.Kind() == reflect.String && c.goType.Kind() == reflect.Slice && rv.Len() == 0 {
  146. return reflect.Zero(c.goType) // ensure empty string is []byte(nil)
  147. }
  148. return rv.Convert(c.goType)
  149. }
  150. func (c *scalarConverter) New() pref.Value {
  151. if c.pbType == bytesType {
  152. return pref.ValueOf(append(([]byte)(nil), c.def.Bytes()...))
  153. }
  154. return c.def
  155. }
  156. func (c *scalarConverter) Zero() pref.Value {
  157. return c.New()
  158. }
  159. type enumConverter struct {
  160. goType reflect.Type
  161. def pref.Value
  162. }
  163. func newEnumConverter(goType reflect.Type, fd pref.FieldDescriptor) Converter {
  164. var def pref.Value
  165. if fd.Cardinality() == pref.Repeated {
  166. def = pref.ValueOf(fd.Enum().Values().Get(0).Number())
  167. } else {
  168. def = fd.Default()
  169. }
  170. return &enumConverter{goType, def}
  171. }
  172. func (c *enumConverter) PBValueOf(v reflect.Value) pref.Value {
  173. if v.Type() != c.goType {
  174. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  175. }
  176. return pref.ValueOf(pref.EnumNumber(v.Int()))
  177. }
  178. func (c *enumConverter) GoValueOf(v pref.Value) reflect.Value {
  179. return reflect.ValueOf(v.Enum()).Convert(c.goType)
  180. }
  181. func (c *enumConverter) New() pref.Value {
  182. return c.def
  183. }
  184. func (c *enumConverter) Zero() pref.Value {
  185. return c.def
  186. }
  187. type messageConverter struct {
  188. goType reflect.Type
  189. }
  190. func newMessageConverter(goType reflect.Type) Converter {
  191. return &messageConverter{goType}
  192. }
  193. func (c *messageConverter) PBValueOf(v reflect.Value) pref.Value {
  194. if v.Type() != c.goType {
  195. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  196. }
  197. if m, ok := v.Interface().(pref.ProtoMessage); ok {
  198. return pref.ValueOf(m.ProtoReflect())
  199. }
  200. return pref.ValueOf(legacyWrapMessage(v).ProtoReflect())
  201. }
  202. func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value {
  203. m := v.Message()
  204. var rv reflect.Value
  205. if u, ok := m.(Unwrapper); ok {
  206. rv = reflect.ValueOf(u.ProtoUnwrap())
  207. } else {
  208. rv = reflect.ValueOf(m.Interface())
  209. }
  210. if rv.Type() != c.goType {
  211. panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.goType))
  212. }
  213. return rv
  214. }
  215. func (c *messageConverter) New() pref.Value {
  216. return c.PBValueOf(reflect.New(c.goType.Elem()))
  217. }
  218. func (c *messageConverter) Zero() pref.Value {
  219. return c.PBValueOf(reflect.Zero(c.goType))
  220. }