message_reflect_field.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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. "math"
  8. "reflect"
  9. "sync"
  10. "google.golang.org/protobuf/internal/flags"
  11. pref "google.golang.org/protobuf/reflect/protoreflect"
  12. preg "google.golang.org/protobuf/reflect/protoregistry"
  13. )
  14. type fieldInfo struct {
  15. fieldDesc pref.FieldDescriptor
  16. // These fields are used for protobuf reflection support.
  17. has func(pointer) bool
  18. clear func(pointer)
  19. get func(pointer) pref.Value
  20. set func(pointer, pref.Value)
  21. mutable func(pointer) pref.Value
  22. newMessage func() pref.Message
  23. newField func() pref.Value
  24. }
  25. func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo {
  26. ft := fs.Type
  27. if ft.Kind() != reflect.Interface {
  28. panic(fmt.Sprintf("invalid type: got %v, want interface kind", ft))
  29. }
  30. if ot.Kind() != reflect.Struct {
  31. panic(fmt.Sprintf("invalid type: got %v, want struct kind", ot))
  32. }
  33. if !reflect.PtrTo(ot).Implements(ft) {
  34. panic(fmt.Sprintf("invalid type: %v does not implement %v", ot, ft))
  35. }
  36. conv := NewConverter(ot.Field(0).Type, fd)
  37. isMessage := fd.Message() != nil
  38. // TODO: Implement unsafe fast path?
  39. fieldOffset := offsetOf(fs, x)
  40. return fieldInfo{
  41. // NOTE: The logic below intentionally assumes that oneof fields are
  42. // well-formatted. That is, the oneof interface never contains a
  43. // typed nil pointer to one of the wrapper structs.
  44. fieldDesc: fd,
  45. has: func(p pointer) bool {
  46. if p.IsNil() {
  47. return false
  48. }
  49. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  50. if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
  51. return false
  52. }
  53. return true
  54. },
  55. clear: func(p pointer) {
  56. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  57. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  58. // NOTE: We intentionally don't check for rv.Elem().IsNil()
  59. // so that (*OneofWrapperType)(nil) gets cleared to nil.
  60. return
  61. }
  62. rv.Set(reflect.Zero(rv.Type()))
  63. },
  64. get: func(p pointer) pref.Value {
  65. if p.IsNil() {
  66. return conv.Zero()
  67. }
  68. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  69. if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
  70. return conv.Zero()
  71. }
  72. rv = rv.Elem().Elem().Field(0)
  73. return conv.PBValueOf(rv)
  74. },
  75. set: func(p pointer, v pref.Value) {
  76. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  77. if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
  78. rv.Set(reflect.New(ot))
  79. }
  80. rv = rv.Elem().Elem().Field(0)
  81. rv.Set(conv.GoValueOf(v))
  82. },
  83. mutable: func(p pointer) pref.Value {
  84. if !isMessage {
  85. panic("invalid Mutable on field with non-composite type")
  86. }
  87. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  88. if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
  89. rv.Set(reflect.New(ot))
  90. }
  91. rv = rv.Elem().Elem().Field(0)
  92. if rv.IsNil() {
  93. rv.Set(conv.GoValueOf(pref.ValueOfMessage(conv.New().Message())))
  94. }
  95. return conv.PBValueOf(rv)
  96. },
  97. newMessage: func() pref.Message {
  98. return conv.New().Message()
  99. },
  100. newField: func() pref.Value {
  101. return conv.New()
  102. },
  103. }
  104. }
  105. func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
  106. ft := fs.Type
  107. if ft.Kind() != reflect.Map {
  108. panic(fmt.Sprintf("invalid type: got %v, want map kind", ft))
  109. }
  110. conv := NewConverter(ft, fd)
  111. // TODO: Implement unsafe fast path?
  112. fieldOffset := offsetOf(fs, x)
  113. return fieldInfo{
  114. fieldDesc: fd,
  115. has: func(p pointer) bool {
  116. if p.IsNil() {
  117. return false
  118. }
  119. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  120. return rv.Len() > 0
  121. },
  122. clear: func(p pointer) {
  123. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  124. rv.Set(reflect.Zero(rv.Type()))
  125. },
  126. get: func(p pointer) pref.Value {
  127. if p.IsNil() {
  128. return conv.Zero()
  129. }
  130. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  131. return conv.PBValueOf(rv)
  132. },
  133. set: func(p pointer, v pref.Value) {
  134. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  135. rv.Set(conv.GoValueOf(v))
  136. },
  137. mutable: func(p pointer) pref.Value {
  138. v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  139. if v.IsNil() {
  140. v.Set(reflect.MakeMap(fs.Type))
  141. }
  142. return conv.PBValueOf(v)
  143. },
  144. newField: func() pref.Value {
  145. return conv.New()
  146. },
  147. }
  148. }
  149. func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
  150. ft := fs.Type
  151. if ft.Kind() != reflect.Slice {
  152. panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft))
  153. }
  154. conv := NewConverter(reflect.PtrTo(ft), fd)
  155. // TODO: Implement unsafe fast path?
  156. fieldOffset := offsetOf(fs, x)
  157. return fieldInfo{
  158. fieldDesc: fd,
  159. has: func(p pointer) bool {
  160. if p.IsNil() {
  161. return false
  162. }
  163. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  164. return rv.Len() > 0
  165. },
  166. clear: func(p pointer) {
  167. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  168. rv.Set(reflect.Zero(rv.Type()))
  169. },
  170. get: func(p pointer) pref.Value {
  171. if p.IsNil() {
  172. return conv.Zero()
  173. }
  174. rv := p.Apply(fieldOffset).AsValueOf(fs.Type)
  175. return conv.PBValueOf(rv)
  176. },
  177. set: func(p pointer, v pref.Value) {
  178. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  179. rv.Set(reflect.ValueOf(v.List().(unwrapper).protoUnwrap()).Elem())
  180. },
  181. mutable: func(p pointer) pref.Value {
  182. v := p.Apply(fieldOffset).AsValueOf(fs.Type)
  183. return conv.PBValueOf(v)
  184. },
  185. newField: func() pref.Value {
  186. return conv.New()
  187. },
  188. }
  189. }
  190. var (
  191. nilBytes = reflect.ValueOf([]byte(nil))
  192. emptyBytes = reflect.ValueOf([]byte{})
  193. )
  194. func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
  195. ft := fs.Type
  196. nullable := fd.Syntax() == pref.Proto2
  197. isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8
  198. if nullable {
  199. if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
  200. panic(fmt.Sprintf("invalid type: got %v, want pointer", ft))
  201. }
  202. if ft.Kind() == reflect.Ptr {
  203. ft = ft.Elem()
  204. }
  205. }
  206. conv := NewConverter(ft, fd)
  207. // TODO: Implement unsafe fast path?
  208. fieldOffset := offsetOf(fs, x)
  209. return fieldInfo{
  210. fieldDesc: fd,
  211. has: func(p pointer) bool {
  212. if p.IsNil() {
  213. return false
  214. }
  215. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  216. if nullable {
  217. return !rv.IsNil()
  218. }
  219. switch rv.Kind() {
  220. case reflect.Bool:
  221. return rv.Bool()
  222. case reflect.Int32, reflect.Int64:
  223. return rv.Int() != 0
  224. case reflect.Uint32, reflect.Uint64:
  225. return rv.Uint() != 0
  226. case reflect.Float32, reflect.Float64:
  227. return rv.Float() != 0 || math.Signbit(rv.Float())
  228. case reflect.String, reflect.Slice:
  229. return rv.Len() > 0
  230. default:
  231. panic(fmt.Sprintf("invalid type: %v", rv.Type())) // should never happen
  232. }
  233. },
  234. clear: func(p pointer) {
  235. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  236. rv.Set(reflect.Zero(rv.Type()))
  237. },
  238. get: func(p pointer) pref.Value {
  239. if p.IsNil() {
  240. return conv.Zero()
  241. }
  242. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  243. if nullable {
  244. if rv.IsNil() {
  245. return conv.Zero()
  246. }
  247. if rv.Kind() == reflect.Ptr {
  248. rv = rv.Elem()
  249. }
  250. }
  251. return conv.PBValueOf(rv)
  252. },
  253. set: func(p pointer, v pref.Value) {
  254. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  255. if nullable && rv.Kind() == reflect.Ptr {
  256. if rv.IsNil() {
  257. rv.Set(reflect.New(ft))
  258. }
  259. rv = rv.Elem()
  260. }
  261. rv.Set(conv.GoValueOf(v))
  262. if isBytes && rv.Len() == 0 {
  263. if nullable {
  264. rv.Set(emptyBytes) // preserve presence in proto2
  265. } else {
  266. rv.Set(nilBytes) // do not preserve presence in proto3
  267. }
  268. }
  269. },
  270. newField: func() pref.Value {
  271. return conv.New()
  272. },
  273. }
  274. }
  275. func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldInfo {
  276. if !flags.ProtoLegacy {
  277. panic("no support for proto1 weak fields")
  278. }
  279. var once sync.Once
  280. var messageType pref.MessageType
  281. lazyInit := func() {
  282. once.Do(func() {
  283. messageName := fd.Message().FullName()
  284. messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
  285. if messageType == nil {
  286. panic(fmt.Sprintf("weak message %v is not linked in", messageName))
  287. }
  288. })
  289. }
  290. num := fd.Number()
  291. return fieldInfo{
  292. fieldDesc: fd,
  293. has: func(p pointer) bool {
  294. if p.IsNil() {
  295. return false
  296. }
  297. _, ok := p.Apply(weakOffset).WeakFields().get(num)
  298. return ok
  299. },
  300. clear: func(p pointer) {
  301. p.Apply(weakOffset).WeakFields().clear(num)
  302. },
  303. get: func(p pointer) pref.Value {
  304. lazyInit()
  305. if p.IsNil() {
  306. return pref.ValueOfMessage(messageType.Zero())
  307. }
  308. m, ok := p.Apply(weakOffset).WeakFields().get(num)
  309. if !ok {
  310. return pref.ValueOfMessage(messageType.Zero())
  311. }
  312. return pref.ValueOfMessage(m.ProtoReflect())
  313. },
  314. set: func(p pointer, v pref.Value) {
  315. lazyInit()
  316. m := v.Message()
  317. if m.Descriptor() != messageType.Descriptor() {
  318. panic("mismatching message descriptor")
  319. }
  320. p.Apply(weakOffset).WeakFields().set(num, m.Interface())
  321. },
  322. mutable: func(p pointer) pref.Value {
  323. lazyInit()
  324. fs := p.Apply(weakOffset).WeakFields()
  325. m, ok := fs.get(num)
  326. if !ok {
  327. m = messageType.New().Interface()
  328. fs.set(num, m)
  329. }
  330. return pref.ValueOfMessage(m.ProtoReflect())
  331. },
  332. newMessage: func() pref.Message {
  333. lazyInit()
  334. return messageType.New()
  335. },
  336. newField: func() pref.Value {
  337. lazyInit()
  338. return pref.ValueOfMessage(messageType.New())
  339. },
  340. }
  341. }
  342. func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
  343. ft := fs.Type
  344. conv := NewConverter(ft, fd)
  345. // TODO: Implement unsafe fast path?
  346. fieldOffset := offsetOf(fs, x)
  347. return fieldInfo{
  348. fieldDesc: fd,
  349. has: func(p pointer) bool {
  350. if p.IsNil() {
  351. return false
  352. }
  353. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  354. return !rv.IsNil()
  355. },
  356. clear: func(p pointer) {
  357. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  358. rv.Set(reflect.Zero(rv.Type()))
  359. },
  360. get: func(p pointer) pref.Value {
  361. if p.IsNil() {
  362. return conv.Zero()
  363. }
  364. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  365. return conv.PBValueOf(rv)
  366. },
  367. set: func(p pointer, v pref.Value) {
  368. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  369. rv.Set(conv.GoValueOf(v))
  370. if rv.IsNil() {
  371. panic("invalid nil pointer")
  372. }
  373. },
  374. mutable: func(p pointer) pref.Value {
  375. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  376. if rv.IsNil() {
  377. rv.Set(conv.GoValueOf(conv.New()))
  378. }
  379. return conv.PBValueOf(rv)
  380. },
  381. newMessage: func() pref.Message {
  382. return conv.New().Message()
  383. },
  384. newField: func() pref.Value {
  385. return conv.New()
  386. },
  387. }
  388. }
  389. type oneofInfo struct {
  390. oneofDesc pref.OneofDescriptor
  391. which func(pointer) pref.FieldNumber
  392. }
  393. func makeOneofInfo(od pref.OneofDescriptor, fs reflect.StructField, x exporter, wrappersByType map[reflect.Type]pref.FieldNumber) *oneofInfo {
  394. fieldOffset := offsetOf(fs, x)
  395. return &oneofInfo{
  396. oneofDesc: od,
  397. which: func(p pointer) pref.FieldNumber {
  398. if p.IsNil() {
  399. return 0
  400. }
  401. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  402. if rv.IsNil() {
  403. return 0
  404. }
  405. rv = rv.Elem()
  406. if rv.IsNil() {
  407. return 0
  408. }
  409. return wrappersByType[rv.Type().Elem()]
  410. },
  411. }
  412. }