convert.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  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. func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter {
  73. defVal := func(fd pref.FieldDescriptor, zero pref.Value) pref.Value {
  74. if fd.Cardinality() == pref.Repeated {
  75. // Default isn't defined for repeated fields.
  76. return zero
  77. }
  78. return fd.Default()
  79. }
  80. switch fd.Kind() {
  81. case pref.BoolKind:
  82. if t.Kind() == reflect.Bool {
  83. return &boolConverter{t, defVal(fd, boolZero)}
  84. }
  85. case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
  86. if t.Kind() == reflect.Int32 {
  87. return &int32Converter{t, defVal(fd, int32Zero)}
  88. }
  89. case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
  90. if t.Kind() == reflect.Int64 {
  91. return &int64Converter{t, defVal(fd, int64Zero)}
  92. }
  93. case pref.Uint32Kind, pref.Fixed32Kind:
  94. if t.Kind() == reflect.Uint32 {
  95. return &uint32Converter{t, defVal(fd, uint32Zero)}
  96. }
  97. case pref.Uint64Kind, pref.Fixed64Kind:
  98. if t.Kind() == reflect.Uint64 {
  99. return &uint64Converter{t, defVal(fd, uint64Zero)}
  100. }
  101. case pref.FloatKind:
  102. if t.Kind() == reflect.Float32 {
  103. return &float32Converter{t, defVal(fd, float32Zero)}
  104. }
  105. case pref.DoubleKind:
  106. if t.Kind() == reflect.Float64 {
  107. return &float64Converter{t, defVal(fd, float64Zero)}
  108. }
  109. case pref.StringKind:
  110. if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
  111. return &stringConverter{t, defVal(fd, stringZero)}
  112. }
  113. case pref.BytesKind:
  114. if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
  115. return &bytesConverter{t, defVal(fd, bytesZero)}
  116. }
  117. case pref.EnumKind:
  118. // Handle enums, which must be a named int32 type.
  119. if t.Kind() == reflect.Int32 {
  120. return newEnumConverter(t, fd)
  121. }
  122. case pref.MessageKind, pref.GroupKind:
  123. return newMessageConverter(t)
  124. }
  125. panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName()))
  126. }
  127. type boolConverter struct {
  128. goType reflect.Type
  129. def pref.Value
  130. }
  131. func (c *boolConverter) 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. return pref.ValueOfBool(v.Bool())
  136. }
  137. func (c *boolConverter) GoValueOf(v pref.Value) reflect.Value {
  138. return reflect.ValueOf(v.Bool()).Convert(c.goType)
  139. }
  140. func (c *boolConverter) New() pref.Value { return c.def }
  141. func (c *boolConverter) Zero() pref.Value { return c.def }
  142. type int32Converter struct {
  143. goType reflect.Type
  144. def pref.Value
  145. }
  146. func (c *int32Converter) PBValueOf(v reflect.Value) pref.Value {
  147. if v.Type() != c.goType {
  148. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  149. }
  150. return pref.ValueOfInt32(int32(v.Int()))
  151. }
  152. func (c *int32Converter) GoValueOf(v pref.Value) reflect.Value {
  153. return reflect.ValueOf(int32(v.Int())).Convert(c.goType)
  154. }
  155. func (c *int32Converter) New() pref.Value { return c.def }
  156. func (c *int32Converter) Zero() pref.Value { return c.def }
  157. type int64Converter struct {
  158. goType reflect.Type
  159. def pref.Value
  160. }
  161. func (c *int64Converter) PBValueOf(v reflect.Value) pref.Value {
  162. if v.Type() != c.goType {
  163. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  164. }
  165. return pref.ValueOfInt64(int64(v.Int()))
  166. }
  167. func (c *int64Converter) GoValueOf(v pref.Value) reflect.Value {
  168. return reflect.ValueOf(int64(v.Int())).Convert(c.goType)
  169. }
  170. func (c *int64Converter) New() pref.Value { return c.def }
  171. func (c *int64Converter) Zero() pref.Value { return c.def }
  172. type uint32Converter struct {
  173. goType reflect.Type
  174. def pref.Value
  175. }
  176. func (c *uint32Converter) PBValueOf(v reflect.Value) pref.Value {
  177. if v.Type() != c.goType {
  178. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  179. }
  180. return pref.ValueOfUint32(uint32(v.Uint()))
  181. }
  182. func (c *uint32Converter) GoValueOf(v pref.Value) reflect.Value {
  183. return reflect.ValueOf(uint32(v.Uint())).Convert(c.goType)
  184. }
  185. func (c *uint32Converter) New() pref.Value { return c.def }
  186. func (c *uint32Converter) Zero() pref.Value { return c.def }
  187. type uint64Converter struct {
  188. goType reflect.Type
  189. def pref.Value
  190. }
  191. func (c *uint64Converter) PBValueOf(v reflect.Value) pref.Value {
  192. if v.Type() != c.goType {
  193. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  194. }
  195. return pref.ValueOfUint64(uint64(v.Uint()))
  196. }
  197. func (c *uint64Converter) GoValueOf(v pref.Value) reflect.Value {
  198. return reflect.ValueOf(uint64(v.Uint())).Convert(c.goType)
  199. }
  200. func (c *uint64Converter) New() pref.Value { return c.def }
  201. func (c *uint64Converter) Zero() pref.Value { return c.def }
  202. type float32Converter struct {
  203. goType reflect.Type
  204. def pref.Value
  205. }
  206. func (c *float32Converter) PBValueOf(v reflect.Value) pref.Value {
  207. if v.Type() != c.goType {
  208. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  209. }
  210. return pref.ValueOfFloat32(float32(v.Float()))
  211. }
  212. func (c *float32Converter) GoValueOf(v pref.Value) reflect.Value {
  213. return reflect.ValueOf(float32(v.Float())).Convert(c.goType)
  214. }
  215. func (c *float32Converter) New() pref.Value { return c.def }
  216. func (c *float32Converter) Zero() pref.Value { return c.def }
  217. type float64Converter struct {
  218. goType reflect.Type
  219. def pref.Value
  220. }
  221. func (c *float64Converter) PBValueOf(v reflect.Value) pref.Value {
  222. if v.Type() != c.goType {
  223. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  224. }
  225. return pref.ValueOfFloat64(float64(v.Float()))
  226. }
  227. func (c *float64Converter) GoValueOf(v pref.Value) reflect.Value {
  228. return reflect.ValueOf(float64(v.Float())).Convert(c.goType)
  229. }
  230. func (c *float64Converter) New() pref.Value { return c.def }
  231. func (c *float64Converter) Zero() pref.Value { return c.def }
  232. type stringConverter struct {
  233. goType reflect.Type
  234. def pref.Value
  235. }
  236. func (c *stringConverter) PBValueOf(v reflect.Value) pref.Value {
  237. if v.Type() != c.goType {
  238. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  239. }
  240. return pref.ValueOfString(v.Convert(stringType).String())
  241. }
  242. func (c *stringConverter) GoValueOf(v pref.Value) reflect.Value {
  243. // pref.Value.String never panics, so we go through an interface
  244. // conversion here to check the type.
  245. s := v.Interface().(string)
  246. if c.goType.Kind() == reflect.Slice && s == "" {
  247. return reflect.Zero(c.goType) // ensure empty string is []byte(nil)
  248. }
  249. return reflect.ValueOf(s).Convert(c.goType)
  250. }
  251. func (c *stringConverter) New() pref.Value { return c.def }
  252. func (c *stringConverter) Zero() pref.Value { return c.def }
  253. type bytesConverter struct {
  254. goType reflect.Type
  255. def pref.Value
  256. }
  257. func (c *bytesConverter) PBValueOf(v reflect.Value) pref.Value {
  258. if v.Type() != c.goType {
  259. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  260. }
  261. if c.goType.Kind() == reflect.String && v.Len() == 0 {
  262. return pref.ValueOfBytes(nil) // ensure empty string is []byte(nil)
  263. }
  264. return pref.ValueOfBytes(v.Convert(bytesType).Bytes())
  265. }
  266. func (c *bytesConverter) GoValueOf(v pref.Value) reflect.Value {
  267. return reflect.ValueOf(v.Bytes()).Convert(c.goType)
  268. }
  269. func (c *bytesConverter) New() pref.Value { return c.def }
  270. func (c *bytesConverter) Zero() pref.Value { return c.def }
  271. type enumConverter struct {
  272. goType reflect.Type
  273. def pref.Value
  274. }
  275. func newEnumConverter(goType reflect.Type, fd pref.FieldDescriptor) Converter {
  276. var def pref.Value
  277. if fd.Cardinality() == pref.Repeated {
  278. def = pref.ValueOf(fd.Enum().Values().Get(0).Number())
  279. } else {
  280. def = fd.Default()
  281. }
  282. return &enumConverter{goType, def}
  283. }
  284. func (c *enumConverter) PBValueOf(v reflect.Value) pref.Value {
  285. if v.Type() != c.goType {
  286. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  287. }
  288. return pref.ValueOf(pref.EnumNumber(v.Int()))
  289. }
  290. func (c *enumConverter) GoValueOf(v pref.Value) reflect.Value {
  291. return reflect.ValueOf(v.Enum()).Convert(c.goType)
  292. }
  293. func (c *enumConverter) New() pref.Value {
  294. return c.def
  295. }
  296. func (c *enumConverter) Zero() pref.Value {
  297. return c.def
  298. }
  299. type messageConverter struct {
  300. goType reflect.Type
  301. }
  302. func newMessageConverter(goType reflect.Type) Converter {
  303. return &messageConverter{goType}
  304. }
  305. func (c *messageConverter) PBValueOf(v reflect.Value) pref.Value {
  306. if v.Type() != c.goType {
  307. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType))
  308. }
  309. if m, ok := v.Interface().(pref.ProtoMessage); ok {
  310. return pref.ValueOf(m.ProtoReflect())
  311. }
  312. return pref.ValueOf(legacyWrapMessage(v).ProtoReflect())
  313. }
  314. func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value {
  315. m := v.Message()
  316. var rv reflect.Value
  317. if u, ok := m.(Unwrapper); ok {
  318. rv = reflect.ValueOf(u.ProtoUnwrap())
  319. } else {
  320. rv = reflect.ValueOf(m.Interface())
  321. }
  322. if rv.Type() != c.goType {
  323. panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), c.goType))
  324. }
  325. return rv
  326. }
  327. func (c *messageConverter) New() pref.Value {
  328. return c.PBValueOf(reflect.New(c.goType.Elem()))
  329. }
  330. func (c *messageConverter) Zero() pref.Value {
  331. return c.PBValueOf(reflect.Zero(c.goType))
  332. }