message_field.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  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. "google.golang.org/protobuf/internal/encoding/wire"
  10. pvalue "google.golang.org/protobuf/internal/value"
  11. pref "google.golang.org/protobuf/reflect/protoreflect"
  12. piface "google.golang.org/protobuf/runtime/protoiface"
  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. // These fields are used for fast-path functions.
  24. funcs pointerCoderFuncs // fast-path per-field functions
  25. num pref.FieldNumber // field number
  26. offset offset // struct field offset
  27. wiretag uint64 // field tag (number + wire type)
  28. tagsize int // size of the varint-encoded tag
  29. isPointer bool // true if IsNil may be called on the struct field
  30. isRequired bool // true if field is required
  31. }
  32. func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, ot reflect.Type) fieldInfo {
  33. ft := fs.Type
  34. if ft.Kind() != reflect.Interface {
  35. panic(fmt.Sprintf("invalid type: got %v, want interface kind", ft))
  36. }
  37. if ot.Kind() != reflect.Struct {
  38. panic(fmt.Sprintf("invalid type: got %v, want struct kind", ot))
  39. }
  40. if !reflect.PtrTo(ot).Implements(ft) {
  41. panic(fmt.Sprintf("invalid type: %v does not implement %v", ot, ft))
  42. }
  43. conv, _ := newConverter(ot.Field(0).Type, fd.Kind())
  44. var frozenEmpty pref.Value
  45. if conv.NewMessage != nil {
  46. frozenEmpty = pref.ValueOf(frozenMessage{conv.NewMessage()})
  47. }
  48. // TODO: Implement unsafe fast path?
  49. fieldOffset := offsetOf(fs)
  50. return fieldInfo{
  51. // NOTE: The logic below intentionally assumes that oneof fields are
  52. // well-formatted. That is, the oneof interface never contains a
  53. // typed nil pointer to one of the wrapper structs.
  54. fieldDesc: fd,
  55. has: func(p pointer) bool {
  56. if p.IsNil() {
  57. return false
  58. }
  59. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  60. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  61. return false
  62. }
  63. return true
  64. },
  65. clear: func(p pointer) {
  66. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  67. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  68. return
  69. }
  70. rv.Set(reflect.Zero(rv.Type()))
  71. },
  72. get: func(p pointer) pref.Value {
  73. if p.IsNil() {
  74. if frozenEmpty.IsValid() {
  75. return frozenEmpty
  76. }
  77. return defaultValueOf(fd)
  78. }
  79. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  80. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  81. if frozenEmpty.IsValid() {
  82. return frozenEmpty
  83. }
  84. return defaultValueOf(fd)
  85. }
  86. rv = rv.Elem().Elem().Field(0)
  87. return conv.PBValueOf(rv)
  88. },
  89. set: func(p pointer, v pref.Value) {
  90. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  91. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  92. rv.Set(reflect.New(ot))
  93. }
  94. rv = rv.Elem().Elem().Field(0)
  95. rv.Set(conv.GoValueOf(v))
  96. },
  97. mutable: func(p pointer) pref.Value {
  98. if conv.NewMessage == nil {
  99. panic("invalid Mutable on field with non-composite type")
  100. }
  101. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  102. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  103. rv.Set(reflect.New(ot))
  104. }
  105. rv = rv.Elem().Elem().Field(0)
  106. if rv.IsNil() {
  107. rv.Set(conv.GoValueOf(pref.ValueOf(conv.NewMessage())))
  108. }
  109. return conv.PBValueOf(rv)
  110. },
  111. newMessage: conv.NewMessage,
  112. offset: fieldOffset,
  113. isPointer: true,
  114. }
  115. }
  116. func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
  117. ft := fs.Type
  118. if ft.Kind() != reflect.Map {
  119. panic(fmt.Sprintf("invalid type: got %v, want map kind", ft))
  120. }
  121. keyConv, _ := newConverter(ft.Key(), fd.MapKey().Kind())
  122. valConv, _ := newConverter(ft.Elem(), fd.MapValue().Kind())
  123. wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
  124. frozenEmpty := pref.ValueOf(frozenMap{
  125. pvalue.MapOf(reflect.Zero(reflect.PtrTo(fs.Type)).Interface(), keyConv, valConv),
  126. })
  127. // TODO: Implement unsafe fast path?
  128. fieldOffset := offsetOf(fs)
  129. return fieldInfo{
  130. fieldDesc: fd,
  131. has: func(p pointer) bool {
  132. if p.IsNil() {
  133. return false
  134. }
  135. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  136. return rv.Len() > 0
  137. },
  138. clear: func(p pointer) {
  139. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  140. rv.Set(reflect.Zero(rv.Type()))
  141. },
  142. get: func(p pointer) pref.Value {
  143. if p.IsNil() {
  144. return frozenEmpty
  145. }
  146. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  147. if rv.IsNil() {
  148. return frozenEmpty
  149. }
  150. return pref.ValueOf(pvalue.MapOf(rv.Addr().Interface(), keyConv, valConv))
  151. },
  152. set: func(p pointer, v pref.Value) {
  153. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  154. rv.Set(reflect.ValueOf(v.Map().(pvalue.Unwrapper).ProtoUnwrap()).Elem())
  155. },
  156. mutable: func(p pointer) pref.Value {
  157. v := p.Apply(fieldOffset).AsIfaceOf(fs.Type)
  158. return pref.ValueOf(pvalue.MapOf(v, keyConv, valConv))
  159. },
  160. funcs: encoderFuncsForMap(fd, ft),
  161. offset: fieldOffset,
  162. wiretag: wiretag,
  163. tagsize: wire.SizeVarint(wiretag),
  164. isPointer: true,
  165. }
  166. }
  167. func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
  168. ft := fs.Type
  169. if ft.Kind() != reflect.Slice {
  170. panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft))
  171. }
  172. conv, _ := newConverter(ft.Elem(), fd.Kind())
  173. var wiretag uint64
  174. if !fd.IsPacked() {
  175. wiretag = wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
  176. } else {
  177. wiretag = wire.EncodeTag(fd.Number(), wire.BytesType)
  178. }
  179. frozenEmpty := pref.ValueOf(frozenList{
  180. pvalue.ListOf(reflect.Zero(reflect.PtrTo(fs.Type)).Interface(), conv),
  181. })
  182. // TODO: Implement unsafe fast path?
  183. fieldOffset := offsetOf(fs)
  184. return fieldInfo{
  185. fieldDesc: fd,
  186. has: func(p pointer) bool {
  187. if p.IsNil() {
  188. return false
  189. }
  190. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  191. return rv.Len() > 0
  192. },
  193. clear: func(p pointer) {
  194. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  195. rv.Set(reflect.Zero(rv.Type()))
  196. },
  197. get: func(p pointer) pref.Value {
  198. if p.IsNil() {
  199. return frozenEmpty
  200. }
  201. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  202. if rv.Len() == 0 {
  203. return frozenEmpty
  204. }
  205. return pref.ValueOf(pvalue.ListOf(rv.Addr().Interface(), conv))
  206. },
  207. set: func(p pointer, v pref.Value) {
  208. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  209. rv.Set(reflect.ValueOf(v.List().(pvalue.Unwrapper).ProtoUnwrap()).Elem())
  210. },
  211. mutable: func(p pointer) pref.Value {
  212. v := p.Apply(fieldOffset).AsIfaceOf(fs.Type)
  213. return pref.ValueOf(pvalue.ListOf(v, conv))
  214. },
  215. funcs: fieldCoder(fd, ft),
  216. offset: fieldOffset,
  217. wiretag: wiretag,
  218. tagsize: wire.SizeVarint(wiretag),
  219. isPointer: true,
  220. }
  221. }
  222. var emptyBytes = reflect.ValueOf([]byte{})
  223. func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
  224. ft := fs.Type
  225. funcs := fieldCoder(fd, ft)
  226. nullable := fd.Syntax() == pref.Proto2
  227. if nullable {
  228. if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
  229. panic(fmt.Sprintf("invalid type: got %v, want pointer", ft))
  230. }
  231. if ft.Kind() == reflect.Ptr {
  232. ft = ft.Elem()
  233. }
  234. }
  235. conv, _ := newConverter(ft, fd.Kind())
  236. wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
  237. // TODO: Implement unsafe fast path?
  238. fieldOffset := offsetOf(fs)
  239. return fieldInfo{
  240. fieldDesc: fd,
  241. has: func(p pointer) bool {
  242. if p.IsNil() {
  243. return false
  244. }
  245. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  246. if nullable {
  247. return !rv.IsNil()
  248. }
  249. switch rv.Kind() {
  250. case reflect.Bool:
  251. return rv.Bool()
  252. case reflect.Int32, reflect.Int64:
  253. return rv.Int() != 0
  254. case reflect.Uint32, reflect.Uint64:
  255. return rv.Uint() != 0
  256. case reflect.Float32, reflect.Float64:
  257. return rv.Float() != 0 || math.Signbit(rv.Float())
  258. case reflect.String, reflect.Slice:
  259. return rv.Len() > 0
  260. default:
  261. panic(fmt.Sprintf("invalid type: %v", rv.Type())) // should never happen
  262. }
  263. },
  264. clear: func(p pointer) {
  265. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  266. rv.Set(reflect.Zero(rv.Type()))
  267. },
  268. get: func(p pointer) pref.Value {
  269. if p.IsNil() {
  270. return defaultValueOf(fd)
  271. }
  272. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  273. if nullable {
  274. if rv.IsNil() {
  275. return defaultValueOf(fd)
  276. }
  277. if rv.Kind() == reflect.Ptr {
  278. rv = rv.Elem()
  279. }
  280. }
  281. return conv.PBValueOf(rv)
  282. },
  283. set: func(p pointer, v pref.Value) {
  284. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  285. if nullable && rv.Kind() == reflect.Ptr {
  286. if rv.IsNil() {
  287. rv.Set(reflect.New(ft))
  288. }
  289. rv = rv.Elem()
  290. }
  291. rv.Set(conv.GoValueOf(v))
  292. if nullable && rv.Kind() == reflect.Slice && rv.IsNil() {
  293. rv.Set(emptyBytes)
  294. }
  295. },
  296. funcs: funcs,
  297. offset: fieldOffset,
  298. isPointer: nullable,
  299. isRequired: fd.Cardinality() == pref.Required,
  300. wiretag: wiretag,
  301. tagsize: wire.SizeVarint(wiretag),
  302. }
  303. }
  304. func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
  305. ft := fs.Type
  306. conv, _ := newConverter(ft, fd.Kind())
  307. wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
  308. frozenEmpty := pref.ValueOf(frozenMessage{conv.NewMessage()})
  309. // TODO: Implement unsafe fast path?
  310. fieldOffset := offsetOf(fs)
  311. return fieldInfo{
  312. fieldDesc: fd,
  313. has: func(p pointer) bool {
  314. if p.IsNil() {
  315. return false
  316. }
  317. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  318. return !rv.IsNil()
  319. },
  320. clear: func(p pointer) {
  321. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  322. rv.Set(reflect.Zero(rv.Type()))
  323. },
  324. get: func(p pointer) pref.Value {
  325. if p.IsNil() {
  326. return frozenEmpty
  327. }
  328. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  329. if rv.IsNil() {
  330. return frozenEmpty
  331. }
  332. return conv.PBValueOf(rv)
  333. },
  334. set: func(p pointer, v pref.Value) {
  335. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  336. rv.Set(conv.GoValueOf(v))
  337. if rv.IsNil() {
  338. panic("invalid nil pointer")
  339. }
  340. },
  341. mutable: func(p pointer) pref.Value {
  342. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  343. if rv.IsNil() {
  344. rv.Set(conv.GoValueOf(pref.ValueOf(conv.NewMessage())))
  345. }
  346. return conv.PBValueOf(rv)
  347. },
  348. newMessage: conv.NewMessage,
  349. funcs: fieldCoder(fd, ft),
  350. offset: fieldOffset,
  351. isPointer: true,
  352. isRequired: fd.Cardinality() == pref.Required,
  353. wiretag: wiretag,
  354. tagsize: wire.SizeVarint(wiretag),
  355. }
  356. }
  357. type oneofInfo struct {
  358. oneofDesc pref.OneofDescriptor
  359. which func(pointer) pref.FieldNumber
  360. }
  361. func makeOneofInfo(od pref.OneofDescriptor, fs reflect.StructField, wrappersByType map[reflect.Type]pref.FieldNumber) *oneofInfo {
  362. fieldOffset := offsetOf(fs)
  363. return &oneofInfo{
  364. oneofDesc: od,
  365. which: func(p pointer) pref.FieldNumber {
  366. if p.IsNil() {
  367. return 0
  368. }
  369. rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
  370. if rv.IsNil() {
  371. return 0
  372. }
  373. return wrappersByType[rv.Elem().Type().Elem()]
  374. },
  375. }
  376. }
  377. var (
  378. enumIfaceV2 = reflect.TypeOf((*pref.Enum)(nil)).Elem()
  379. messageIfaceV1 = reflect.TypeOf((*piface.MessageV1)(nil)).Elem()
  380. messageIfaceV2 = reflect.TypeOf((*pref.ProtoMessage)(nil)).Elem()
  381. )
  382. func newConverter(t reflect.Type, k pref.Kind) (conv pvalue.Converter, isLegacy bool) {
  383. switch k {
  384. case pref.EnumKind:
  385. if t.Kind() == reflect.Int32 && !t.Implements(enumIfaceV2) {
  386. return pvalue.Converter{
  387. PBValueOf: func(v reflect.Value) pref.Value {
  388. if v.Type() != t {
  389. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t))
  390. }
  391. return pref.ValueOf(pref.EnumNumber(v.Int()))
  392. },
  393. GoValueOf: func(v pref.Value) reflect.Value {
  394. return reflect.ValueOf(v.Enum()).Convert(t)
  395. },
  396. NewEnum: func(n pref.EnumNumber) pref.Enum {
  397. return legacyWrapEnum(reflect.ValueOf(n).Convert(t))
  398. },
  399. }, true
  400. }
  401. case pref.MessageKind, pref.GroupKind:
  402. if t.Kind() == reflect.Ptr && t.Implements(messageIfaceV1) && !t.Implements(messageIfaceV2) {
  403. return pvalue.Converter{
  404. PBValueOf: func(v reflect.Value) pref.Value {
  405. if v.Type() != t {
  406. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), t))
  407. }
  408. return pref.ValueOf(Export{}.MessageOf(v.Interface()))
  409. },
  410. GoValueOf: func(v pref.Value) reflect.Value {
  411. rv := reflect.ValueOf(v.Message().(pvalue.Unwrapper).ProtoUnwrap())
  412. if rv.Type() != t {
  413. panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), t))
  414. }
  415. return rv
  416. },
  417. NewMessage: func() pref.Message {
  418. return legacyWrapMessage(reflect.New(t.Elem())).ProtoReflect()
  419. },
  420. }, true
  421. }
  422. }
  423. return pvalue.NewConverter(t, k), false
  424. }
  425. // defaultValueOf returns the default value for the field.
  426. func defaultValueOf(fd pref.FieldDescriptor) pref.Value {
  427. if fd == nil {
  428. return pref.Value{}
  429. }
  430. pv := fd.Default() // invalid Value for messages and repeated fields
  431. if fd.Kind() == pref.BytesKind && pv.IsValid() && len(pv.Bytes()) > 0 {
  432. return pref.ValueOf(append([]byte(nil), pv.Bytes()...)) // copy default bytes for safety
  433. }
  434. return pv
  435. }
  436. // frozenValueOf returns a frozen version of any composite value.
  437. func frozenValueOf(v pref.Value) pref.Value {
  438. switch v := v.Interface().(type) {
  439. case pref.Message:
  440. if _, ok := v.(frozenMessage); !ok {
  441. return pref.ValueOf(frozenMessage{v})
  442. }
  443. case pref.List:
  444. if _, ok := v.(frozenList); !ok {
  445. return pref.ValueOf(frozenList{v})
  446. }
  447. case pref.Map:
  448. if _, ok := v.(frozenMap); !ok {
  449. return pref.ValueOf(frozenMap{v})
  450. }
  451. }
  452. return v
  453. }
  454. type frozenMessage struct{ pref.Message }
  455. func (m frozenMessage) ProtoReflect() pref.Message { return m }
  456. func (m frozenMessage) Interface() pref.ProtoMessage { return m }
  457. func (m frozenMessage) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
  458. m.Message.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
  459. return f(fd, frozenValueOf(v))
  460. })
  461. }
  462. func (m frozenMessage) Get(fd pref.FieldDescriptor) pref.Value {
  463. v := m.Message.Get(fd)
  464. return frozenValueOf(v)
  465. }
  466. func (frozenMessage) Clear(pref.FieldDescriptor) { panic("invalid on read-only Message") }
  467. func (frozenMessage) Set(pref.FieldDescriptor, pref.Value) { panic("invalid on read-only Message") }
  468. func (frozenMessage) Mutable(pref.FieldDescriptor) pref.Value { panic("invalid on read-only Message") }
  469. func (frozenMessage) SetUnknown(pref.RawFields) { panic("invalid on read-only Message") }
  470. type frozenList struct{ pref.List }
  471. func (ls frozenList) Get(i int) pref.Value {
  472. v := ls.List.Get(i)
  473. return frozenValueOf(v)
  474. }
  475. func (frozenList) Set(i int, v pref.Value) { panic("invalid on read-only List") }
  476. func (frozenList) Append(v pref.Value) { panic("invalid on read-only List") }
  477. func (frozenList) Truncate(i int) { panic("invalid on read-only List") }
  478. type frozenMap struct{ pref.Map }
  479. func (ms frozenMap) Get(k pref.MapKey) pref.Value {
  480. v := ms.Map.Get(k)
  481. return frozenValueOf(v)
  482. }
  483. func (ms frozenMap) Range(f func(pref.MapKey, pref.Value) bool) {
  484. ms.Map.Range(func(k pref.MapKey, v pref.Value) bool {
  485. return f(k, frozenValueOf(v))
  486. })
  487. }
  488. func (frozenMap) Set(k pref.MapKey, v pref.Value) { panic("invalid n read-only Map") }
  489. func (frozenMap) Clear(k pref.MapKey) { panic("invalid on read-only Map") }