codec_field.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  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. pref "google.golang.org/protobuf/reflect/protoreflect"
  9. )
  10. // pointerCoderFuncs is a set of pointer encoding functions.
  11. type pointerCoderFuncs struct {
  12. size func(p pointer, tagsize int, opts marshalOptions) int
  13. marshal func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error)
  14. isInit func(p pointer) error
  15. }
  16. // ifaceCoderFuncs is a set of interface{} encoding functions.
  17. type ifaceCoderFuncs struct {
  18. size func(ival interface{}, tagsize int, opts marshalOptions) int
  19. marshal func(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error)
  20. isInit func(ival interface{}) error
  21. }
  22. // fieldCoder returns pointer functions for a field, used for operating on
  23. // struct fields.
  24. func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
  25. switch {
  26. case fd.IsMap():
  27. return encoderFuncsForMap(fd, ft)
  28. case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
  29. // Repeated fields (not packed).
  30. if ft.Kind() != reflect.Slice {
  31. break
  32. }
  33. ft := ft.Elem()
  34. switch fd.Kind() {
  35. case pref.BoolKind:
  36. if ft.Kind() == reflect.Bool {
  37. return coderBoolSlice
  38. }
  39. case pref.EnumKind:
  40. if ft.Kind() == reflect.Int32 {
  41. return coderEnumSlice
  42. }
  43. case pref.Int32Kind:
  44. if ft.Kind() == reflect.Int32 {
  45. return coderInt32Slice
  46. }
  47. case pref.Sint32Kind:
  48. if ft.Kind() == reflect.Int32 {
  49. return coderSint32Slice
  50. }
  51. case pref.Uint32Kind:
  52. if ft.Kind() == reflect.Uint32 {
  53. return coderUint32Slice
  54. }
  55. case pref.Int64Kind:
  56. if ft.Kind() == reflect.Int64 {
  57. return coderInt64Slice
  58. }
  59. case pref.Sint64Kind:
  60. if ft.Kind() == reflect.Int64 {
  61. return coderSint64Slice
  62. }
  63. case pref.Uint64Kind:
  64. if ft.Kind() == reflect.Uint64 {
  65. return coderUint64Slice
  66. }
  67. case pref.Sfixed32Kind:
  68. if ft.Kind() == reflect.Int32 {
  69. return coderSfixed32Slice
  70. }
  71. case pref.Fixed32Kind:
  72. if ft.Kind() == reflect.Uint32 {
  73. return coderFixed32Slice
  74. }
  75. case pref.FloatKind:
  76. if ft.Kind() == reflect.Float32 {
  77. return coderFloatSlice
  78. }
  79. case pref.Sfixed64Kind:
  80. if ft.Kind() == reflect.Int64 {
  81. return coderSfixed64Slice
  82. }
  83. case pref.Fixed64Kind:
  84. if ft.Kind() == reflect.Uint64 {
  85. return coderFixed64Slice
  86. }
  87. case pref.DoubleKind:
  88. if ft.Kind() == reflect.Float64 {
  89. return coderDoubleSlice
  90. }
  91. case pref.StringKind:
  92. if ft.Kind() == reflect.String && fd.Syntax() == pref.Proto3 {
  93. return coderStringSliceValidateUTF8
  94. }
  95. if ft.Kind() == reflect.String {
  96. return coderStringSlice
  97. }
  98. if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
  99. return coderBytesSlice
  100. }
  101. case pref.BytesKind:
  102. if ft.Kind() == reflect.String {
  103. return coderStringSlice
  104. }
  105. if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
  106. return coderBytesSlice
  107. }
  108. case pref.MessageKind:
  109. return makeMessageSliceFieldCoder(fd, ft)
  110. case pref.GroupKind:
  111. return makeGroupSliceFieldCoder(fd, ft)
  112. }
  113. case fd.Cardinality() == pref.Repeated && fd.IsPacked():
  114. // Packed repeated fields.
  115. //
  116. // Only repeated fields of primitive numeric types
  117. // (Varint, Fixed32, or Fixed64 wire type) can be packed.
  118. if ft.Kind() != reflect.Slice {
  119. break
  120. }
  121. ft := ft.Elem()
  122. switch fd.Kind() {
  123. case pref.BoolKind:
  124. if ft.Kind() == reflect.Bool {
  125. return coderBoolPackedSlice
  126. }
  127. case pref.EnumKind:
  128. if ft.Kind() == reflect.Int32 {
  129. return coderEnumPackedSlice
  130. }
  131. case pref.Int32Kind:
  132. if ft.Kind() == reflect.Int32 {
  133. return coderInt32PackedSlice
  134. }
  135. case pref.Sint32Kind:
  136. if ft.Kind() == reflect.Int32 {
  137. return coderSint32PackedSlice
  138. }
  139. case pref.Uint32Kind:
  140. if ft.Kind() == reflect.Uint32 {
  141. return coderUint32PackedSlice
  142. }
  143. case pref.Int64Kind:
  144. if ft.Kind() == reflect.Int64 {
  145. return coderInt64PackedSlice
  146. }
  147. case pref.Sint64Kind:
  148. if ft.Kind() == reflect.Int64 {
  149. return coderSint64PackedSlice
  150. }
  151. case pref.Uint64Kind:
  152. if ft.Kind() == reflect.Uint64 {
  153. return coderUint64PackedSlice
  154. }
  155. case pref.Sfixed32Kind:
  156. if ft.Kind() == reflect.Int32 {
  157. return coderSfixed32PackedSlice
  158. }
  159. case pref.Fixed32Kind:
  160. if ft.Kind() == reflect.Uint32 {
  161. return coderFixed32PackedSlice
  162. }
  163. case pref.FloatKind:
  164. if ft.Kind() == reflect.Float32 {
  165. return coderFloatPackedSlice
  166. }
  167. case pref.Sfixed64Kind:
  168. if ft.Kind() == reflect.Int64 {
  169. return coderSfixed64PackedSlice
  170. }
  171. case pref.Fixed64Kind:
  172. if ft.Kind() == reflect.Uint64 {
  173. return coderFixed64PackedSlice
  174. }
  175. case pref.DoubleKind:
  176. if ft.Kind() == reflect.Float64 {
  177. return coderDoublePackedSlice
  178. }
  179. }
  180. case fd.Kind() == pref.MessageKind:
  181. return makeMessageFieldCoder(fd, ft)
  182. case fd.Kind() == pref.GroupKind:
  183. return makeGroupFieldCoder(fd, ft)
  184. case fd.Syntax() == pref.Proto3 && fd.ContainingOneof() == nil:
  185. // Populated oneof fields always encode even if set to the zero value,
  186. // which normally are not encoded in proto3.
  187. switch fd.Kind() {
  188. case pref.BoolKind:
  189. if ft.Kind() == reflect.Bool {
  190. return coderBoolNoZero
  191. }
  192. case pref.EnumKind:
  193. if ft.Kind() == reflect.Int32 {
  194. return coderEnumNoZero
  195. }
  196. case pref.Int32Kind:
  197. if ft.Kind() == reflect.Int32 {
  198. return coderInt32NoZero
  199. }
  200. case pref.Sint32Kind:
  201. if ft.Kind() == reflect.Int32 {
  202. return coderSint32NoZero
  203. }
  204. case pref.Uint32Kind:
  205. if ft.Kind() == reflect.Uint32 {
  206. return coderUint32NoZero
  207. }
  208. case pref.Int64Kind:
  209. if ft.Kind() == reflect.Int64 {
  210. return coderInt64NoZero
  211. }
  212. case pref.Sint64Kind:
  213. if ft.Kind() == reflect.Int64 {
  214. return coderSint64NoZero
  215. }
  216. case pref.Uint64Kind:
  217. if ft.Kind() == reflect.Uint64 {
  218. return coderUint64NoZero
  219. }
  220. case pref.Sfixed32Kind:
  221. if ft.Kind() == reflect.Int32 {
  222. return coderSfixed32NoZero
  223. }
  224. case pref.Fixed32Kind:
  225. if ft.Kind() == reflect.Uint32 {
  226. return coderFixed32NoZero
  227. }
  228. case pref.FloatKind:
  229. if ft.Kind() == reflect.Float32 {
  230. return coderFloatNoZero
  231. }
  232. case pref.Sfixed64Kind:
  233. if ft.Kind() == reflect.Int64 {
  234. return coderSfixed64NoZero
  235. }
  236. case pref.Fixed64Kind:
  237. if ft.Kind() == reflect.Uint64 {
  238. return coderFixed64NoZero
  239. }
  240. case pref.DoubleKind:
  241. if ft.Kind() == reflect.Float64 {
  242. return coderDoubleNoZero
  243. }
  244. case pref.StringKind:
  245. if ft.Kind() == reflect.String {
  246. return coderStringNoZeroValidateUTF8
  247. }
  248. if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
  249. return coderBytesNoZero
  250. }
  251. case pref.BytesKind:
  252. if ft.Kind() == reflect.String {
  253. return coderStringNoZero
  254. }
  255. if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
  256. return coderBytesNoZero
  257. }
  258. }
  259. case ft.Kind() == reflect.Ptr:
  260. ft := ft.Elem()
  261. switch fd.Kind() {
  262. case pref.BoolKind:
  263. if ft.Kind() == reflect.Bool {
  264. return coderBoolPtr
  265. }
  266. case pref.EnumKind:
  267. if ft.Kind() == reflect.Int32 {
  268. return coderEnumPtr
  269. }
  270. case pref.Int32Kind:
  271. if ft.Kind() == reflect.Int32 {
  272. return coderInt32Ptr
  273. }
  274. case pref.Sint32Kind:
  275. if ft.Kind() == reflect.Int32 {
  276. return coderSint32Ptr
  277. }
  278. case pref.Uint32Kind:
  279. if ft.Kind() == reflect.Uint32 {
  280. return coderUint32Ptr
  281. }
  282. case pref.Int64Kind:
  283. if ft.Kind() == reflect.Int64 {
  284. return coderInt64Ptr
  285. }
  286. case pref.Sint64Kind:
  287. if ft.Kind() == reflect.Int64 {
  288. return coderSint64Ptr
  289. }
  290. case pref.Uint64Kind:
  291. if ft.Kind() == reflect.Uint64 {
  292. return coderUint64Ptr
  293. }
  294. case pref.Sfixed32Kind:
  295. if ft.Kind() == reflect.Int32 {
  296. return coderSfixed32Ptr
  297. }
  298. case pref.Fixed32Kind:
  299. if ft.Kind() == reflect.Uint32 {
  300. return coderFixed32Ptr
  301. }
  302. case pref.FloatKind:
  303. if ft.Kind() == reflect.Float32 {
  304. return coderFloatPtr
  305. }
  306. case pref.Sfixed64Kind:
  307. if ft.Kind() == reflect.Int64 {
  308. return coderSfixed64Ptr
  309. }
  310. case pref.Fixed64Kind:
  311. if ft.Kind() == reflect.Uint64 {
  312. return coderFixed64Ptr
  313. }
  314. case pref.DoubleKind:
  315. if ft.Kind() == reflect.Float64 {
  316. return coderDoublePtr
  317. }
  318. case pref.StringKind:
  319. if ft.Kind() == reflect.String {
  320. return coderStringPtr
  321. }
  322. case pref.BytesKind:
  323. if ft.Kind() == reflect.String {
  324. return coderStringPtr
  325. }
  326. }
  327. default:
  328. switch fd.Kind() {
  329. case pref.BoolKind:
  330. if ft.Kind() == reflect.Bool {
  331. return coderBool
  332. }
  333. case pref.EnumKind:
  334. if ft.Kind() == reflect.Int32 {
  335. return coderEnum
  336. }
  337. case pref.Int32Kind:
  338. if ft.Kind() == reflect.Int32 {
  339. return coderInt32
  340. }
  341. case pref.Sint32Kind:
  342. if ft.Kind() == reflect.Int32 {
  343. return coderSint32
  344. }
  345. case pref.Uint32Kind:
  346. if ft.Kind() == reflect.Uint32 {
  347. return coderUint32
  348. }
  349. case pref.Int64Kind:
  350. if ft.Kind() == reflect.Int64 {
  351. return coderInt64
  352. }
  353. case pref.Sint64Kind:
  354. if ft.Kind() == reflect.Int64 {
  355. return coderSint64
  356. }
  357. case pref.Uint64Kind:
  358. if ft.Kind() == reflect.Uint64 {
  359. return coderUint64
  360. }
  361. case pref.Sfixed32Kind:
  362. if ft.Kind() == reflect.Int32 {
  363. return coderSfixed32
  364. }
  365. case pref.Fixed32Kind:
  366. if ft.Kind() == reflect.Uint32 {
  367. return coderFixed32
  368. }
  369. case pref.FloatKind:
  370. if ft.Kind() == reflect.Float32 {
  371. return coderFloat
  372. }
  373. case pref.Sfixed64Kind:
  374. if ft.Kind() == reflect.Int64 {
  375. return coderSfixed64
  376. }
  377. case pref.Fixed64Kind:
  378. if ft.Kind() == reflect.Uint64 {
  379. return coderFixed64
  380. }
  381. case pref.DoubleKind:
  382. if ft.Kind() == reflect.Float64 {
  383. return coderDouble
  384. }
  385. case pref.StringKind:
  386. if fd.Syntax() == pref.Proto3 && ft.Kind() == reflect.String {
  387. return coderStringValidateUTF8
  388. }
  389. if ft.Kind() == reflect.String {
  390. return coderString
  391. }
  392. if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
  393. return coderBytes
  394. }
  395. case pref.BytesKind:
  396. if ft.Kind() == reflect.String {
  397. return coderString
  398. }
  399. if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
  400. return coderBytes
  401. }
  402. }
  403. }
  404. panic(fmt.Errorf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft))
  405. }
  406. // encoderFuncsForValue returns interface{} value functions for a field, used for
  407. // extension values and map encoding.
  408. func encoderFuncsForValue(fd pref.FieldDescriptor, ft reflect.Type) ifaceCoderFuncs {
  409. switch {
  410. case fd.Cardinality() == pref.Repeated && !fd.IsPacked():
  411. if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice {
  412. break
  413. }
  414. ft := ft.Elem().Elem()
  415. switch fd.Kind() {
  416. case pref.BoolKind:
  417. if ft.Kind() == reflect.Bool {
  418. return coderBoolSliceIface
  419. }
  420. case pref.EnumKind:
  421. if ft.Kind() == reflect.Int32 {
  422. return coderEnumSliceIface
  423. }
  424. case pref.Int32Kind:
  425. if ft.Kind() == reflect.Int32 {
  426. return coderInt32SliceIface
  427. }
  428. case pref.Sint32Kind:
  429. if ft.Kind() == reflect.Int32 {
  430. return coderSint32SliceIface
  431. }
  432. case pref.Uint32Kind:
  433. if ft.Kind() == reflect.Uint32 {
  434. return coderUint32SliceIface
  435. }
  436. case pref.Int64Kind:
  437. if ft.Kind() == reflect.Int64 {
  438. return coderInt64SliceIface
  439. }
  440. case pref.Sint64Kind:
  441. if ft.Kind() == reflect.Int64 {
  442. return coderSint64SliceIface
  443. }
  444. case pref.Uint64Kind:
  445. if ft.Kind() == reflect.Uint64 {
  446. return coderUint64SliceIface
  447. }
  448. case pref.Sfixed32Kind:
  449. if ft.Kind() == reflect.Int32 {
  450. return coderSfixed32SliceIface
  451. }
  452. case pref.Fixed32Kind:
  453. if ft.Kind() == reflect.Uint32 {
  454. return coderFixed32SliceIface
  455. }
  456. case pref.FloatKind:
  457. if ft.Kind() == reflect.Float32 {
  458. return coderFloatSliceIface
  459. }
  460. case pref.Sfixed64Kind:
  461. if ft.Kind() == reflect.Int64 {
  462. return coderSfixed64SliceIface
  463. }
  464. case pref.Fixed64Kind:
  465. if ft.Kind() == reflect.Uint64 {
  466. return coderFixed64SliceIface
  467. }
  468. case pref.DoubleKind:
  469. if ft.Kind() == reflect.Float64 {
  470. return coderDoubleSliceIface
  471. }
  472. case pref.StringKind:
  473. if ft.Kind() == reflect.String {
  474. return coderStringSliceIface
  475. }
  476. if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
  477. return coderBytesSliceIface
  478. }
  479. case pref.BytesKind:
  480. if ft.Kind() == reflect.String {
  481. return coderStringSliceIface
  482. }
  483. if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
  484. return coderBytesSliceIface
  485. }
  486. case pref.MessageKind:
  487. return coderMessageSliceIface
  488. case pref.GroupKind:
  489. return coderGroupSliceIface
  490. }
  491. case fd.Cardinality() == pref.Repeated && fd.IsPacked():
  492. default:
  493. switch fd.Kind() {
  494. case pref.BoolKind:
  495. if ft.Kind() == reflect.Bool {
  496. return coderBoolIface
  497. }
  498. case pref.EnumKind:
  499. if ft.Kind() == reflect.Int32 {
  500. return coderEnumIface
  501. }
  502. case pref.Int32Kind:
  503. if ft.Kind() == reflect.Int32 {
  504. return coderInt32Iface
  505. }
  506. case pref.Sint32Kind:
  507. if ft.Kind() == reflect.Int32 {
  508. return coderSint32Iface
  509. }
  510. case pref.Uint32Kind:
  511. if ft.Kind() == reflect.Uint32 {
  512. return coderUint32Iface
  513. }
  514. case pref.Int64Kind:
  515. if ft.Kind() == reflect.Int64 {
  516. return coderInt64Iface
  517. }
  518. case pref.Sint64Kind:
  519. if ft.Kind() == reflect.Int64 {
  520. return coderSint64Iface
  521. }
  522. case pref.Uint64Kind:
  523. if ft.Kind() == reflect.Uint64 {
  524. return coderUint64Iface
  525. }
  526. case pref.Sfixed32Kind:
  527. if ft.Kind() == reflect.Int32 {
  528. return coderSfixed32Iface
  529. }
  530. case pref.Fixed32Kind:
  531. if ft.Kind() == reflect.Uint32 {
  532. return coderFixed32Iface
  533. }
  534. case pref.FloatKind:
  535. if ft.Kind() == reflect.Float32 {
  536. return coderFloatIface
  537. }
  538. case pref.Sfixed64Kind:
  539. if ft.Kind() == reflect.Int64 {
  540. return coderSfixed64Iface
  541. }
  542. case pref.Fixed64Kind:
  543. if ft.Kind() == reflect.Uint64 {
  544. return coderFixed64Iface
  545. }
  546. case pref.DoubleKind:
  547. if ft.Kind() == reflect.Float64 {
  548. return coderDoubleIface
  549. }
  550. case pref.StringKind:
  551. if fd.Syntax() == pref.Proto3 && ft.Kind() == reflect.String {
  552. return coderStringIfaceValidateUTF8
  553. }
  554. if ft.Kind() == reflect.String {
  555. return coderStringIface
  556. }
  557. if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
  558. return coderBytesIface
  559. }
  560. case pref.BytesKind:
  561. if ft.Kind() == reflect.String {
  562. return coderStringIface
  563. }
  564. if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 {
  565. return coderBytesIface
  566. }
  567. case pref.MessageKind:
  568. return coderMessageIface
  569. case pref.GroupKind:
  570. return coderGroupIface
  571. }
  572. }
  573. panic(fmt.Errorf("invalid type: no encoder for %v %v %v/%v", fd.FullName(), fd.Cardinality(), fd.Kind(), ft))
  574. }