message_field.go 14 KB

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