codec_field.go 14 KB

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