encode_field.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  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. "unicode/utf8"
  9. "google.golang.org/protobuf/internal/encoding/wire"
  10. "google.golang.org/protobuf/proto"
  11. pref "google.golang.org/protobuf/reflect/protoreflect"
  12. )
  13. type errInvalidUTF8 struct{}
  14. func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" }
  15. func (errInvalidUTF8) InvalidUTF8() bool { return true }
  16. func makeOneofFieldCoder(fs reflect.StructField, od pref.OneofDescriptor, structFields map[pref.FieldNumber]reflect.StructField, otypes map[pref.FieldNumber]reflect.Type) pointerCoderFuncs {
  17. type oneofFieldInfo struct {
  18. wiretag uint64
  19. tagsize int
  20. funcs pointerCoderFuncs
  21. }
  22. oneofFieldInfos := make(map[reflect.Type]oneofFieldInfo)
  23. for i, fields := 0, od.Fields(); i < fields.Len(); i++ {
  24. fd := fields.Get(i)
  25. ot := otypes[fd.Number()]
  26. wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
  27. oneofFieldInfos[ot] = oneofFieldInfo{
  28. wiretag: wiretag,
  29. tagsize: wire.SizeVarint(wiretag),
  30. funcs: fieldCoder(fd, ot.Field(0).Type),
  31. }
  32. }
  33. ft := fs.Type
  34. return pointerCoderFuncs{
  35. size: func(p pointer, _ int, opts marshalOptions) int {
  36. v := p.AsValueOf(ft).Elem()
  37. if v.IsNil() {
  38. return 0
  39. }
  40. v = v.Elem() // interface -> *struct
  41. telem := v.Elem().Type()
  42. info, ok := oneofFieldInfos[telem]
  43. if !ok {
  44. panic(fmt.Errorf("invalid oneof type %v", telem))
  45. }
  46. return info.funcs.size(pointerOfValue(v).Apply(zeroOffset), info.tagsize, opts)
  47. },
  48. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  49. v := p.AsValueOf(ft).Elem()
  50. if v.IsNil() {
  51. return b, nil
  52. }
  53. v = v.Elem() // interface -> *struct
  54. telem := v.Elem().Type()
  55. info, ok := oneofFieldInfos[telem]
  56. if !ok {
  57. panic(fmt.Errorf("invalid oneof type %v", telem))
  58. }
  59. return info.funcs.marshal(b, pointerOfValue(v).Apply(zeroOffset), info.wiretag, opts)
  60. },
  61. }
  62. }
  63. func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
  64. if fi, ok := getMessageInfo(ft); ok {
  65. return pointerCoderFuncs{
  66. size: func(p pointer, tagsize int, opts marshalOptions) int {
  67. return sizeMessageInfo(p, fi, tagsize, opts)
  68. },
  69. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  70. return appendMessageInfo(b, p, wiretag, fi, opts)
  71. },
  72. }
  73. } else {
  74. return pointerCoderFuncs{
  75. size: func(p pointer, tagsize int, opts marshalOptions) int {
  76. m := asMessage(p.AsValueOf(ft).Elem())
  77. return sizeMessage(m, tagsize, opts)
  78. },
  79. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  80. m := asMessage(p.AsValueOf(ft).Elem())
  81. return appendMessage(b, m, wiretag, opts)
  82. },
  83. }
  84. }
  85. }
  86. func sizeMessageInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
  87. return wire.SizeBytes(mi.sizePointer(p.Elem(), opts)) + tagsize
  88. }
  89. func appendMessageInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
  90. b = wire.AppendVarint(b, wiretag)
  91. b = wire.AppendVarint(b, uint64(mi.sizePointer(p.Elem(), opts)))
  92. return mi.marshalAppendPointer(b, p.Elem(), opts)
  93. }
  94. func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
  95. return wire.SizeBytes(proto.Size(m)) + tagsize
  96. }
  97. func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
  98. b = wire.AppendVarint(b, wiretag)
  99. b = wire.AppendVarint(b, uint64(proto.Size(m)))
  100. return opts.Options().MarshalAppend(b, m)
  101. }
  102. func sizeMessageIface(ival interface{}, tagsize int, opts marshalOptions) int {
  103. m := Export{}.MessageOf(ival).Interface()
  104. return sizeMessage(m, tagsize, opts)
  105. }
  106. func appendMessageIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
  107. m := Export{}.MessageOf(ival).Interface()
  108. return appendMessage(b, m, wiretag, opts)
  109. }
  110. var coderMessageIface = ifaceCoderFuncs{
  111. size: sizeMessageIface,
  112. marshal: appendMessageIface,
  113. }
  114. func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
  115. if fi, ok := getMessageInfo(ft); ok {
  116. return pointerCoderFuncs{
  117. size: func(p pointer, tagsize int, opts marshalOptions) int {
  118. return sizeGroupType(p, fi, tagsize, opts)
  119. },
  120. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  121. return appendGroupType(b, p, wiretag, fi, opts)
  122. },
  123. }
  124. } else {
  125. return pointerCoderFuncs{
  126. size: func(p pointer, tagsize int, opts marshalOptions) int {
  127. m := asMessage(p.AsValueOf(ft).Elem())
  128. return sizeGroup(m, tagsize, opts)
  129. },
  130. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  131. m := asMessage(p.AsValueOf(ft).Elem())
  132. return appendGroup(b, m, wiretag, opts)
  133. },
  134. }
  135. }
  136. }
  137. func sizeGroupType(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
  138. return 2*tagsize + mi.sizePointer(p.Elem(), opts)
  139. }
  140. func appendGroupType(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
  141. b = wire.AppendVarint(b, wiretag) // start group
  142. b, err := mi.marshalAppendPointer(b, p.Elem(), opts)
  143. b = wire.AppendVarint(b, wiretag+1) // end group
  144. return b, err
  145. }
  146. func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
  147. return 2*tagsize + proto.Size(m)
  148. }
  149. func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
  150. b = wire.AppendVarint(b, wiretag) // start group
  151. b, err := opts.Options().MarshalAppend(b, m)
  152. b = wire.AppendVarint(b, wiretag+1) // end group
  153. return b, err
  154. }
  155. func sizeGroupIface(ival interface{}, tagsize int, opts marshalOptions) int {
  156. m := Export{}.MessageOf(ival).Interface()
  157. return sizeGroup(m, tagsize, opts)
  158. }
  159. func appendGroupIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
  160. m := Export{}.MessageOf(ival).Interface()
  161. return appendGroup(b, m, wiretag, opts)
  162. }
  163. var coderGroupIface = ifaceCoderFuncs{
  164. size: sizeGroupIface,
  165. marshal: appendGroupIface,
  166. }
  167. func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
  168. if fi, ok := getMessageInfo(ft); ok {
  169. return pointerCoderFuncs{
  170. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  171. return appendMessageSliceInfo(b, p, wiretag, fi, opts)
  172. },
  173. size: func(p pointer, tagsize int, opts marshalOptions) int {
  174. return sizeMessageSliceInfo(p, fi, tagsize, opts)
  175. },
  176. }
  177. }
  178. return pointerCoderFuncs{
  179. size: func(p pointer, tagsize int, opts marshalOptions) int {
  180. return sizeMessageSlice(p, ft, tagsize, opts)
  181. },
  182. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  183. return appendMessageSlice(b, p, wiretag, ft, opts)
  184. },
  185. }
  186. }
  187. func sizeMessageSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
  188. s := p.PointerSlice()
  189. n := 0
  190. for _, v := range s {
  191. n += wire.SizeBytes(mi.sizePointer(v, opts)) + tagsize
  192. }
  193. return n
  194. }
  195. func appendMessageSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
  196. s := p.PointerSlice()
  197. var err error
  198. for _, v := range s {
  199. b = wire.AppendVarint(b, wiretag)
  200. siz := mi.sizePointer(v, opts)
  201. b = wire.AppendVarint(b, uint64(siz))
  202. b, err = mi.marshalAppendPointer(b, v, opts)
  203. if err != nil {
  204. return b, err
  205. }
  206. }
  207. return b, nil
  208. }
  209. func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
  210. s := p.PointerSlice()
  211. n := 0
  212. for _, v := range s {
  213. m := Export{}.MessageOf(v.AsValueOf(goType.Elem()).Interface()).Interface()
  214. n += wire.SizeBytes(proto.Size(m)) + tagsize
  215. }
  216. return n
  217. }
  218. func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
  219. s := p.PointerSlice()
  220. var err error
  221. for _, v := range s {
  222. m := Export{}.MessageOf(v.AsValueOf(goType.Elem()).Interface()).Interface()
  223. b = wire.AppendVarint(b, wiretag)
  224. siz := proto.Size(m)
  225. b = wire.AppendVarint(b, uint64(siz))
  226. b, err = opts.Options().MarshalAppend(b, m)
  227. if err != nil {
  228. return b, err
  229. }
  230. }
  231. return b, nil
  232. }
  233. // Slices of messages
  234. func sizeMessageSliceIface(ival interface{}, tagsize int, opts marshalOptions) int {
  235. p := pointerOfIface(ival)
  236. return sizeMessageSlice(p, reflect.TypeOf(ival).Elem().Elem(), tagsize, opts)
  237. }
  238. func appendMessageSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
  239. p := pointerOfIface(ival)
  240. return appendMessageSlice(b, p, wiretag, reflect.TypeOf(ival).Elem().Elem(), opts)
  241. }
  242. var coderMessageSliceIface = ifaceCoderFuncs{
  243. size: sizeMessageSliceIface,
  244. marshal: appendMessageSliceIface,
  245. }
  246. func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
  247. if fi, ok := getMessageInfo(ft); ok {
  248. return pointerCoderFuncs{
  249. size: func(p pointer, tagsize int, opts marshalOptions) int {
  250. return sizeGroupSliceInfo(p, fi, tagsize, opts)
  251. },
  252. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  253. return appendGroupSliceInfo(b, p, wiretag, fi, opts)
  254. },
  255. }
  256. }
  257. return pointerCoderFuncs{
  258. size: func(p pointer, tagsize int, opts marshalOptions) int {
  259. return sizeGroupSlice(p, ft, tagsize, opts)
  260. },
  261. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  262. return appendGroupSlice(b, p, wiretag, ft, opts)
  263. },
  264. }
  265. }
  266. func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
  267. s := p.PointerSlice()
  268. n := 0
  269. for _, v := range s {
  270. m := Export{}.MessageOf(v.AsValueOf(messageType.Elem()).Interface()).Interface()
  271. n += 2*tagsize + proto.Size(m)
  272. }
  273. return n
  274. }
  275. func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
  276. s := p.PointerSlice()
  277. var err error
  278. for _, v := range s {
  279. m := Export{}.MessageOf(v.AsValueOf(messageType.Elem()).Interface()).Interface()
  280. b = wire.AppendVarint(b, wiretag) // start group
  281. b, err = opts.Options().MarshalAppend(b, m)
  282. if err != nil {
  283. return b, err
  284. }
  285. b = wire.AppendVarint(b, wiretag+1) // end group
  286. }
  287. return b, nil
  288. }
  289. func sizeGroupSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
  290. s := p.PointerSlice()
  291. n := 0
  292. for _, v := range s {
  293. n += 2*tagsize + mi.sizePointer(v, opts)
  294. }
  295. return n
  296. }
  297. func appendGroupSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
  298. s := p.PointerSlice()
  299. var err error
  300. for _, v := range s {
  301. b = wire.AppendVarint(b, wiretag) // start group
  302. b, err = mi.marshalAppendPointer(b, v, opts)
  303. if err != nil {
  304. return b, err
  305. }
  306. b = wire.AppendVarint(b, wiretag+1) // end group
  307. }
  308. return b, nil
  309. }
  310. func sizeGroupSliceIface(ival interface{}, tagsize int, opts marshalOptions) int {
  311. p := pointerOfIface(ival)
  312. return sizeGroupSlice(p, reflect.TypeOf(ival).Elem().Elem(), tagsize, opts)
  313. }
  314. func appendGroupSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
  315. p := pointerOfIface(ival)
  316. return appendGroupSlice(b, p, wiretag, reflect.TypeOf(ival).Elem().Elem(), opts)
  317. }
  318. var coderGroupSliceIface = ifaceCoderFuncs{
  319. size: sizeGroupSliceIface,
  320. marshal: appendGroupSliceIface,
  321. }
  322. // Enums
  323. func sizeEnumIface(ival interface{}, tagsize int, _ marshalOptions) (n int) {
  324. v := reflect.ValueOf(ival).Int()
  325. return wire.SizeVarint(uint64(v)) + tagsize
  326. }
  327. func appendEnumIface(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
  328. v := reflect.ValueOf(ival).Int()
  329. b = wire.AppendVarint(b, wiretag)
  330. b = wire.AppendVarint(b, uint64(v))
  331. return b, nil
  332. }
  333. var coderEnumIface = ifaceCoderFuncs{
  334. size: sizeEnumIface,
  335. marshal: appendEnumIface,
  336. }
  337. func sizeEnumSliceIface(ival interface{}, tagsize int, opts marshalOptions) (size int) {
  338. return sizeEnumSliceReflect(reflect.ValueOf(ival).Elem(), tagsize, opts)
  339. }
  340. func sizeEnumSliceReflect(s reflect.Value, tagsize int, _ marshalOptions) (size int) {
  341. for i, llen := 0, s.Len(); i < llen; i++ {
  342. size += wire.SizeVarint(uint64(s.Index(i).Int())) + tagsize
  343. }
  344. return size
  345. }
  346. func appendEnumSliceIface(b []byte, ival interface{}, wiretag uint64, opts marshalOptions) ([]byte, error) {
  347. return appendEnumSliceReflect(b, reflect.ValueOf(ival).Elem(), wiretag, opts)
  348. }
  349. func appendEnumSliceReflect(b []byte, s reflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
  350. for i, llen := 0, s.Len(); i < llen; i++ {
  351. b = wire.AppendVarint(b, wiretag)
  352. b = wire.AppendVarint(b, uint64(s.Index(i).Int()))
  353. }
  354. return b, nil
  355. }
  356. var coderEnumSliceIface = ifaceCoderFuncs{
  357. size: sizeEnumSliceIface,
  358. marshal: appendEnumSliceIface,
  359. }
  360. // Strings with UTF8 validation.
  361. func appendStringValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
  362. v := *p.String()
  363. b = wire.AppendVarint(b, wiretag)
  364. b = wire.AppendBytes(b, []byte(v))
  365. if !utf8.ValidString(v) {
  366. return b, errInvalidUTF8{}
  367. }
  368. return b, nil
  369. }
  370. var coderStringValidateUTF8 = pointerCoderFuncs{
  371. size: sizeString,
  372. marshal: appendStringValidateUTF8,
  373. }
  374. func appendStringNoZeroValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
  375. v := *p.String()
  376. if len(v) == 0 {
  377. return b, nil
  378. }
  379. b = wire.AppendVarint(b, wiretag)
  380. b = wire.AppendBytes(b, []byte(v))
  381. if !utf8.ValidString(v) {
  382. return b, errInvalidUTF8{}
  383. }
  384. return b, nil
  385. }
  386. var coderStringNoZeroValidateUTF8 = pointerCoderFuncs{
  387. size: sizeStringNoZero,
  388. marshal: appendStringNoZeroValidateUTF8,
  389. }
  390. func sizeStringSliceValidateUTF8(p pointer, tagsize int, _ marshalOptions) (size int) {
  391. s := *p.StringSlice()
  392. for _, v := range s {
  393. size += tagsize + wire.SizeBytes(len([]byte(v)))
  394. }
  395. return size
  396. }
  397. func appendStringSliceValidateUTF8(b []byte, p pointer, wiretag uint64, _ marshalOptions) ([]byte, error) {
  398. s := *p.StringSlice()
  399. var err error
  400. for _, v := range s {
  401. b = wire.AppendVarint(b, wiretag)
  402. b = wire.AppendBytes(b, []byte(v))
  403. if !utf8.ValidString(v) {
  404. err = errInvalidUTF8{}
  405. }
  406. }
  407. return b, err
  408. }
  409. var coderStringSliceValidateUTF8 = pointerCoderFuncs{
  410. size: sizeStringSliceValidateUTF8,
  411. marshal: appendStringSliceValidateUTF8,
  412. }
  413. func sizeStringIfaceValidateUTF8(ival interface{}, tagsize int, _ marshalOptions) int {
  414. v := ival.(string)
  415. return tagsize + wire.SizeBytes(len([]byte(v)))
  416. }
  417. func appendStringIfaceValidateUTF8(b []byte, ival interface{}, wiretag uint64, _ marshalOptions) ([]byte, error) {
  418. v := ival.(string)
  419. b = wire.AppendVarint(b, wiretag)
  420. b = wire.AppendBytes(b, []byte(v))
  421. if !utf8.ValidString(v) {
  422. return b, errInvalidUTF8{}
  423. }
  424. return b, nil
  425. }
  426. var coderStringIfaceValidateUTF8 = ifaceCoderFuncs{
  427. size: sizeStringIfaceValidateUTF8,
  428. marshal: appendStringIfaceValidateUTF8,
  429. }
  430. func asMessage(v reflect.Value) pref.ProtoMessage {
  431. if m, ok := v.Interface().(pref.ProtoMessage); ok {
  432. return m
  433. }
  434. return legacyWrapMessage(v)
  435. }