message_reflect.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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.Descriptor(), xt.ValueOf(x.GetValue())) {
  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.Descriptor().Number())]
  118. }
  119. return ok
  120. }
  121. func (m *extensionMap) Clear(xt pref.ExtensionType) {
  122. delete(*m, int32(xt.Descriptor().Number()))
  123. }
  124. func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value {
  125. xd := xt.Descriptor()
  126. if m != nil {
  127. if x, ok := (*m)[int32(xd.Number())]; ok {
  128. return xt.ValueOf(x.GetValue())
  129. }
  130. }
  131. return xt.Zero()
  132. }
  133. func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) {
  134. if *m == nil {
  135. *m = make(map[int32]ExtensionField)
  136. }
  137. var x ExtensionField
  138. x.SetType(xt)
  139. x.SetEagerValue(xt.InterfaceOf(v))
  140. (*m)[int32(xt.Descriptor().Number())] = x
  141. }
  142. func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value {
  143. xd := xt.Descriptor()
  144. if xd.Kind() != pref.MessageKind && xd.Kind() != pref.GroupKind && !xd.IsList() && !xd.IsMap() {
  145. panic("invalid Mutable on field with non-composite type")
  146. }
  147. if x, ok := (*m)[int32(xd.Number())]; ok {
  148. return xt.ValueOf(x.GetValue())
  149. }
  150. v := xt.New()
  151. m.Set(xt, v)
  152. return v
  153. }
  154. // MessageState is a data structure that is nested as the first field in a
  155. // concrete message. It provides a way to implement the ProtoReflect method
  156. // in an allocation-free way without needing to have a shadow Go type generated
  157. // for every message type. This technique only works using unsafe.
  158. //
  159. //
  160. // Example generated code:
  161. //
  162. // type M struct {
  163. // state protoimpl.MessageState
  164. //
  165. // Field1 int32
  166. // Field2 string
  167. // Field3 *BarMessage
  168. // ...
  169. // }
  170. //
  171. // func (m *M) ProtoReflect() protoreflect.Message {
  172. // mi := &file_fizz_buzz_proto_msgInfos[5]
  173. // if protoimpl.UnsafeEnabled && m != nil {
  174. // ms := protoimpl.X.MessageStateOf(Pointer(m))
  175. // if ms.LoadMessageInfo() == nil {
  176. // ms.StoreMessageInfo(mi)
  177. // }
  178. // return ms
  179. // }
  180. // return mi.MessageOf(m)
  181. // }
  182. //
  183. // The MessageState type holds a *MessageInfo, which must be atomically set to
  184. // the message info associated with a given message instance.
  185. // By unsafely converting a *M into a *MessageState, the MessageState object
  186. // has access to all the information needed to implement protobuf reflection.
  187. // It has access to the message info as its first field, and a pointer to the
  188. // MessageState is identical to a pointer to the concrete message value.
  189. //
  190. //
  191. // Requirements:
  192. // • The type M must implement protoreflect.ProtoMessage.
  193. // • The address of m must not be nil.
  194. // • The address of m and the address of m.state must be equal,
  195. // even though they are different Go types.
  196. type MessageState struct {
  197. pragma.NoUnkeyedLiterals
  198. pragma.DoNotCompare
  199. pragma.DoNotCopy
  200. mi *MessageInfo
  201. }
  202. type messageState MessageState
  203. var (
  204. _ pref.Message = (*messageState)(nil)
  205. _ Unwrapper = (*messageState)(nil)
  206. )
  207. // messageDataType is a tuple of a pointer to the message data and
  208. // a pointer to the message type. It is a generalized way of providing a
  209. // reflective view over a message instance. The disadvantage of this approach
  210. // is the need to allocate this tuple of 16B.
  211. type messageDataType struct {
  212. p pointer
  213. mi *MessageInfo
  214. }
  215. type (
  216. messageReflectWrapper messageDataType
  217. messageIfaceWrapper messageDataType
  218. )
  219. var (
  220. _ pref.Message = (*messageReflectWrapper)(nil)
  221. _ Unwrapper = (*messageReflectWrapper)(nil)
  222. _ pref.ProtoMessage = (*messageIfaceWrapper)(nil)
  223. _ Unwrapper = (*messageIfaceWrapper)(nil)
  224. )
  225. // MessageOf returns a reflective view over a message. The input must be a
  226. // pointer to a named Go struct. If the provided type has a ProtoReflect method,
  227. // it must be implemented by calling this method.
  228. func (mi *MessageInfo) MessageOf(m interface{}) pref.Message {
  229. // TODO: Switch the input to be an opaque Pointer.
  230. if reflect.TypeOf(m) != mi.GoReflectType {
  231. panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType))
  232. }
  233. p := pointerOfIface(m)
  234. if p.IsNil() {
  235. return mi.nilMessage.Init(mi)
  236. }
  237. return &messageReflectWrapper{p, mi}
  238. }
  239. func (m *messageReflectWrapper) pointer() pointer { return m.p }
  240. func (m *messageReflectWrapper) messageInfo() *MessageInfo { return m.mi }
  241. func (m *messageIfaceWrapper) ProtoReflect() pref.Message {
  242. return (*messageReflectWrapper)(m)
  243. }
  244. func (m *messageIfaceWrapper) ProtoUnwrap() interface{} {
  245. return m.p.AsIfaceOf(m.mi.GoReflectType.Elem())
  246. }
  247. // checkField verifies that the provided field descriptor is valid.
  248. // Exactly one of the returned values is populated.
  249. func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.ExtensionType) {
  250. if fi := mi.fields[fd.Number()]; fi != nil {
  251. if fi.fieldDesc != fd {
  252. panic("mismatching field descriptor")
  253. }
  254. return fi, nil
  255. }
  256. if fd.IsExtension() {
  257. if fd.ContainingMessage().FullName() != mi.Desc.FullName() {
  258. // TODO: Should this be exact containing message descriptor match?
  259. panic("mismatching containing message")
  260. }
  261. if !mi.Desc.ExtensionRanges().Has(fd.Number()) {
  262. panic("invalid extension field")
  263. }
  264. xtd, ok := fd.(pref.ExtensionTypeDescriptor)
  265. if !ok {
  266. panic("extension descriptor does not implement ExtensionTypeDescriptor")
  267. }
  268. return nil, xtd.Type()
  269. }
  270. panic("invalid field descriptor")
  271. }