message_reflect.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  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 impl
  5. import (
  6. "fmt"
  7. "reflect"
  8. "google.golang.org/protobuf/internal/pragma"
  9. pref "google.golang.org/protobuf/reflect/protoreflect"
  10. )
  11. type reflectMessageInfo struct {
  12. fields map[pref.FieldNumber]*fieldInfo
  13. oneofs map[pref.Name]*oneofInfo
  14. getUnknown func(pointer) pref.RawFields
  15. setUnknown func(pointer, pref.RawFields)
  16. extensionMap func(pointer) *extensionMap
  17. nilMessage atomicNilMessage
  18. }
  19. // makeReflectFuncs generates the set of functions to support reflection.
  20. func (mi *MessageInfo) makeReflectFuncs(t reflect.Type, si structInfo) {
  21. mi.makeKnownFieldsFunc(si)
  22. mi.makeUnknownFieldsFunc(t, si)
  23. mi.makeExtensionFieldsFunc(t, si)
  24. }
  25. // makeKnownFieldsFunc generates functions for operations that can be performed
  26. // on each protobuf message field. It takes in a reflect.Type representing the
  27. // Go struct and matches message fields with struct fields.
  28. //
  29. // This code assumes that the struct is well-formed and panics if there are
  30. // any discrepancies.
  31. func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
  32. mi.fields = map[pref.FieldNumber]*fieldInfo{}
  33. md := mi.Desc
  34. for i := 0; i < md.Fields().Len(); i++ {
  35. fd := md.Fields().Get(i)
  36. fs := si.fieldsByNumber[fd.Number()]
  37. var fi fieldInfo
  38. switch {
  39. case fd.ContainingOneof() != nil:
  40. fi = fieldInfoForOneof(fd, si.oneofsByName[fd.ContainingOneof().Name()], mi.Exporter, si.oneofWrappersByNumber[fd.Number()])
  41. case fd.IsMap():
  42. fi = fieldInfoForMap(fd, fs, mi.Exporter)
  43. case fd.IsList():
  44. fi = fieldInfoForList(fd, fs, mi.Exporter)
  45. case fd.IsWeak():
  46. fi = fieldInfoForWeakMessage(fd, si.weakOffset)
  47. case fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind:
  48. fi = fieldInfoForMessage(fd, fs, mi.Exporter)
  49. default:
  50. fi = fieldInfoForScalar(fd, fs, mi.Exporter)
  51. }
  52. mi.fields[fd.Number()] = &fi
  53. }
  54. mi.oneofs = map[pref.Name]*oneofInfo{}
  55. for i := 0; i < md.Oneofs().Len(); i++ {
  56. od := md.Oneofs().Get(i)
  57. mi.oneofs[od.Name()] = makeOneofInfo(od, si.oneofsByName[od.Name()], mi.Exporter, si.oneofWrappersByType)
  58. }
  59. }
  60. func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) {
  61. mi.getUnknown = func(pointer) pref.RawFields { return nil }
  62. mi.setUnknown = func(pointer, pref.RawFields) { return }
  63. if si.unknownOffset.IsValid() {
  64. mi.getUnknown = func(p pointer) pref.RawFields {
  65. if p.IsNil() {
  66. return nil
  67. }
  68. rv := p.Apply(si.unknownOffset).AsValueOf(unknownFieldsType)
  69. return pref.RawFields(*rv.Interface().(*[]byte))
  70. }
  71. mi.setUnknown = func(p pointer, b pref.RawFields) {
  72. if p.IsNil() {
  73. panic("invalid SetUnknown on nil Message")
  74. }
  75. rv := p.Apply(si.unknownOffset).AsValueOf(unknownFieldsType)
  76. *rv.Interface().(*[]byte) = []byte(b)
  77. }
  78. } else {
  79. mi.getUnknown = func(pointer) pref.RawFields {
  80. return nil
  81. }
  82. mi.setUnknown = func(p pointer, _ pref.RawFields) {
  83. if p.IsNil() {
  84. panic("invalid SetUnknown on nil Message")
  85. }
  86. }
  87. }
  88. }
  89. func (mi *MessageInfo) makeExtensionFieldsFunc(t reflect.Type, si structInfo) {
  90. if si.extensionOffset.IsValid() {
  91. mi.extensionMap = func(p pointer) *extensionMap {
  92. if p.IsNil() {
  93. return (*extensionMap)(nil)
  94. }
  95. v := p.Apply(si.extensionOffset).AsValueOf(extensionFieldsType)
  96. return (*extensionMap)(v.Interface().(*map[int32]ExtensionField))
  97. }
  98. } else {
  99. mi.extensionMap = func(pointer) *extensionMap {
  100. return (*extensionMap)(nil)
  101. }
  102. }
  103. }
  104. type extensionMap map[int32]ExtensionField
  105. func (m *extensionMap) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
  106. if m != nil {
  107. for _, x := range *m {
  108. xt := x.GetType()
  109. if !f(xt.TypeDescriptor(), x.Value()) {
  110. return
  111. }
  112. }
  113. }
  114. }
  115. func (m *extensionMap) Has(xt pref.ExtensionType) (ok bool) {
  116. if m != nil {
  117. _, ok = (*m)[int32(xt.TypeDescriptor().Number())]
  118. }
  119. return ok
  120. }
  121. func (m *extensionMap) Clear(xt pref.ExtensionType) {
  122. delete(*m, int32(xt.TypeDescriptor().Number()))
  123. }
  124. func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value {
  125. xd := xt.TypeDescriptor()
  126. if m != nil {
  127. if x, ok := (*m)[int32(xd.Number())]; ok {
  128. return x.Value()
  129. }
  130. }
  131. return xt.Zero()
  132. }
  133. func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) {
  134. if !xt.IsValidValue(v) {
  135. panic(fmt.Sprintf("%v: assigning invalid value", xt.TypeDescriptor().FullName()))
  136. }
  137. if *m == nil {
  138. *m = make(map[int32]ExtensionField)
  139. }
  140. var x ExtensionField
  141. x.Set(xt, v)
  142. (*m)[int32(xt.TypeDescriptor().Number())] = x
  143. }
  144. func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value {
  145. xd := xt.TypeDescriptor()
  146. if xd.Kind() != pref.MessageKind && xd.Kind() != pref.GroupKind && !xd.IsList() && !xd.IsMap() {
  147. panic("invalid Mutable on field with non-composite type")
  148. }
  149. if x, ok := (*m)[int32(xd.Number())]; ok {
  150. return x.Value()
  151. }
  152. v := xt.New()
  153. m.Set(xt, v)
  154. return v
  155. }
  156. // MessageState is a data structure that is nested as the first field in a
  157. // concrete message. It provides a way to implement the ProtoReflect method
  158. // in an allocation-free way without needing to have a shadow Go type generated
  159. // for every message type. This technique only works using unsafe.
  160. //
  161. //
  162. // Example generated code:
  163. //
  164. // type M struct {
  165. // state protoimpl.MessageState
  166. //
  167. // Field1 int32
  168. // Field2 string
  169. // Field3 *BarMessage
  170. // ...
  171. // }
  172. //
  173. // func (m *M) ProtoReflect() protoreflect.Message {
  174. // mi := &file_fizz_buzz_proto_msgInfos[5]
  175. // if protoimpl.UnsafeEnabled && m != nil {
  176. // ms := protoimpl.X.MessageStateOf(Pointer(m))
  177. // if ms.LoadMessageInfo() == nil {
  178. // ms.StoreMessageInfo(mi)
  179. // }
  180. // return ms
  181. // }
  182. // return mi.MessageOf(m)
  183. // }
  184. //
  185. // The MessageState type holds a *MessageInfo, which must be atomically set to
  186. // the message info associated with a given message instance.
  187. // By unsafely converting a *M into a *MessageState, the MessageState object
  188. // has access to all the information needed to implement protobuf reflection.
  189. // It has access to the message info as its first field, and a pointer to the
  190. // MessageState is identical to a pointer to the concrete message value.
  191. //
  192. //
  193. // Requirements:
  194. // • The type M must implement protoreflect.ProtoMessage.
  195. // • The address of m must not be nil.
  196. // • The address of m and the address of m.state must be equal,
  197. // even though they are different Go types.
  198. type MessageState struct {
  199. pragma.NoUnkeyedLiterals
  200. pragma.DoNotCompare
  201. pragma.DoNotCopy
  202. mi *MessageInfo
  203. }
  204. type messageState MessageState
  205. var (
  206. _ pref.Message = (*messageState)(nil)
  207. _ unwrapper = (*messageState)(nil)
  208. )
  209. // messageDataType is a tuple of a pointer to the message data and
  210. // a pointer to the message type. It is a generalized way of providing a
  211. // reflective view over a message instance. The disadvantage of this approach
  212. // is the need to allocate this tuple of 16B.
  213. type messageDataType struct {
  214. p pointer
  215. mi *MessageInfo
  216. }
  217. type (
  218. messageReflectWrapper messageDataType
  219. messageIfaceWrapper messageDataType
  220. )
  221. var (
  222. _ pref.Message = (*messageReflectWrapper)(nil)
  223. _ unwrapper = (*messageReflectWrapper)(nil)
  224. _ pref.ProtoMessage = (*messageIfaceWrapper)(nil)
  225. _ unwrapper = (*messageIfaceWrapper)(nil)
  226. )
  227. // MessageOf returns a reflective view over a message. The input must be a
  228. // pointer to a named Go struct. If the provided type has a ProtoReflect method,
  229. // it must be implemented by calling this method.
  230. func (mi *MessageInfo) MessageOf(m interface{}) pref.Message {
  231. // TODO: Switch the input to be an opaque Pointer.
  232. if reflect.TypeOf(m) != mi.GoReflectType {
  233. panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType))
  234. }
  235. p := pointerOfIface(m)
  236. if p.IsNil() {
  237. return mi.nilMessage.Init(mi)
  238. }
  239. return &messageReflectWrapper{p, mi}
  240. }
  241. func (m *messageReflectWrapper) pointer() pointer { return m.p }
  242. func (m *messageReflectWrapper) messageInfo() *MessageInfo { return m.mi }
  243. func (m *messageIfaceWrapper) ProtoReflect() pref.Message {
  244. return (*messageReflectWrapper)(m)
  245. }
  246. func (m *messageIfaceWrapper) protoUnwrap() interface{} {
  247. return m.p.AsIfaceOf(m.mi.GoReflectType.Elem())
  248. }
  249. // checkField verifies that the provided field descriptor is valid.
  250. // Exactly one of the returned values is populated.
  251. func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.ExtensionType) {
  252. if fi := mi.fields[fd.Number()]; fi != nil {
  253. if fi.fieldDesc != fd {
  254. panic("mismatching field descriptor")
  255. }
  256. return fi, nil
  257. }
  258. if fd.IsExtension() {
  259. if fd.ContainingMessage().FullName() != mi.Desc.FullName() {
  260. // TODO: Should this be exact containing message descriptor match?
  261. panic("mismatching containing message")
  262. }
  263. if !mi.Desc.ExtensionRanges().Has(fd.Number()) {
  264. panic("invalid extension field")
  265. }
  266. xtd, ok := fd.(pref.ExtensionTypeDescriptor)
  267. if !ok {
  268. panic("extension descriptor does not implement ExtensionTypeDescriptor")
  269. }
  270. return nil, xtd.Type()
  271. }
  272. panic("invalid field descriptor")
  273. }