type.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. // Copyright 2019 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 prototype provides constructors for protoreflect.EnumType,
  5. // protoreflect.MessageType, and protoreflect.ExtensionType.
  6. package prototype
  7. import (
  8. "fmt"
  9. "reflect"
  10. "sync"
  11. "google.golang.org/protobuf/internal/descfmt"
  12. "google.golang.org/protobuf/internal/value"
  13. "google.golang.org/protobuf/reflect/protoreflect"
  14. )
  15. // Enum is a protoreflect.EnumType which combines a
  16. // protoreflect.EnumDescriptor with a constructor function.
  17. //
  18. // Both EnumDescriptor and NewEnum must be populated.
  19. // Once constructed, the exported fields must not be modified.
  20. type Enum struct {
  21. protoreflect.EnumDescriptor
  22. // NewEnum constructs a new protoreflect.Enum representing the provided
  23. // enum number. The returned Go type must be identical for every call.
  24. NewEnum func(protoreflect.EnumNumber) protoreflect.Enum
  25. once sync.Once
  26. goType reflect.Type
  27. }
  28. func (t *Enum) New(n protoreflect.EnumNumber) protoreflect.Enum {
  29. e := t.NewEnum(n)
  30. t.once.Do(func() {
  31. t.goType = reflect.TypeOf(e)
  32. if e.Descriptor() != t.Descriptor() {
  33. panic(fmt.Sprintf("mismatching enum descriptor: got %v, want %v", e.Descriptor(), t.Descriptor()))
  34. }
  35. if e.Descriptor().IsPlaceholder() {
  36. panic("enum descriptor must not be a placeholder")
  37. }
  38. })
  39. if t.goType != reflect.TypeOf(e) {
  40. panic(fmt.Sprintf("mismatching types for enum: got %T, want %v", e, t.goType))
  41. }
  42. return e
  43. }
  44. func (t *Enum) GoType() reflect.Type {
  45. t.New(0) // initialize t.typ
  46. return t.goType
  47. }
  48. func (t *Enum) Descriptor() protoreflect.EnumDescriptor {
  49. return t.EnumDescriptor
  50. }
  51. func (t *Enum) Format(s fmt.State, r rune) {
  52. descfmt.FormatDesc(s, r, t)
  53. }
  54. // Message is a protoreflect.MessageType which combines a
  55. // protoreflect.MessageDescriptor with a constructor function.
  56. //
  57. // Both MessageDescriptor and NewMessage must be populated.
  58. // Once constructed, the exported fields must not be modified.
  59. type Message struct {
  60. protoreflect.MessageDescriptor
  61. // NewMessage constructs an empty, newly allocated protoreflect.Message.
  62. // The returned Go type must be identical for every call.
  63. NewMessage func() protoreflect.Message
  64. once sync.Once
  65. goType reflect.Type
  66. }
  67. func (t *Message) New() protoreflect.Message {
  68. m := t.NewMessage()
  69. mi := m.Interface()
  70. t.once.Do(func() {
  71. t.goType = reflect.TypeOf(mi)
  72. if m.Descriptor() != t.Descriptor() {
  73. panic(fmt.Sprintf("mismatching message descriptor: got %v, want %v", m.Descriptor(), t.Descriptor()))
  74. }
  75. if m.Descriptor().IsPlaceholder() {
  76. panic("message descriptor must not be a placeholder")
  77. }
  78. })
  79. if t.goType != reflect.TypeOf(mi) {
  80. panic(fmt.Sprintf("mismatching types for message: got %T, want %v", mi, t.goType))
  81. }
  82. return m
  83. }
  84. func (t *Message) GoType() reflect.Type {
  85. t.New() // initialize t.goType
  86. return t.goType
  87. }
  88. func (t *Message) Descriptor() protoreflect.MessageDescriptor {
  89. return t.MessageDescriptor
  90. }
  91. func (t *Message) Format(s fmt.State, r rune) {
  92. descfmt.FormatDesc(s, r, t)
  93. }
  94. // Extension is a protoreflect.ExtensionType which combines a
  95. // protoreflect.ExtensionDescriptor with a constructor function.
  96. //
  97. // ExtensionDescriptor must be populated, while NewEnum or NewMessage must
  98. // populated depending on the kind of the extension field.
  99. // Once constructed, the exported fields must not be modified.
  100. type Extension struct {
  101. protoreflect.ExtensionDescriptor
  102. // NewEnum constructs a new enum (see Enum.NewEnum).
  103. // This must be populated if and only if ExtensionDescriptor.Kind
  104. // is a protoreflect.EnumKind.
  105. NewEnum func(protoreflect.EnumNumber) protoreflect.Enum
  106. // NewMessage constructs a new message (see Enum.NewMessage).
  107. // This must be populated if and only if ExtensionDescriptor.Kind
  108. // is a protoreflect.MessageKind or protoreflect.GroupKind.
  109. NewMessage func() protoreflect.Message
  110. // TODO: Allow users to manually set new, valueOf, and interfaceOf.
  111. // This allows users to implement custom composite types (e.g., List) or
  112. // custom Go types for primitives (e.g., int32).
  113. once sync.Once
  114. goType reflect.Type
  115. new func() protoreflect.Value
  116. valueOf func(v interface{}) protoreflect.Value
  117. interfaceOf func(v protoreflect.Value) interface{}
  118. }
  119. func (t *Extension) New() protoreflect.Value {
  120. t.lazyInit()
  121. pv := t.new()
  122. v := t.interfaceOf(pv)
  123. if reflect.TypeOf(v) != t.goType {
  124. panic(fmt.Sprintf("invalid type: got %T, want %v", v, t.goType))
  125. }
  126. return pv
  127. }
  128. func (t *Extension) ValueOf(v interface{}) protoreflect.Value {
  129. t.lazyInit()
  130. if reflect.TypeOf(v) != t.goType {
  131. panic(fmt.Sprintf("invalid type: got %T, want %v", v, t.goType))
  132. }
  133. return t.valueOf(v)
  134. }
  135. func (t *Extension) InterfaceOf(v protoreflect.Value) interface{} {
  136. t.lazyInit()
  137. vi := t.interfaceOf(v)
  138. if reflect.TypeOf(vi) != t.goType {
  139. panic(fmt.Sprintf("invalid type: got %T, want %v", vi, t.goType))
  140. }
  141. return vi
  142. }
  143. // GoType is the type of the extension field.
  144. // The type is T for scalars and *[]T for lists (maps are not allowed).
  145. // The type T is determined as follows:
  146. //
  147. // +------------+-------------------------------------+
  148. // | Go type | Protobuf kind |
  149. // +------------+-------------------------------------+
  150. // | bool | BoolKind |
  151. // | int32 | Int32Kind, Sint32Kind, Sfixed32Kind |
  152. // | int64 | Int64Kind, Sint64Kind, Sfixed64Kind |
  153. // | uint32 | Uint32Kind, Fixed32Kind |
  154. // | uint64 | Uint64Kind, Fixed64Kind |
  155. // | float32 | FloatKind |
  156. // | float64 | DoubleKind |
  157. // | string | StringKind |
  158. // | []byte | BytesKind |
  159. // | E | EnumKind |
  160. // | M | MessageKind, GroupKind |
  161. // +------------+-------------------------------------+
  162. //
  163. // The type E is the concrete enum type returned by NewEnum,
  164. // which is often, but not required to be, a named int32 type.
  165. // The type M is the concrete message type returned by NewMessage,
  166. // which is often, but not required to be, a pointer to a named struct type.
  167. func (t *Extension) GoType() reflect.Type {
  168. t.lazyInit()
  169. return t.goType
  170. }
  171. func (t *Extension) Descriptor() protoreflect.ExtensionDescriptor {
  172. return t.ExtensionDescriptor
  173. }
  174. func (t *Extension) Format(s fmt.State, r rune) {
  175. descfmt.FormatDesc(s, r, t)
  176. }
  177. func (t *Extension) lazyInit() {
  178. t.once.Do(func() {
  179. switch t.Kind() {
  180. case protoreflect.EnumKind:
  181. if t.NewEnum == nil || t.NewMessage != nil {
  182. panic("NewEnum alone must be set")
  183. }
  184. e := t.NewEnum(0)
  185. if e.Descriptor() != t.Enum() {
  186. panic(fmt.Sprintf("mismatching enum descriptor: got %v, want %v", e.Descriptor(), t.Enum()))
  187. }
  188. t.goType = reflect.TypeOf(e)
  189. case protoreflect.MessageKind, protoreflect.GroupKind:
  190. if t.NewEnum != nil || t.NewMessage == nil {
  191. panic("NewMessage alone must be set")
  192. }
  193. m := t.NewMessage()
  194. if m.Descriptor() != t.Message() {
  195. panic(fmt.Sprintf("mismatching message descriptor: got %v, want %v", m.Descriptor(), t.Message()))
  196. }
  197. t.goType = reflect.TypeOf(m.Interface())
  198. default:
  199. if t.NewEnum != nil || t.NewMessage != nil {
  200. panic("neither NewEnum nor NewMessage may be set")
  201. }
  202. t.goType = goTypeForPBKind[t.Kind()]
  203. }
  204. switch t.Cardinality() {
  205. case protoreflect.Optional:
  206. switch t.Kind() {
  207. case protoreflect.EnumKind:
  208. t.new = func() protoreflect.Value {
  209. return t.Default()
  210. }
  211. t.valueOf = func(v interface{}) protoreflect.Value {
  212. ev := v.(protoreflect.Enum)
  213. return protoreflect.ValueOf(ev.Number())
  214. }
  215. t.interfaceOf = func(v protoreflect.Value) interface{} {
  216. return t.NewEnum(v.Enum())
  217. }
  218. case protoreflect.MessageKind, protoreflect.GroupKind:
  219. t.new = func() protoreflect.Value {
  220. return protoreflect.ValueOf(t.NewMessage())
  221. }
  222. t.valueOf = func(v interface{}) protoreflect.Value {
  223. mv := v.(protoreflect.ProtoMessage).ProtoReflect()
  224. return protoreflect.ValueOf(mv)
  225. }
  226. t.interfaceOf = func(v protoreflect.Value) interface{} {
  227. return v.Message().Interface()
  228. }
  229. default:
  230. t.new = func() protoreflect.Value {
  231. v := t.Default()
  232. if t.Kind() == protoreflect.BytesKind {
  233. // Copy default bytes to avoid aliasing the original.
  234. v = protoreflect.ValueOf(append([]byte(nil), v.Bytes()...))
  235. }
  236. return v
  237. }
  238. t.valueOf = func(v interface{}) protoreflect.Value {
  239. return protoreflect.ValueOf(v)
  240. }
  241. t.interfaceOf = func(v protoreflect.Value) interface{} {
  242. return v.Interface()
  243. }
  244. }
  245. case protoreflect.Repeated:
  246. var conv value.Converter
  247. elemType := t.goType
  248. switch t.Kind() {
  249. case protoreflect.EnumKind:
  250. conv = value.Converter{
  251. PBValueOf: func(v reflect.Value) protoreflect.Value {
  252. if v.Type() != elemType {
  253. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), elemType))
  254. }
  255. e := v.Interface().(protoreflect.Enum)
  256. return protoreflect.ValueOf(e.Number())
  257. },
  258. GoValueOf: func(v protoreflect.Value) reflect.Value {
  259. rv := reflect.ValueOf(t.NewEnum(v.Enum()))
  260. if rv.Type() != elemType {
  261. panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), elemType))
  262. }
  263. return rv
  264. },
  265. NewEnum: t.NewEnum,
  266. }
  267. case protoreflect.MessageKind, protoreflect.GroupKind:
  268. conv = value.Converter{
  269. PBValueOf: func(v reflect.Value) protoreflect.Value {
  270. if v.Type() != elemType {
  271. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), elemType))
  272. }
  273. m := v.Interface().(protoreflect.ProtoMessage).ProtoReflect()
  274. return protoreflect.ValueOf(m)
  275. },
  276. GoValueOf: func(v protoreflect.Value) reflect.Value {
  277. rv := reflect.ValueOf(v.Message().Interface())
  278. if rv.Type() != elemType {
  279. panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), elemType))
  280. }
  281. return rv
  282. },
  283. NewMessage: t.NewMessage,
  284. }
  285. default:
  286. conv = value.NewConverter(elemType, t.Kind())
  287. }
  288. t.goType = reflect.PtrTo(reflect.SliceOf(elemType))
  289. t.new = func() protoreflect.Value {
  290. v := reflect.New(t.goType.Elem()).Interface()
  291. return protoreflect.ValueOf(value.ListOf(v, conv))
  292. }
  293. t.valueOf = func(v interface{}) protoreflect.Value {
  294. return protoreflect.ValueOf(value.ListOf(v, conv))
  295. }
  296. t.interfaceOf = func(v protoreflect.Value) interface{} {
  297. return v.List().(value.Unwrapper).ProtoUnwrap()
  298. }
  299. default:
  300. panic(fmt.Sprintf("invalid cardinality: %v", t.Cardinality()))
  301. }
  302. })
  303. }
  304. var goTypeForPBKind = map[protoreflect.Kind]reflect.Type{
  305. protoreflect.BoolKind: reflect.TypeOf(bool(false)),
  306. protoreflect.Int32Kind: reflect.TypeOf(int32(0)),
  307. protoreflect.Sint32Kind: reflect.TypeOf(int32(0)),
  308. protoreflect.Sfixed32Kind: reflect.TypeOf(int32(0)),
  309. protoreflect.Int64Kind: reflect.TypeOf(int64(0)),
  310. protoreflect.Sint64Kind: reflect.TypeOf(int64(0)),
  311. protoreflect.Sfixed64Kind: reflect.TypeOf(int64(0)),
  312. protoreflect.Uint32Kind: reflect.TypeOf(uint32(0)),
  313. protoreflect.Fixed32Kind: reflect.TypeOf(uint32(0)),
  314. protoreflect.Uint64Kind: reflect.TypeOf(uint64(0)),
  315. protoreflect.Fixed64Kind: reflect.TypeOf(uint64(0)),
  316. protoreflect.FloatKind: reflect.TypeOf(float32(0)),
  317. protoreflect.DoubleKind: reflect.TypeOf(float64(0)),
  318. protoreflect.StringKind: reflect.TypeOf(string("")),
  319. protoreflect.BytesKind: reflect.TypeOf([]byte(nil)),
  320. }
  321. var (
  322. _ protoreflect.EnumType = (*Enum)(nil)
  323. _ protoreflect.MessageType = (*Message)(nil)
  324. _ protoreflect.ExtensionType = (*Extension)(nil)
  325. )