marshalto.go 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  1. // Protocol Buffers for Go with Gadgets
  2. //
  3. // Copyright (c) 2013, The GoGo Authors. All rights reserved.
  4. // http://github.com/gogo/protobuf
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are
  8. // met:
  9. //
  10. // * Redistributions of source code must retain the above copyright
  11. // notice, this list of conditions and the following disclaimer.
  12. // * Redistributions in binary form must reproduce the above
  13. // copyright notice, this list of conditions and the following disclaimer
  14. // in the documentation and/or other materials provided with the
  15. // distribution.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  20. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  21. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. /*
  29. The marshalto plugin generates a Marshal and MarshalTo method for each message.
  30. The `Marshal() ([]byte, error)` method results in the fact that the message
  31. implements the Marshaler interface.
  32. This allows proto.Marshal to be faster by calling the generated Marshal method rather than using reflect to Marshal the struct.
  33. If is enabled by the following extensions:
  34. - marshaler
  35. - marshaler_all
  36. Or the following extensions:
  37. - unsafe_marshaler
  38. - unsafe_marshaler_all
  39. That is if you want to use the unsafe package in your generated code.
  40. The speed up using the unsafe package is not very significant.
  41. The generation of marshalling tests are enabled using one of the following extensions:
  42. - testgen
  43. - testgen_all
  44. And benchmarks given it is enabled using one of the following extensions:
  45. - benchgen
  46. - benchgen_all
  47. Let us look at:
  48. github.com/gogo/protobuf/test/example/example.proto
  49. Btw all the output can be seen at:
  50. github.com/gogo/protobuf/test/example/*
  51. The following message:
  52. option (gogoproto.marshaler_all) = true;
  53. message B {
  54. option (gogoproto.description) = true;
  55. optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
  56. repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false];
  57. }
  58. given to the marshalto plugin, will generate the following code:
  59. func (m *B) Marshal() (dAtA []byte, err error) {
  60. size := m.Size()
  61. dAtA = make([]byte, size)
  62. n, err := m.MarshalToSizedBuffer(dAtA[:size])
  63. if err != nil {
  64. return nil, err
  65. }
  66. return dAtA[:n], nil
  67. }
  68. func (m *B) MarshalTo(dAtA []byte) (int, error) {
  69. size := m.Size()
  70. return m.MarshalToSizedBuffer(dAtA[:size])
  71. }
  72. func (m *B) MarshalToSizedBuffer(dAtA []byte) (int, error) {
  73. i := len(dAtA)
  74. _ = i
  75. var l int
  76. _ = l
  77. if m.XXX_unrecognized != nil {
  78. i -= len(m.XXX_unrecognized)
  79. copy(dAtA[i:], m.XXX_unrecognized)
  80. }
  81. if len(m.G) > 0 {
  82. for iNdEx := len(m.G) - 1; iNdEx >= 0; iNdEx-- {
  83. {
  84. size := m.G[iNdEx].Size()
  85. i -= size
  86. if _, err := m.G[iNdEx].MarshalTo(dAtA[i:]); err != nil {
  87. return 0, err
  88. }
  89. i = encodeVarintExample(dAtA, i, uint64(size))
  90. }
  91. i--
  92. dAtA[i] = 0x12
  93. }
  94. }
  95. {
  96. size, err := m.A.MarshalToSizedBuffer(dAtA[:i])
  97. if err != nil {
  98. return 0, err
  99. }
  100. i -= size
  101. i = encodeVarintExample(dAtA, i, uint64(size))
  102. }
  103. i--
  104. dAtA[i] = 0xa
  105. return len(dAtA) - i, nil
  106. }
  107. As shown above Marshal calculates the size of the not yet marshalled message
  108. and allocates the appropriate buffer.
  109. This is followed by calling the MarshalToSizedBuffer method which requires a preallocated buffer, and marshals backwards.
  110. The MarshalTo method allows a user to rather preallocated a reusable buffer.
  111. The Size method is generated using the size plugin and the gogoproto.sizer, gogoproto.sizer_all extensions.
  112. The user can also using the generated Size method to check that his reusable buffer is still big enough.
  113. The generated tests and benchmarks will keep you safe and show that this is really a significant speed improvement.
  114. An additional message-level option `stable_marshaler` (and the file-level
  115. option `stable_marshaler_all`) exists which causes the generated marshalling
  116. code to behave deterministically. Today, this only changes the serialization of
  117. maps; they are serialized in sort order.
  118. */
  119. package marshalto
  120. import (
  121. "fmt"
  122. "sort"
  123. "strconv"
  124. "strings"
  125. "github.com/gogo/protobuf/gogoproto"
  126. "github.com/gogo/protobuf/proto"
  127. descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
  128. "github.com/gogo/protobuf/protoc-gen-gogo/generator"
  129. "github.com/gogo/protobuf/vanity"
  130. )
  131. type NumGen interface {
  132. Next() string
  133. Current() string
  134. }
  135. type numGen struct {
  136. index int
  137. }
  138. func NewNumGen() NumGen {
  139. return &numGen{0}
  140. }
  141. func (this *numGen) Next() string {
  142. this.index++
  143. return this.Current()
  144. }
  145. func (this *numGen) Current() string {
  146. return strconv.Itoa(this.index)
  147. }
  148. type marshalto struct {
  149. *generator.Generator
  150. generator.PluginImports
  151. atleastOne bool
  152. errorsPkg generator.Single
  153. protoPkg generator.Single
  154. sortKeysPkg generator.Single
  155. mathPkg generator.Single
  156. typesPkg generator.Single
  157. binaryPkg generator.Single
  158. localName string
  159. }
  160. func NewMarshal() *marshalto {
  161. return &marshalto{}
  162. }
  163. func (p *marshalto) Name() string {
  164. return "marshalto"
  165. }
  166. func (p *marshalto) Init(g *generator.Generator) {
  167. p.Generator = g
  168. }
  169. func (p *marshalto) callFixed64(varName ...string) {
  170. p.P(`i -= 8`)
  171. p.P(p.binaryPkg.Use(), `.LittleEndian.PutUint64(dAtA[i:], uint64(`, strings.Join(varName, ""), `))`)
  172. }
  173. func (p *marshalto) callFixed32(varName ...string) {
  174. p.P(`i -= 4`)
  175. p.P(p.binaryPkg.Use(), `.LittleEndian.PutUint32(dAtA[i:], uint32(`, strings.Join(varName, ""), `))`)
  176. }
  177. func (p *marshalto) callVarint(varName ...string) {
  178. p.P(`i = encodeVarint`, p.localName, `(dAtA, i, uint64(`, strings.Join(varName, ""), `))`)
  179. }
  180. func (p *marshalto) encodeKey(fieldNumber int32, wireType int) {
  181. x := uint32(fieldNumber)<<3 | uint32(wireType)
  182. i := 0
  183. keybuf := make([]byte, 0)
  184. for i = 0; x > 127; i++ {
  185. keybuf = append(keybuf, 0x80|uint8(x&0x7F))
  186. x >>= 7
  187. }
  188. keybuf = append(keybuf, uint8(x))
  189. for i = len(keybuf) - 1; i >= 0; i-- {
  190. p.P(`i--`)
  191. p.P(`dAtA[i] = `, fmt.Sprintf("%#v", keybuf[i]))
  192. }
  193. }
  194. func keySize(fieldNumber int32, wireType int) int {
  195. x := uint32(fieldNumber)<<3 | uint32(wireType)
  196. size := 0
  197. for size = 0; x > 127; size++ {
  198. x >>= 7
  199. }
  200. size++
  201. return size
  202. }
  203. func wireToType(wire string) int {
  204. switch wire {
  205. case "fixed64":
  206. return proto.WireFixed64
  207. case "fixed32":
  208. return proto.WireFixed32
  209. case "varint":
  210. return proto.WireVarint
  211. case "bytes":
  212. return proto.WireBytes
  213. case "group":
  214. return proto.WireBytes
  215. case "zigzag32":
  216. return proto.WireVarint
  217. case "zigzag64":
  218. return proto.WireVarint
  219. }
  220. panic("unreachable")
  221. }
  222. func (p *marshalto) mapField(numGen NumGen, field *descriptor.FieldDescriptorProto, kvField *descriptor.FieldDescriptorProto, varName string, protoSizer bool) {
  223. switch kvField.GetType() {
  224. case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
  225. p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(`, varName, `))`)
  226. case descriptor.FieldDescriptorProto_TYPE_FLOAT:
  227. p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(`, varName, `))`)
  228. case descriptor.FieldDescriptorProto_TYPE_INT64,
  229. descriptor.FieldDescriptorProto_TYPE_UINT64,
  230. descriptor.FieldDescriptorProto_TYPE_INT32,
  231. descriptor.FieldDescriptorProto_TYPE_UINT32,
  232. descriptor.FieldDescriptorProto_TYPE_ENUM:
  233. p.callVarint(varName)
  234. case descriptor.FieldDescriptorProto_TYPE_FIXED64,
  235. descriptor.FieldDescriptorProto_TYPE_SFIXED64:
  236. p.callFixed64(varName)
  237. case descriptor.FieldDescriptorProto_TYPE_FIXED32,
  238. descriptor.FieldDescriptorProto_TYPE_SFIXED32:
  239. p.callFixed32(varName)
  240. case descriptor.FieldDescriptorProto_TYPE_BOOL:
  241. p.P(`i--`)
  242. p.P(`if `, varName, ` {`)
  243. p.In()
  244. p.P(`dAtA[i] = 1`)
  245. p.Out()
  246. p.P(`} else {`)
  247. p.In()
  248. p.P(`dAtA[i] = 0`)
  249. p.Out()
  250. p.P(`}`)
  251. case descriptor.FieldDescriptorProto_TYPE_STRING,
  252. descriptor.FieldDescriptorProto_TYPE_BYTES:
  253. if gogoproto.IsCustomType(field) && kvField.IsBytes() {
  254. p.forward(varName, true, protoSizer)
  255. } else {
  256. p.P(`i -= len(`, varName, `)`)
  257. p.P(`copy(dAtA[i:], `, varName, `)`)
  258. p.callVarint(`len(`, varName, `)`)
  259. }
  260. case descriptor.FieldDescriptorProto_TYPE_SINT32:
  261. p.callVarint(`(uint32(`, varName, `) << 1) ^ uint32((`, varName, ` >> 31))`)
  262. case descriptor.FieldDescriptorProto_TYPE_SINT64:
  263. p.callVarint(`(uint64(`, varName, `) << 1) ^ uint64((`, varName, ` >> 63))`)
  264. case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
  265. if !p.marshalAllSizeOf(kvField, `(*`+varName+`)`, numGen.Next()) {
  266. if gogoproto.IsCustomType(field) {
  267. p.forward(varName, true, protoSizer)
  268. } else {
  269. p.backward(varName, true)
  270. }
  271. }
  272. }
  273. }
  274. type orderFields []*descriptor.FieldDescriptorProto
  275. func (this orderFields) Len() int {
  276. return len(this)
  277. }
  278. func (this orderFields) Less(i, j int) bool {
  279. return this[i].GetNumber() < this[j].GetNumber()
  280. }
  281. func (this orderFields) Swap(i, j int) {
  282. this[i], this[j] = this[j], this[i]
  283. }
  284. func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) {
  285. fieldname := p.GetOneOfFieldName(message, field)
  286. nullable := gogoproto.IsNullable(field)
  287. repeated := field.IsRepeated()
  288. required := field.IsRequired()
  289. protoSizer := gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto)
  290. doNilCheck := gogoproto.NeedsNilCheck(proto3, field)
  291. if required && nullable {
  292. p.P(`if m.`, fieldname, `== nil {`)
  293. p.In()
  294. if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
  295. p.P(`return 0, new(`, p.protoPkg.Use(), `.RequiredNotSetError)`)
  296. } else {
  297. p.P(`return 0, `, p.protoPkg.Use(), `.NewRequiredNotSetError("`, field.GetName(), `")`)
  298. }
  299. p.Out()
  300. p.P(`} else {`)
  301. } else if repeated {
  302. p.P(`if len(m.`, fieldname, `) > 0 {`)
  303. p.In()
  304. } else if doNilCheck {
  305. p.P(`if m.`, fieldname, ` != nil {`)
  306. p.In()
  307. }
  308. packed := field.IsPacked() || (proto3 && field.IsPacked3())
  309. wireType := field.WireType()
  310. fieldNumber := field.GetNumber()
  311. if packed {
  312. wireType = proto.WireBytes
  313. }
  314. switch *field.Type {
  315. case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
  316. if packed {
  317. val := p.reverseListRange(`m.`, fieldname)
  318. p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(`, val, `))`)
  319. p.callFixed64("f" + numGen.Current())
  320. p.Out()
  321. p.P(`}`)
  322. p.callVarint(`len(m.`, fieldname, `) * 8`)
  323. p.encodeKey(fieldNumber, wireType)
  324. } else if repeated {
  325. val := p.reverseListRange(`m.`, fieldname)
  326. p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(`, val, `))`)
  327. p.callFixed64("f" + numGen.Current())
  328. p.encodeKey(fieldNumber, wireType)
  329. p.Out()
  330. p.P(`}`)
  331. } else if proto3 {
  332. p.P(`if m.`, fieldname, ` != 0 {`)
  333. p.In()
  334. p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`)
  335. p.encodeKey(fieldNumber, wireType)
  336. p.Out()
  337. p.P(`}`)
  338. } else if !nullable {
  339. p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`)
  340. p.encodeKey(fieldNumber, wireType)
  341. } else {
  342. p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(*m.`+fieldname, `))`)
  343. p.encodeKey(fieldNumber, wireType)
  344. }
  345. case descriptor.FieldDescriptorProto_TYPE_FLOAT:
  346. if packed {
  347. val := p.reverseListRange(`m.`, fieldname)
  348. p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(`, val, `))`)
  349. p.callFixed32("f" + numGen.Current())
  350. p.Out()
  351. p.P(`}`)
  352. p.callVarint(`len(m.`, fieldname, `) * 4`)
  353. p.encodeKey(fieldNumber, wireType)
  354. } else if repeated {
  355. val := p.reverseListRange(`m.`, fieldname)
  356. p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(`, val, `))`)
  357. p.callFixed32("f" + numGen.Current())
  358. p.encodeKey(fieldNumber, wireType)
  359. p.Out()
  360. p.P(`}`)
  361. } else if proto3 {
  362. p.P(`if m.`, fieldname, ` != 0 {`)
  363. p.In()
  364. p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`)
  365. p.encodeKey(fieldNumber, wireType)
  366. p.Out()
  367. p.P(`}`)
  368. } else if !nullable {
  369. p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`)
  370. p.encodeKey(fieldNumber, wireType)
  371. } else {
  372. p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(*m.`+fieldname, `))`)
  373. p.encodeKey(fieldNumber, wireType)
  374. }
  375. case descriptor.FieldDescriptorProto_TYPE_INT64,
  376. descriptor.FieldDescriptorProto_TYPE_UINT64,
  377. descriptor.FieldDescriptorProto_TYPE_INT32,
  378. descriptor.FieldDescriptorProto_TYPE_UINT32,
  379. descriptor.FieldDescriptorProto_TYPE_ENUM:
  380. if packed {
  381. jvar := "j" + numGen.Next()
  382. p.P(`dAtA`, numGen.Next(), ` := make([]byte, len(m.`, fieldname, `)*10)`)
  383. p.P(`var `, jvar, ` int`)
  384. if *field.Type == descriptor.FieldDescriptorProto_TYPE_INT64 ||
  385. *field.Type == descriptor.FieldDescriptorProto_TYPE_INT32 {
  386. p.P(`for _, num1 := range m.`, fieldname, ` {`)
  387. p.In()
  388. p.P(`num := uint64(num1)`)
  389. } else {
  390. p.P(`for _, num := range m.`, fieldname, ` {`)
  391. p.In()
  392. }
  393. p.P(`for num >= 1<<7 {`)
  394. p.In()
  395. p.P(`dAtA`, numGen.Current(), `[`, jvar, `] = uint8(uint64(num)&0x7f|0x80)`)
  396. p.P(`num >>= 7`)
  397. p.P(jvar, `++`)
  398. p.Out()
  399. p.P(`}`)
  400. p.P(`dAtA`, numGen.Current(), `[`, jvar, `] = uint8(num)`)
  401. p.P(jvar, `++`)
  402. p.Out()
  403. p.P(`}`)
  404. p.P(`i -= `, jvar)
  405. p.P(`copy(dAtA[i:], dAtA`, numGen.Current(), `[:`, jvar, `])`)
  406. p.callVarint(jvar)
  407. p.encodeKey(fieldNumber, wireType)
  408. } else if repeated {
  409. val := p.reverseListRange(`m.`, fieldname)
  410. p.callVarint(val)
  411. p.encodeKey(fieldNumber, wireType)
  412. p.Out()
  413. p.P(`}`)
  414. } else if proto3 {
  415. p.P(`if m.`, fieldname, ` != 0 {`)
  416. p.In()
  417. p.callVarint(`m.`, fieldname)
  418. p.encodeKey(fieldNumber, wireType)
  419. p.Out()
  420. p.P(`}`)
  421. } else if !nullable {
  422. p.callVarint(`m.`, fieldname)
  423. p.encodeKey(fieldNumber, wireType)
  424. } else {
  425. p.callVarint(`*m.`, fieldname)
  426. p.encodeKey(fieldNumber, wireType)
  427. }
  428. case descriptor.FieldDescriptorProto_TYPE_FIXED64,
  429. descriptor.FieldDescriptorProto_TYPE_SFIXED64:
  430. if packed {
  431. val := p.reverseListRange(`m.`, fieldname)
  432. p.callFixed64(val)
  433. p.Out()
  434. p.P(`}`)
  435. p.callVarint(`len(m.`, fieldname, `) * 8`)
  436. p.encodeKey(fieldNumber, wireType)
  437. } else if repeated {
  438. val := p.reverseListRange(`m.`, fieldname)
  439. p.callFixed64(val)
  440. p.encodeKey(fieldNumber, wireType)
  441. p.Out()
  442. p.P(`}`)
  443. } else if proto3 {
  444. p.P(`if m.`, fieldname, ` != 0 {`)
  445. p.In()
  446. p.callFixed64("m." + fieldname)
  447. p.encodeKey(fieldNumber, wireType)
  448. p.Out()
  449. p.P(`}`)
  450. } else if !nullable {
  451. p.callFixed64("m." + fieldname)
  452. p.encodeKey(fieldNumber, wireType)
  453. } else {
  454. p.callFixed64("*m." + fieldname)
  455. p.encodeKey(fieldNumber, wireType)
  456. }
  457. case descriptor.FieldDescriptorProto_TYPE_FIXED32,
  458. descriptor.FieldDescriptorProto_TYPE_SFIXED32:
  459. if packed {
  460. val := p.reverseListRange(`m.`, fieldname)
  461. p.callFixed32(val)
  462. p.Out()
  463. p.P(`}`)
  464. p.callVarint(`len(m.`, fieldname, `) * 4`)
  465. p.encodeKey(fieldNumber, wireType)
  466. } else if repeated {
  467. val := p.reverseListRange(`m.`, fieldname)
  468. p.callFixed32(val)
  469. p.encodeKey(fieldNumber, wireType)
  470. p.Out()
  471. p.P(`}`)
  472. } else if proto3 {
  473. p.P(`if m.`, fieldname, ` != 0 {`)
  474. p.In()
  475. p.callFixed32("m." + fieldname)
  476. p.encodeKey(fieldNumber, wireType)
  477. p.Out()
  478. p.P(`}`)
  479. } else if !nullable {
  480. p.callFixed32("m." + fieldname)
  481. p.encodeKey(fieldNumber, wireType)
  482. } else {
  483. p.callFixed32("*m." + fieldname)
  484. p.encodeKey(fieldNumber, wireType)
  485. }
  486. case descriptor.FieldDescriptorProto_TYPE_BOOL:
  487. if packed {
  488. val := p.reverseListRange(`m.`, fieldname)
  489. p.P(`i--`)
  490. p.P(`if `, val, ` {`)
  491. p.In()
  492. p.P(`dAtA[i] = 1`)
  493. p.Out()
  494. p.P(`} else {`)
  495. p.In()
  496. p.P(`dAtA[i] = 0`)
  497. p.Out()
  498. p.P(`}`)
  499. p.Out()
  500. p.P(`}`)
  501. p.callVarint(`len(m.`, fieldname, `)`)
  502. p.encodeKey(fieldNumber, wireType)
  503. } else if repeated {
  504. val := p.reverseListRange(`m.`, fieldname)
  505. p.P(`i--`)
  506. p.P(`if `, val, ` {`)
  507. p.In()
  508. p.P(`dAtA[i] = 1`)
  509. p.Out()
  510. p.P(`} else {`)
  511. p.In()
  512. p.P(`dAtA[i] = 0`)
  513. p.Out()
  514. p.P(`}`)
  515. p.encodeKey(fieldNumber, wireType)
  516. p.Out()
  517. p.P(`}`)
  518. } else if proto3 {
  519. p.P(`if m.`, fieldname, ` {`)
  520. p.In()
  521. p.P(`i--`)
  522. p.P(`if m.`, fieldname, ` {`)
  523. p.In()
  524. p.P(`dAtA[i] = 1`)
  525. p.Out()
  526. p.P(`} else {`)
  527. p.In()
  528. p.P(`dAtA[i] = 0`)
  529. p.Out()
  530. p.P(`}`)
  531. p.encodeKey(fieldNumber, wireType)
  532. p.Out()
  533. p.P(`}`)
  534. } else if !nullable {
  535. p.P(`i--`)
  536. p.P(`if m.`, fieldname, ` {`)
  537. p.In()
  538. p.P(`dAtA[i] = 1`)
  539. p.Out()
  540. p.P(`} else {`)
  541. p.In()
  542. p.P(`dAtA[i] = 0`)
  543. p.Out()
  544. p.P(`}`)
  545. p.encodeKey(fieldNumber, wireType)
  546. } else {
  547. p.P(`i--`)
  548. p.P(`if *m.`, fieldname, ` {`)
  549. p.In()
  550. p.P(`dAtA[i] = 1`)
  551. p.Out()
  552. p.P(`} else {`)
  553. p.In()
  554. p.P(`dAtA[i] = 0`)
  555. p.Out()
  556. p.P(`}`)
  557. p.encodeKey(fieldNumber, wireType)
  558. }
  559. case descriptor.FieldDescriptorProto_TYPE_STRING:
  560. if repeated {
  561. val := p.reverseListRange(`m.`, fieldname)
  562. p.P(`i -= len(`, val, `)`)
  563. p.P(`copy(dAtA[i:], `, val, `)`)
  564. p.callVarint(`len(`, val, `)`)
  565. p.encodeKey(fieldNumber, wireType)
  566. p.Out()
  567. p.P(`}`)
  568. } else if proto3 {
  569. p.P(`if len(m.`, fieldname, `) > 0 {`)
  570. p.In()
  571. p.P(`i -= len(m.`, fieldname, `)`)
  572. p.P(`copy(dAtA[i:], m.`, fieldname, `)`)
  573. p.callVarint(`len(m.`, fieldname, `)`)
  574. p.encodeKey(fieldNumber, wireType)
  575. p.Out()
  576. p.P(`}`)
  577. } else if !nullable {
  578. p.P(`i -= len(m.`, fieldname, `)`)
  579. p.P(`copy(dAtA[i:], m.`, fieldname, `)`)
  580. p.callVarint(`len(m.`, fieldname, `)`)
  581. p.encodeKey(fieldNumber, wireType)
  582. } else {
  583. p.P(`i -= len(*m.`, fieldname, `)`)
  584. p.P(`copy(dAtA[i:], *m.`, fieldname, `)`)
  585. p.callVarint(`len(*m.`, fieldname, `)`)
  586. p.encodeKey(fieldNumber, wireType)
  587. }
  588. case descriptor.FieldDescriptorProto_TYPE_GROUP:
  589. panic(fmt.Errorf("marshaler does not support group %v", fieldname))
  590. case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
  591. if p.IsMap(field) {
  592. m := p.GoMapType(nil, field)
  593. keygoTyp, keywire := p.GoType(nil, m.KeyField)
  594. keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField)
  595. // keys may not be pointers
  596. keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
  597. keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
  598. keyCapTyp := generator.CamelCase(keygoTyp)
  599. valuegoTyp, valuewire := p.GoType(nil, m.ValueField)
  600. valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField)
  601. nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
  602. var val string
  603. if gogoproto.IsStableMarshaler(file.FileDescriptorProto, message.DescriptorProto) {
  604. keysName := `keysFor` + fieldname
  605. p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(m.`, fieldname, `))`)
  606. p.P(`for k := range m.`, fieldname, ` {`)
  607. p.In()
  608. p.P(keysName, ` = append(`, keysName, `, `, keygoTyp, `(k))`)
  609. p.Out()
  610. p.P(`}`)
  611. p.P(p.sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`)
  612. val = p.reverseListRange(keysName)
  613. } else {
  614. p.P(`for k := range m.`, fieldname, ` {`)
  615. val = "k"
  616. p.In()
  617. }
  618. if gogoproto.IsStableMarshaler(file.FileDescriptorProto, message.DescriptorProto) {
  619. p.P(`v := m.`, fieldname, `[`, keygoAliasTyp, `(`, val, `)]`)
  620. } else {
  621. p.P(`v := m.`, fieldname, `[`, val, `]`)
  622. }
  623. p.P(`baseI := i`)
  624. accessor := `v`
  625. if m.ValueField.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE {
  626. if valuegoTyp != valuegoAliasTyp && !gogoproto.IsStdType(m.ValueAliasField) {
  627. if nullable {
  628. // cast back to the type that has the generated methods on it
  629. accessor = `((` + valuegoTyp + `)(` + accessor + `))`
  630. } else {
  631. accessor = `((*` + valuegoTyp + `)(&` + accessor + `))`
  632. }
  633. } else if !nullable {
  634. accessor = `(&v)`
  635. }
  636. }
  637. nullableMsg := nullable && (m.ValueField.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE ||
  638. gogoproto.IsCustomType(field) && m.ValueField.IsBytes())
  639. plainBytes := m.ValueField.IsBytes() && !gogoproto.IsCustomType(field)
  640. if nullableMsg {
  641. p.P(`if `, accessor, ` != nil { `)
  642. p.In()
  643. } else if plainBytes {
  644. if proto3 {
  645. p.P(`if len(`, accessor, `) > 0 {`)
  646. } else {
  647. p.P(`if `, accessor, ` != nil {`)
  648. }
  649. p.In()
  650. }
  651. p.mapField(numGen, field, m.ValueAliasField, accessor, protoSizer)
  652. p.encodeKey(2, wireToType(valuewire))
  653. if nullableMsg || plainBytes {
  654. p.Out()
  655. p.P(`}`)
  656. }
  657. p.mapField(numGen, field, m.KeyField, val, protoSizer)
  658. p.encodeKey(1, wireToType(keywire))
  659. p.callVarint(`baseI - i`)
  660. p.encodeKey(fieldNumber, wireType)
  661. p.Out()
  662. p.P(`}`)
  663. } else if repeated {
  664. val := p.reverseListRange(`m.`, fieldname)
  665. sizeOfVarName := val
  666. if gogoproto.IsNullable(field) {
  667. sizeOfVarName = `*` + val
  668. }
  669. if !p.marshalAllSizeOf(field, sizeOfVarName, ``) {
  670. if gogoproto.IsCustomType(field) {
  671. p.forward(val, true, protoSizer)
  672. } else {
  673. p.backward(val, true)
  674. }
  675. }
  676. p.encodeKey(fieldNumber, wireType)
  677. p.Out()
  678. p.P(`}`)
  679. } else {
  680. sizeOfVarName := `m.` + fieldname
  681. if gogoproto.IsNullable(field) {
  682. sizeOfVarName = `*` + sizeOfVarName
  683. }
  684. if !p.marshalAllSizeOf(field, sizeOfVarName, numGen.Next()) {
  685. if gogoproto.IsCustomType(field) {
  686. p.forward(`m.`+fieldname, true, protoSizer)
  687. } else {
  688. p.backward(`m.`+fieldname, true)
  689. }
  690. }
  691. p.encodeKey(fieldNumber, wireType)
  692. }
  693. case descriptor.FieldDescriptorProto_TYPE_BYTES:
  694. if !gogoproto.IsCustomType(field) {
  695. if repeated {
  696. val := p.reverseListRange(`m.`, fieldname)
  697. p.P(`i -= len(`, val, `)`)
  698. p.P(`copy(dAtA[i:], `, val, `)`)
  699. p.callVarint(`len(`, val, `)`)
  700. p.encodeKey(fieldNumber, wireType)
  701. p.Out()
  702. p.P(`}`)
  703. } else if proto3 {
  704. p.P(`if len(m.`, fieldname, `) > 0 {`)
  705. p.In()
  706. p.P(`i -= len(m.`, fieldname, `)`)
  707. p.P(`copy(dAtA[i:], m.`, fieldname, `)`)
  708. p.callVarint(`len(m.`, fieldname, `)`)
  709. p.encodeKey(fieldNumber, wireType)
  710. p.Out()
  711. p.P(`}`)
  712. } else {
  713. p.P(`i -= len(m.`, fieldname, `)`)
  714. p.P(`copy(dAtA[i:], m.`, fieldname, `)`)
  715. p.callVarint(`len(m.`, fieldname, `)`)
  716. p.encodeKey(fieldNumber, wireType)
  717. }
  718. } else {
  719. if repeated {
  720. val := p.reverseListRange(`m.`, fieldname)
  721. p.forward(val, true, protoSizer)
  722. p.encodeKey(fieldNumber, wireType)
  723. p.Out()
  724. p.P(`}`)
  725. } else {
  726. p.forward(`m.`+fieldname, true, protoSizer)
  727. p.encodeKey(fieldNumber, wireType)
  728. }
  729. }
  730. case descriptor.FieldDescriptorProto_TYPE_SINT32:
  731. if packed {
  732. datavar := "dAtA" + numGen.Next()
  733. jvar := "j" + numGen.Next()
  734. p.P(datavar, ` := make([]byte, len(m.`, fieldname, ")*5)")
  735. p.P(`var `, jvar, ` int`)
  736. p.P(`for _, num := range m.`, fieldname, ` {`)
  737. p.In()
  738. xvar := "x" + numGen.Next()
  739. p.P(xvar, ` := (uint32(num) << 1) ^ uint32((num >> 31))`)
  740. p.P(`for `, xvar, ` >= 1<<7 {`)
  741. p.In()
  742. p.P(datavar, `[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`)
  743. p.P(jvar, `++`)
  744. p.P(xvar, ` >>= 7`)
  745. p.Out()
  746. p.P(`}`)
  747. p.P(datavar, `[`, jvar, `] = uint8(`, xvar, `)`)
  748. p.P(jvar, `++`)
  749. p.Out()
  750. p.P(`}`)
  751. p.P(`i -= `, jvar)
  752. p.P(`copy(dAtA[i:], `, datavar, `[:`, jvar, `])`)
  753. p.callVarint(jvar)
  754. p.encodeKey(fieldNumber, wireType)
  755. } else if repeated {
  756. val := p.reverseListRange(`m.`, fieldname)
  757. p.P(`x`, numGen.Next(), ` := (uint32(`, val, `) << 1) ^ uint32((`, val, ` >> 31))`)
  758. p.callVarint(`x`, numGen.Current())
  759. p.encodeKey(fieldNumber, wireType)
  760. p.Out()
  761. p.P(`}`)
  762. } else if proto3 {
  763. p.P(`if m.`, fieldname, ` != 0 {`)
  764. p.In()
  765. p.callVarint(`(uint32(m.`, fieldname, `) << 1) ^ uint32((m.`, fieldname, ` >> 31))`)
  766. p.encodeKey(fieldNumber, wireType)
  767. p.Out()
  768. p.P(`}`)
  769. } else if !nullable {
  770. p.callVarint(`(uint32(m.`, fieldname, `) << 1) ^ uint32((m.`, fieldname, ` >> 31))`)
  771. p.encodeKey(fieldNumber, wireType)
  772. } else {
  773. p.callVarint(`(uint32(*m.`, fieldname, `) << 1) ^ uint32((*m.`, fieldname, ` >> 31))`)
  774. p.encodeKey(fieldNumber, wireType)
  775. }
  776. case descriptor.FieldDescriptorProto_TYPE_SINT64:
  777. if packed {
  778. jvar := "j" + numGen.Next()
  779. xvar := "x" + numGen.Next()
  780. datavar := "dAtA" + numGen.Next()
  781. p.P(`var `, jvar, ` int`)
  782. p.P(datavar, ` := make([]byte, len(m.`, fieldname, `)*10)`)
  783. p.P(`for _, num := range m.`, fieldname, ` {`)
  784. p.In()
  785. p.P(xvar, ` := (uint64(num) << 1) ^ uint64((num >> 63))`)
  786. p.P(`for `, xvar, ` >= 1<<7 {`)
  787. p.In()
  788. p.P(datavar, `[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`)
  789. p.P(jvar, `++`)
  790. p.P(xvar, ` >>= 7`)
  791. p.Out()
  792. p.P(`}`)
  793. p.P(datavar, `[`, jvar, `] = uint8(`, xvar, `)`)
  794. p.P(jvar, `++`)
  795. p.Out()
  796. p.P(`}`)
  797. p.P(`i -= `, jvar)
  798. p.P(`copy(dAtA[i:], `, datavar, `[:`, jvar, `])`)
  799. p.callVarint(jvar)
  800. p.encodeKey(fieldNumber, wireType)
  801. } else if repeated {
  802. val := p.reverseListRange(`m.`, fieldname)
  803. p.P(`x`, numGen.Next(), ` := (uint64(`, val, `) << 1) ^ uint64((`, val, ` >> 63))`)
  804. p.callVarint("x" + numGen.Current())
  805. p.encodeKey(fieldNumber, wireType)
  806. p.Out()
  807. p.P(`}`)
  808. } else if proto3 {
  809. p.P(`if m.`, fieldname, ` != 0 {`)
  810. p.In()
  811. p.callVarint(`(uint64(m.`, fieldname, `) << 1) ^ uint64((m.`, fieldname, ` >> 63))`)
  812. p.encodeKey(fieldNumber, wireType)
  813. p.Out()
  814. p.P(`}`)
  815. } else if !nullable {
  816. p.callVarint(`(uint64(m.`, fieldname, `) << 1) ^ uint64((m.`, fieldname, ` >> 63))`)
  817. p.encodeKey(fieldNumber, wireType)
  818. } else {
  819. p.callVarint(`(uint64(*m.`, fieldname, `) << 1) ^ uint64((*m.`, fieldname, ` >> 63))`)
  820. p.encodeKey(fieldNumber, wireType)
  821. }
  822. default:
  823. panic("not implemented")
  824. }
  825. if (required && nullable) || repeated || doNilCheck {
  826. p.Out()
  827. p.P(`}`)
  828. }
  829. }
  830. func (p *marshalto) Generate(file *generator.FileDescriptor) {
  831. numGen := NewNumGen()
  832. p.PluginImports = generator.NewPluginImports(p.Generator)
  833. p.atleastOne = false
  834. p.localName = generator.FileName(file)
  835. p.mathPkg = p.NewImport("math")
  836. p.sortKeysPkg = p.NewImport("github.com/gogo/protobuf/sortkeys")
  837. p.protoPkg = p.NewImport("github.com/gogo/protobuf/proto")
  838. if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
  839. p.protoPkg = p.NewImport("github.com/golang/protobuf/proto")
  840. }
  841. p.errorsPkg = p.NewImport("errors")
  842. p.binaryPkg = p.NewImport("encoding/binary")
  843. p.typesPkg = p.NewImport("github.com/gogo/protobuf/types")
  844. for _, message := range file.Messages() {
  845. if message.DescriptorProto.GetOptions().GetMapEntry() {
  846. continue
  847. }
  848. ccTypeName := generator.CamelCaseSlice(message.TypeName())
  849. if !gogoproto.IsMarshaler(file.FileDescriptorProto, message.DescriptorProto) &&
  850. !gogoproto.IsUnsafeMarshaler(file.FileDescriptorProto, message.DescriptorProto) {
  851. continue
  852. }
  853. p.atleastOne = true
  854. p.P(`func (m *`, ccTypeName, `) Marshal() (dAtA []byte, err error) {`)
  855. p.In()
  856. if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
  857. p.P(`size := m.ProtoSize()`)
  858. } else {
  859. p.P(`size := m.Size()`)
  860. }
  861. p.P(`dAtA = make([]byte, size)`)
  862. p.P(`n, err := m.MarshalToSizedBuffer(dAtA[:size])`)
  863. p.P(`if err != nil {`)
  864. p.In()
  865. p.P(`return nil, err`)
  866. p.Out()
  867. p.P(`}`)
  868. p.P(`return dAtA[:n], nil`)
  869. p.Out()
  870. p.P(`}`)
  871. p.P(``)
  872. p.P(`func (m *`, ccTypeName, `) MarshalTo(dAtA []byte) (int, error) {`)
  873. p.In()
  874. if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
  875. p.P(`size := m.ProtoSize()`)
  876. } else {
  877. p.P(`size := m.Size()`)
  878. }
  879. p.P(`return m.MarshalToSizedBuffer(dAtA[:size])`)
  880. p.Out()
  881. p.P(`}`)
  882. p.P(``)
  883. p.P(`func (m *`, ccTypeName, `) MarshalToSizedBuffer(dAtA []byte) (int, error) {`)
  884. p.In()
  885. p.P(`i := len(dAtA)`)
  886. p.P(`_ = i`)
  887. p.P(`var l int`)
  888. p.P(`_ = l`)
  889. if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
  890. p.P(`if m.XXX_unrecognized != nil {`)
  891. p.In()
  892. p.P(`i -= len(m.XXX_unrecognized)`)
  893. p.P(`copy(dAtA[i:], m.XXX_unrecognized)`)
  894. p.Out()
  895. p.P(`}`)
  896. }
  897. if message.DescriptorProto.HasExtension() {
  898. if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
  899. p.P(`if n, err := `, p.protoPkg.Use(), `.EncodeInternalExtensionBackwards(m, dAtA[:i]); err != nil {`)
  900. p.In()
  901. p.P(`return 0, err`)
  902. p.Out()
  903. p.P(`} else {`)
  904. p.In()
  905. p.P(`i -= n`)
  906. p.Out()
  907. p.P(`}`)
  908. } else {
  909. p.P(`if m.XXX_extensions != nil {`)
  910. p.In()
  911. p.P(`i -= len(m.XXX_extensions)`)
  912. p.P(`copy(dAtA[i:], m.XXX_extensions)`)
  913. p.Out()
  914. p.P(`}`)
  915. }
  916. }
  917. fields := orderFields(message.GetField())
  918. sort.Sort(fields)
  919. oneofs := make(map[string]struct{})
  920. for i := len(message.Field) - 1; i >= 0; i-- {
  921. field := message.Field[i]
  922. oneof := field.OneofIndex != nil
  923. if !oneof {
  924. proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
  925. p.generateField(proto3, numGen, file, message, field)
  926. } else {
  927. fieldname := p.GetFieldName(message, field)
  928. if _, ok := oneofs[fieldname]; !ok {
  929. oneofs[fieldname] = struct{}{}
  930. p.P(`if m.`, fieldname, ` != nil {`)
  931. p.In()
  932. p.forward(`m.`+fieldname, false, gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto))
  933. p.Out()
  934. p.P(`}`)
  935. }
  936. }
  937. }
  938. p.P(`return len(dAtA) - i, nil`)
  939. p.Out()
  940. p.P(`}`)
  941. p.P()
  942. //Generate MarshalTo methods for oneof fields
  943. m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
  944. for _, field := range m.Field {
  945. oneof := field.OneofIndex != nil
  946. if !oneof {
  947. continue
  948. }
  949. ccTypeName := p.OneOfTypeName(message, field)
  950. p.P(`func (m *`, ccTypeName, `) MarshalTo(dAtA []byte) (int, error) {`)
  951. p.In()
  952. if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
  953. p.P(`size := m.ProtoSize()`)
  954. } else {
  955. p.P(`size := m.Size()`)
  956. }
  957. p.P(`return m.MarshalToSizedBuffer(dAtA[:size])`)
  958. p.Out()
  959. p.P(`}`)
  960. p.P(``)
  961. p.P(`func (m *`, ccTypeName, `) MarshalToSizedBuffer(dAtA []byte) (int, error) {`)
  962. p.In()
  963. p.P(`i := len(dAtA)`)
  964. vanity.TurnOffNullableForNativeTypes(field)
  965. p.generateField(false, numGen, file, message, field)
  966. p.P(`return len(dAtA) - i, nil`)
  967. p.Out()
  968. p.P(`}`)
  969. }
  970. }
  971. if p.atleastOne {
  972. p.P(`func encodeVarint`, p.localName, `(dAtA []byte, offset int, v uint64) int {`)
  973. p.In()
  974. p.P(`offset -= sov`, p.localName, `(v)`)
  975. p.P(`base := offset`)
  976. p.P(`for v >= 1<<7 {`)
  977. p.In()
  978. p.P(`dAtA[offset] = uint8(v&0x7f|0x80)`)
  979. p.P(`v >>= 7`)
  980. p.P(`offset++`)
  981. p.Out()
  982. p.P(`}`)
  983. p.P(`dAtA[offset] = uint8(v)`)
  984. p.P(`return base`)
  985. p.Out()
  986. p.P(`}`)
  987. }
  988. }
  989. func (p *marshalto) reverseListRange(expression ...string) string {
  990. exp := strings.Join(expression, "")
  991. p.P(`for iNdEx := len(`, exp, `) - 1; iNdEx >= 0; iNdEx-- {`)
  992. p.In()
  993. return exp + `[iNdEx]`
  994. }
  995. func (p *marshalto) marshalAllSizeOf(field *descriptor.FieldDescriptorProto, varName, num string) bool {
  996. if gogoproto.IsStdTime(field) {
  997. p.marshalSizeOf(`StdTimeMarshalTo`, `SizeOfStdTime`, varName, num)
  998. } else if gogoproto.IsStdDuration(field) {
  999. p.marshalSizeOf(`StdDurationMarshalTo`, `SizeOfStdDuration`, varName, num)
  1000. } else if gogoproto.IsStdDouble(field) {
  1001. p.marshalSizeOf(`StdDoubleMarshalTo`, `SizeOfStdDouble`, varName, num)
  1002. } else if gogoproto.IsStdFloat(field) {
  1003. p.marshalSizeOf(`StdFloatMarshalTo`, `SizeOfStdFloat`, varName, num)
  1004. } else if gogoproto.IsStdInt64(field) {
  1005. p.marshalSizeOf(`StdInt64MarshalTo`, `SizeOfStdInt64`, varName, num)
  1006. } else if gogoproto.IsStdUInt64(field) {
  1007. p.marshalSizeOf(`StdUInt64MarshalTo`, `SizeOfStdUInt64`, varName, num)
  1008. } else if gogoproto.IsStdInt32(field) {
  1009. p.marshalSizeOf(`StdInt32MarshalTo`, `SizeOfStdInt32`, varName, num)
  1010. } else if gogoproto.IsStdUInt32(field) {
  1011. p.marshalSizeOf(`StdUInt32MarshalTo`, `SizeOfStdUInt32`, varName, num)
  1012. } else if gogoproto.IsStdBool(field) {
  1013. p.marshalSizeOf(`StdBoolMarshalTo`, `SizeOfStdBool`, varName, num)
  1014. } else if gogoproto.IsStdString(field) {
  1015. p.marshalSizeOf(`StdStringMarshalTo`, `SizeOfStdString`, varName, num)
  1016. } else if gogoproto.IsStdBytes(field) {
  1017. p.marshalSizeOf(`StdBytesMarshalTo`, `SizeOfStdBytes`, varName, num)
  1018. } else {
  1019. return false
  1020. }
  1021. return true
  1022. }
  1023. func (p *marshalto) marshalSizeOf(marshal, size, varName, num string) {
  1024. p.P(`n`, num, `, err`, num, ` := `, p.typesPkg.Use(), `.`, marshal, `(`, varName, `, dAtA[i-`, p.typesPkg.Use(), `.`, size, `(`, varName, `):])`)
  1025. p.P(`if err`, num, ` != nil {`)
  1026. p.In()
  1027. p.P(`return 0, err`, num)
  1028. p.Out()
  1029. p.P(`}`)
  1030. p.P(`i -= n`, num)
  1031. p.callVarint(`n`, num)
  1032. }
  1033. func (p *marshalto) backward(varName string, varInt bool) {
  1034. p.P(`{`)
  1035. p.In()
  1036. p.P(`size, err := `, varName, `.MarshalToSizedBuffer(dAtA[:i])`)
  1037. p.P(`if err != nil {`)
  1038. p.In()
  1039. p.P(`return 0, err`)
  1040. p.Out()
  1041. p.P(`}`)
  1042. p.P(`i -= size`)
  1043. if varInt {
  1044. p.callVarint(`size`)
  1045. }
  1046. p.Out()
  1047. p.P(`}`)
  1048. }
  1049. func (p *marshalto) forward(varName string, varInt, protoSizer bool) {
  1050. p.P(`{`)
  1051. p.In()
  1052. if protoSizer {
  1053. p.P(`size := `, varName, `.ProtoSize()`)
  1054. } else {
  1055. p.P(`size := `, varName, `.Size()`)
  1056. }
  1057. p.P(`i -= size`)
  1058. p.P(`if _, err := `, varName, `.MarshalTo(dAtA[i:]); err != nil {`)
  1059. p.In()
  1060. p.P(`return 0, err`)
  1061. p.Out()
  1062. p.P(`}`)
  1063. p.Out()
  1064. if varInt {
  1065. p.callVarint(`size`)
  1066. }
  1067. p.P(`}`)
  1068. }
  1069. func init() {
  1070. generator.RegisterPlugin(NewMarshal())
  1071. }