message_field.go 11 KB

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