codec_field.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  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. "reflect"
  7. "google.golang.org/protobuf/internal/encoding/wire"
  8. "google.golang.org/protobuf/proto"
  9. pref "google.golang.org/protobuf/reflect/protoreflect"
  10. )
  11. type errInvalidUTF8 struct{}
  12. func (errInvalidUTF8) Error() string { return "string field contains invalid UTF-8" }
  13. func (errInvalidUTF8) InvalidUTF8() bool { return true }
  14. func makeOneofFieldCoder(si structInfo, fd pref.FieldDescriptor) pointerCoderFuncs {
  15. ot := si.oneofWrappersByNumber[fd.Number()]
  16. funcs := fieldCoder(fd, ot.Field(0).Type)
  17. fs := si.oneofsByName[fd.ContainingOneof().Name()]
  18. ft := fs.Type
  19. wiretag := wire.EncodeTag(fd.Number(), wireTypes[fd.Kind()])
  20. tagsize := wire.SizeVarint(wiretag)
  21. getInfo := func(p pointer) (pointer, bool) {
  22. v := p.AsValueOf(ft).Elem()
  23. if v.IsNil() {
  24. return pointer{}, false
  25. }
  26. v = v.Elem() // interface -> *struct
  27. if v.IsNil() || v.Elem().Type() != ot {
  28. return pointer{}, false
  29. }
  30. return pointerOfValue(v).Apply(zeroOffset), true
  31. }
  32. pcf := pointerCoderFuncs{
  33. size: func(p pointer, _ int, opts marshalOptions) int {
  34. v, ok := getInfo(p)
  35. if !ok {
  36. return 0
  37. }
  38. return funcs.size(v, tagsize, opts)
  39. },
  40. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  41. v, ok := getInfo(p)
  42. if !ok {
  43. return b, nil
  44. }
  45. return funcs.marshal(b, v, wiretag, opts)
  46. },
  47. unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  48. var vw reflect.Value // pointer to wrapper type
  49. vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
  50. if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
  51. vw = vi.Elem()
  52. } else {
  53. vw = reflect.New(ot)
  54. }
  55. n, err := funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, opts)
  56. if err != nil {
  57. return 0, err
  58. }
  59. vi.Set(vw)
  60. return n, nil
  61. },
  62. }
  63. if funcs.isInit != nil {
  64. pcf.isInit = func(p pointer) error {
  65. v, ok := getInfo(p)
  66. if !ok {
  67. return nil
  68. }
  69. return funcs.isInit(v)
  70. }
  71. }
  72. return pcf
  73. }
  74. func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
  75. if mi := getMessageInfo(ft); mi != nil {
  76. return pointerCoderFuncs{
  77. size: func(p pointer, tagsize int, opts marshalOptions) int {
  78. return sizeMessageInfo(p, mi, tagsize, opts)
  79. },
  80. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  81. return appendMessageInfo(b, p, wiretag, mi, opts)
  82. },
  83. unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  84. return consumeMessageInfo(b, p, mi, wtyp, opts)
  85. },
  86. isInit: func(p pointer) error {
  87. return mi.isInitializedPointer(p.Elem())
  88. },
  89. }
  90. } else {
  91. return pointerCoderFuncs{
  92. size: func(p pointer, tagsize int, opts marshalOptions) int {
  93. m := asMessage(p.AsValueOf(ft).Elem())
  94. return sizeMessage(m, tagsize, opts)
  95. },
  96. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  97. m := asMessage(p.AsValueOf(ft).Elem())
  98. return appendMessage(b, m, wiretag, opts)
  99. },
  100. unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  101. mp := p.AsValueOf(ft).Elem()
  102. if mp.IsNil() {
  103. mp.Set(reflect.New(ft.Elem()))
  104. }
  105. return consumeMessage(b, asMessage(mp), wtyp, opts)
  106. },
  107. isInit: func(p pointer) error {
  108. m := asMessage(p.AsValueOf(ft).Elem())
  109. return proto.IsInitialized(m)
  110. },
  111. }
  112. }
  113. }
  114. func sizeMessageInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
  115. return wire.SizeBytes(mi.sizePointer(p.Elem(), opts)) + tagsize
  116. }
  117. func appendMessageInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
  118. b = wire.AppendVarint(b, wiretag)
  119. b = wire.AppendVarint(b, uint64(mi.sizePointer(p.Elem(), opts)))
  120. return mi.marshalAppendPointer(b, p.Elem(), opts)
  121. }
  122. func consumeMessageInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  123. if wtyp != wire.BytesType {
  124. return 0, errUnknown
  125. }
  126. v, n := wire.ConsumeBytes(b)
  127. if n < 0 {
  128. return 0, wire.ParseError(n)
  129. }
  130. if p.Elem().IsNil() {
  131. p.SetPointer(pointerOfValue(reflect.New(mi.GoReflectType.Elem())))
  132. }
  133. if _, err := mi.unmarshalPointer(v, p.Elem(), 0, opts); err != nil {
  134. return 0, err
  135. }
  136. return n, nil
  137. }
  138. func sizeMessage(m proto.Message, tagsize int, _ marshalOptions) int {
  139. return wire.SizeBytes(proto.Size(m)) + tagsize
  140. }
  141. func appendMessage(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
  142. b = wire.AppendVarint(b, wiretag)
  143. b = wire.AppendVarint(b, uint64(proto.Size(m)))
  144. return opts.Options().MarshalAppend(b, m)
  145. }
  146. func consumeMessage(b []byte, m proto.Message, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  147. if wtyp != wire.BytesType {
  148. return 0, errUnknown
  149. }
  150. v, n := wire.ConsumeBytes(b)
  151. if n < 0 {
  152. return 0, wire.ParseError(n)
  153. }
  154. if err := opts.Options().Unmarshal(v, m); err != nil {
  155. return 0, err
  156. }
  157. return n, nil
  158. }
  159. func sizeMessageValue(v pref.Value, tagsize int, opts marshalOptions) int {
  160. m := v.Message().Interface()
  161. return sizeMessage(m, tagsize, opts)
  162. }
  163. func appendMessageValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
  164. m := v.Message().Interface()
  165. return appendMessage(b, m, wiretag, opts)
  166. }
  167. func consumeMessageValue(b []byte, v pref.Value, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, int, error) {
  168. m := v.Message().Interface()
  169. n, err := consumeMessage(b, m, wtyp, opts)
  170. return v, n, err
  171. }
  172. func isInitMessageValue(v pref.Value) error {
  173. m := v.Message().Interface()
  174. return proto.IsInitialized(m)
  175. }
  176. var coderMessageValue = valueCoderFuncs{
  177. size: sizeMessageValue,
  178. marshal: appendMessageValue,
  179. unmarshal: consumeMessageValue,
  180. isInit: isInitMessageValue,
  181. }
  182. func sizeGroupValue(v pref.Value, tagsize int, opts marshalOptions) int {
  183. m := v.Message().Interface()
  184. return sizeGroup(m, tagsize, opts)
  185. }
  186. func appendGroupValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
  187. m := v.Message().Interface()
  188. return appendGroup(b, m, wiretag, opts)
  189. }
  190. func consumeGroupValue(b []byte, v pref.Value, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, int, error) {
  191. m := v.Message().Interface()
  192. n, err := consumeGroup(b, m, num, wtyp, opts)
  193. return v, n, err
  194. }
  195. var coderGroupValue = valueCoderFuncs{
  196. size: sizeGroupValue,
  197. marshal: appendGroupValue,
  198. unmarshal: consumeGroupValue,
  199. isInit: isInitMessageValue,
  200. }
  201. func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
  202. num := fd.Number()
  203. if mi := getMessageInfo(ft); mi != nil {
  204. return pointerCoderFuncs{
  205. size: func(p pointer, tagsize int, opts marshalOptions) int {
  206. return sizeGroupType(p, mi, tagsize, opts)
  207. },
  208. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  209. return appendGroupType(b, p, wiretag, mi, opts)
  210. },
  211. unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  212. return consumeGroupType(b, p, mi, num, wtyp, opts)
  213. },
  214. isInit: func(p pointer) error {
  215. return mi.isInitializedPointer(p.Elem())
  216. },
  217. }
  218. } else {
  219. return pointerCoderFuncs{
  220. size: func(p pointer, tagsize int, opts marshalOptions) int {
  221. m := asMessage(p.AsValueOf(ft).Elem())
  222. return sizeGroup(m, tagsize, opts)
  223. },
  224. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  225. m := asMessage(p.AsValueOf(ft).Elem())
  226. return appendGroup(b, m, wiretag, opts)
  227. },
  228. unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  229. mp := p.AsValueOf(ft).Elem()
  230. if mp.IsNil() {
  231. mp.Set(reflect.New(ft.Elem()))
  232. }
  233. return consumeGroup(b, asMessage(mp), num, wtyp, opts)
  234. },
  235. isInit: func(p pointer) error {
  236. m := asMessage(p.AsValueOf(ft).Elem())
  237. return proto.IsInitialized(m)
  238. },
  239. }
  240. }
  241. }
  242. func sizeGroupType(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
  243. return 2*tagsize + mi.sizePointer(p.Elem(), opts)
  244. }
  245. func appendGroupType(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
  246. b = wire.AppendVarint(b, wiretag) // start group
  247. b, err := mi.marshalAppendPointer(b, p.Elem(), opts)
  248. b = wire.AppendVarint(b, wiretag+1) // end group
  249. return b, err
  250. }
  251. func consumeGroupType(b []byte, p pointer, mi *MessageInfo, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  252. if wtyp != wire.StartGroupType {
  253. return 0, errUnknown
  254. }
  255. if p.Elem().IsNil() {
  256. p.SetPointer(pointerOfValue(reflect.New(mi.GoReflectType.Elem())))
  257. }
  258. return mi.unmarshalPointer(b, p.Elem(), num, opts)
  259. }
  260. func sizeGroup(m proto.Message, tagsize int, _ marshalOptions) int {
  261. return 2*tagsize + proto.Size(m)
  262. }
  263. func appendGroup(b []byte, m proto.Message, wiretag uint64, opts marshalOptions) ([]byte, error) {
  264. b = wire.AppendVarint(b, wiretag) // start group
  265. b, err := opts.Options().MarshalAppend(b, m)
  266. b = wire.AppendVarint(b, wiretag+1) // end group
  267. return b, err
  268. }
  269. func consumeGroup(b []byte, m proto.Message, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  270. if wtyp != wire.StartGroupType {
  271. return 0, errUnknown
  272. }
  273. b, n := wire.ConsumeGroup(num, b)
  274. if n < 0 {
  275. return 0, wire.ParseError(n)
  276. }
  277. return n, opts.Options().Unmarshal(b, m)
  278. }
  279. func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
  280. if mi := getMessageInfo(ft); mi != nil {
  281. return pointerCoderFuncs{
  282. size: func(p pointer, tagsize int, opts marshalOptions) int {
  283. return sizeMessageSliceInfo(p, mi, tagsize, opts)
  284. },
  285. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  286. return appendMessageSliceInfo(b, p, wiretag, mi, opts)
  287. },
  288. unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  289. return consumeMessageSliceInfo(b, p, mi, wtyp, opts)
  290. },
  291. isInit: func(p pointer) error {
  292. return isInitMessageSliceInfo(p, mi)
  293. },
  294. }
  295. }
  296. return pointerCoderFuncs{
  297. size: func(p pointer, tagsize int, opts marshalOptions) int {
  298. return sizeMessageSlice(p, ft, tagsize, opts)
  299. },
  300. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  301. return appendMessageSlice(b, p, wiretag, ft, opts)
  302. },
  303. unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  304. return consumeMessageSlice(b, p, ft, wtyp, opts)
  305. },
  306. isInit: func(p pointer) error {
  307. return isInitMessageSlice(p, ft)
  308. },
  309. }
  310. }
  311. func sizeMessageSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
  312. s := p.PointerSlice()
  313. n := 0
  314. for _, v := range s {
  315. n += wire.SizeBytes(mi.sizePointer(v, opts)) + tagsize
  316. }
  317. return n
  318. }
  319. func appendMessageSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
  320. s := p.PointerSlice()
  321. var err error
  322. for _, v := range s {
  323. b = wire.AppendVarint(b, wiretag)
  324. siz := mi.sizePointer(v, opts)
  325. b = wire.AppendVarint(b, uint64(siz))
  326. b, err = mi.marshalAppendPointer(b, v, opts)
  327. if err != nil {
  328. return b, err
  329. }
  330. }
  331. return b, nil
  332. }
  333. func consumeMessageSliceInfo(b []byte, p pointer, mi *MessageInfo, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  334. if wtyp != wire.BytesType {
  335. return 0, errUnknown
  336. }
  337. v, n := wire.ConsumeBytes(b)
  338. if n < 0 {
  339. return 0, wire.ParseError(n)
  340. }
  341. m := reflect.New(mi.GoReflectType.Elem()).Interface()
  342. mp := pointerOfIface(m)
  343. if _, err := mi.unmarshalPointer(v, mp, 0, opts); err != nil {
  344. return 0, err
  345. }
  346. p.AppendPointerSlice(mp)
  347. return n, nil
  348. }
  349. func isInitMessageSliceInfo(p pointer, mi *MessageInfo) error {
  350. s := p.PointerSlice()
  351. for _, v := range s {
  352. if err := mi.isInitializedPointer(v); err != nil {
  353. return err
  354. }
  355. }
  356. return nil
  357. }
  358. func sizeMessageSlice(p pointer, goType reflect.Type, tagsize int, _ marshalOptions) int {
  359. s := p.PointerSlice()
  360. n := 0
  361. for _, v := range s {
  362. m := asMessage(v.AsValueOf(goType.Elem()))
  363. n += wire.SizeBytes(proto.Size(m)) + tagsize
  364. }
  365. return n
  366. }
  367. func appendMessageSlice(b []byte, p pointer, wiretag uint64, goType reflect.Type, opts marshalOptions) ([]byte, error) {
  368. s := p.PointerSlice()
  369. var err error
  370. for _, v := range s {
  371. m := asMessage(v.AsValueOf(goType.Elem()))
  372. b = wire.AppendVarint(b, wiretag)
  373. siz := proto.Size(m)
  374. b = wire.AppendVarint(b, uint64(siz))
  375. b, err = opts.Options().MarshalAppend(b, m)
  376. if err != nil {
  377. return b, err
  378. }
  379. }
  380. return b, nil
  381. }
  382. func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  383. if wtyp != wire.BytesType {
  384. return 0, errUnknown
  385. }
  386. v, n := wire.ConsumeBytes(b)
  387. if n < 0 {
  388. return 0, wire.ParseError(n)
  389. }
  390. mp := reflect.New(goType.Elem())
  391. if err := opts.Options().Unmarshal(v, asMessage(mp)); err != nil {
  392. return 0, err
  393. }
  394. p.AppendPointerSlice(pointerOfValue(mp))
  395. return n, nil
  396. }
  397. func isInitMessageSlice(p pointer, goType reflect.Type) error {
  398. s := p.PointerSlice()
  399. for _, v := range s {
  400. m := asMessage(v.AsValueOf(goType.Elem()))
  401. if err := proto.IsInitialized(m); err != nil {
  402. return err
  403. }
  404. }
  405. return nil
  406. }
  407. // Slices of messages
  408. func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
  409. list := listv.List()
  410. n := 0
  411. for i, llen := 0, list.Len(); i < llen; i++ {
  412. m := list.Get(i).Message().Interface()
  413. n += wire.SizeBytes(proto.Size(m)) + tagsize
  414. }
  415. return n
  416. }
  417. func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
  418. list := listv.List()
  419. mopts := opts.Options()
  420. for i, llen := 0, list.Len(); i < llen; i++ {
  421. m := list.Get(i).Message().Interface()
  422. b = wire.AppendVarint(b, wiretag)
  423. siz := proto.Size(m)
  424. b = wire.AppendVarint(b, uint64(siz))
  425. var err error
  426. b, err = mopts.MarshalAppend(b, m)
  427. if err != nil {
  428. return b, err
  429. }
  430. }
  431. return b, nil
  432. }
  433. func consumeMessageSliceValue(b []byte, listv pref.Value, _ wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, int, error) {
  434. list := listv.List()
  435. if wtyp != wire.BytesType {
  436. return pref.Value{}, 0, errUnknown
  437. }
  438. v, n := wire.ConsumeBytes(b)
  439. if n < 0 {
  440. return pref.Value{}, 0, wire.ParseError(n)
  441. }
  442. m := list.NewElement()
  443. if err := opts.Options().Unmarshal(v, m.Message().Interface()); err != nil {
  444. return pref.Value{}, 0, err
  445. }
  446. list.Append(m)
  447. return listv, n, nil
  448. }
  449. func isInitMessageSliceValue(listv pref.Value) error {
  450. list := listv.List()
  451. for i, llen := 0, list.Len(); i < llen; i++ {
  452. m := list.Get(i).Message().Interface()
  453. if err := proto.IsInitialized(m); err != nil {
  454. return err
  455. }
  456. }
  457. return nil
  458. }
  459. var coderMessageSliceValue = valueCoderFuncs{
  460. size: sizeMessageSliceValue,
  461. marshal: appendMessageSliceValue,
  462. unmarshal: consumeMessageSliceValue,
  463. isInit: isInitMessageSliceValue,
  464. }
  465. func sizeGroupSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int {
  466. list := listv.List()
  467. n := 0
  468. for i, llen := 0, list.Len(); i < llen; i++ {
  469. m := list.Get(i).Message().Interface()
  470. n += 2*tagsize + proto.Size(m)
  471. }
  472. return n
  473. }
  474. func appendGroupSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) {
  475. list := listv.List()
  476. mopts := opts.Options()
  477. for i, llen := 0, list.Len(); i < llen; i++ {
  478. m := list.Get(i).Message().Interface()
  479. b = wire.AppendVarint(b, wiretag) // start group
  480. var err error
  481. b, err = mopts.MarshalAppend(b, m)
  482. if err != nil {
  483. return b, err
  484. }
  485. b = wire.AppendVarint(b, wiretag+1) // end group
  486. }
  487. return b, nil
  488. }
  489. func consumeGroupSliceValue(b []byte, listv pref.Value, num wire.Number, wtyp wire.Type, opts unmarshalOptions) (pref.Value, int, error) {
  490. list := listv.List()
  491. if wtyp != wire.StartGroupType {
  492. return pref.Value{}, 0, errUnknown
  493. }
  494. b, n := wire.ConsumeGroup(num, b)
  495. if n < 0 {
  496. return pref.Value{}, 0, wire.ParseError(n)
  497. }
  498. m := list.NewElement()
  499. if err := opts.Options().Unmarshal(b, m.Message().Interface()); err != nil {
  500. return pref.Value{}, 0, err
  501. }
  502. list.Append(m)
  503. return listv, n, nil
  504. }
  505. var coderGroupSliceValue = valueCoderFuncs{
  506. size: sizeGroupSliceValue,
  507. marshal: appendGroupSliceValue,
  508. unmarshal: consumeGroupSliceValue,
  509. isInit: isInitMessageSliceValue,
  510. }
  511. func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs {
  512. num := fd.Number()
  513. if mi := getMessageInfo(ft); mi != nil {
  514. return pointerCoderFuncs{
  515. size: func(p pointer, tagsize int, opts marshalOptions) int {
  516. return sizeGroupSliceInfo(p, mi, tagsize, opts)
  517. },
  518. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  519. return appendGroupSliceInfo(b, p, wiretag, mi, opts)
  520. },
  521. unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  522. return consumeGroupSliceInfo(b, p, num, wtyp, mi, opts)
  523. },
  524. isInit: func(p pointer) error {
  525. return isInitMessageSliceInfo(p, mi)
  526. },
  527. }
  528. }
  529. return pointerCoderFuncs{
  530. size: func(p pointer, tagsize int, opts marshalOptions) int {
  531. return sizeGroupSlice(p, ft, tagsize, opts)
  532. },
  533. marshal: func(b []byte, p pointer, wiretag uint64, opts marshalOptions) ([]byte, error) {
  534. return appendGroupSlice(b, p, wiretag, ft, opts)
  535. },
  536. unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
  537. return consumeGroupSlice(b, p, num, wtyp, ft, opts)
  538. },
  539. isInit: func(p pointer) error {
  540. return isInitMessageSlice(p, ft)
  541. },
  542. }
  543. }
  544. func sizeGroupSlice(p pointer, messageType reflect.Type, tagsize int, _ marshalOptions) int {
  545. s := p.PointerSlice()
  546. n := 0
  547. for _, v := range s {
  548. m := asMessage(v.AsValueOf(messageType.Elem()))
  549. n += 2*tagsize + proto.Size(m)
  550. }
  551. return n
  552. }
  553. func appendGroupSlice(b []byte, p pointer, wiretag uint64, messageType reflect.Type, opts marshalOptions) ([]byte, error) {
  554. s := p.PointerSlice()
  555. var err error
  556. for _, v := range s {
  557. m := asMessage(v.AsValueOf(messageType.Elem()))
  558. b = wire.AppendVarint(b, wiretag) // start group
  559. b, err = opts.Options().MarshalAppend(b, m)
  560. if err != nil {
  561. return b, err
  562. }
  563. b = wire.AppendVarint(b, wiretag+1) // end group
  564. }
  565. return b, nil
  566. }
  567. func consumeGroupSlice(b []byte, p pointer, num wire.Number, wtyp wire.Type, goType reflect.Type, opts unmarshalOptions) (int, error) {
  568. if wtyp != wire.StartGroupType {
  569. return 0, errUnknown
  570. }
  571. b, n := wire.ConsumeGroup(num, b)
  572. if n < 0 {
  573. return 0, wire.ParseError(n)
  574. }
  575. mp := reflect.New(goType.Elem())
  576. if err := opts.Options().Unmarshal(b, asMessage(mp)); err != nil {
  577. return 0, err
  578. }
  579. p.AppendPointerSlice(pointerOfValue(mp))
  580. return n, nil
  581. }
  582. func sizeGroupSliceInfo(p pointer, mi *MessageInfo, tagsize int, opts marshalOptions) int {
  583. s := p.PointerSlice()
  584. n := 0
  585. for _, v := range s {
  586. n += 2*tagsize + mi.sizePointer(v, opts)
  587. }
  588. return n
  589. }
  590. func appendGroupSliceInfo(b []byte, p pointer, wiretag uint64, mi *MessageInfo, opts marshalOptions) ([]byte, error) {
  591. s := p.PointerSlice()
  592. var err error
  593. for _, v := range s {
  594. b = wire.AppendVarint(b, wiretag) // start group
  595. b, err = mi.marshalAppendPointer(b, v, opts)
  596. if err != nil {
  597. return b, err
  598. }
  599. b = wire.AppendVarint(b, wiretag+1) // end group
  600. }
  601. return b, nil
  602. }
  603. func consumeGroupSliceInfo(b []byte, p pointer, num wire.Number, wtyp wire.Type, mi *MessageInfo, opts unmarshalOptions) (int, error) {
  604. if wtyp != wire.StartGroupType {
  605. return 0, errUnknown
  606. }
  607. m := reflect.New(mi.GoReflectType.Elem()).Interface()
  608. mp := pointerOfIface(m)
  609. n, err := mi.unmarshalPointer(b, mp, num, opts)
  610. if err != nil {
  611. return 0, err
  612. }
  613. p.AppendPointerSlice(mp)
  614. return n, nil
  615. }
  616. func asMessage(v reflect.Value) pref.ProtoMessage {
  617. if m, ok := v.Interface().(pref.ProtoMessage); ok {
  618. return m
  619. }
  620. return legacyWrapMessage(v)
  621. }