codec_tables.go 16 KB

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