encode.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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 proto
  5. import (
  6. "errors"
  7. "fmt"
  8. "google.golang.org/protobuf/encoding/protowire"
  9. "google.golang.org/protobuf/internal/encoding/messageset"
  10. "google.golang.org/protobuf/internal/order"
  11. "google.golang.org/protobuf/internal/pragma"
  12. "google.golang.org/protobuf/reflect/protoreflect"
  13. "google.golang.org/protobuf/runtime/protoiface"
  14. protoerrors "google.golang.org/protobuf/internal/errors"
  15. )
  16. // MarshalOptions configures the marshaler.
  17. //
  18. // Example usage:
  19. //
  20. // b, err := MarshalOptions{Deterministic: true}.Marshal(m)
  21. type MarshalOptions struct {
  22. pragma.NoUnkeyedLiterals
  23. // AllowPartial allows messages that have missing required fields to marshal
  24. // without returning an error. If AllowPartial is false (the default),
  25. // Marshal will return an error if there are any missing required fields.
  26. AllowPartial bool
  27. // Deterministic controls whether the same message will always be
  28. // serialized to the same bytes within the same binary.
  29. //
  30. // Setting this option guarantees that repeated serialization of
  31. // the same message will return the same bytes, and that different
  32. // processes of the same binary (which may be executing on different
  33. // machines) will serialize equal messages to the same bytes.
  34. // It has no effect on the resulting size of the encoded message compared
  35. // to a non-deterministic marshal.
  36. //
  37. // Note that the deterministic serialization is NOT canonical across
  38. // languages. It is not guaranteed to remain stable over time. It is
  39. // unstable across different builds with schema changes due to unknown
  40. // fields. Users who need canonical serialization (e.g., persistent
  41. // storage in a canonical form, fingerprinting, etc.) must define
  42. // their own canonicalization specification and implement their own
  43. // serializer rather than relying on this API.
  44. //
  45. // If deterministic serialization is requested, map entries will be
  46. // sorted by keys in lexographical order. This is an implementation
  47. // detail and subject to change.
  48. Deterministic bool
  49. // UseCachedSize indicates that the result of a previous Size call
  50. // may be reused.
  51. //
  52. // Setting this option asserts that:
  53. //
  54. // 1. Size has previously been called on this message with identical
  55. // options (except for UseCachedSize itself).
  56. //
  57. // 2. The message and all its submessages have not changed in any
  58. // way since the Size call.
  59. //
  60. // If either of these invariants is violated,
  61. // the results are undefined and may include panics or corrupted output.
  62. //
  63. // Implementations MAY take this option into account to provide
  64. // better performance, but there is no guarantee that they will do so.
  65. // There is absolutely no guarantee that Size followed by Marshal with
  66. // UseCachedSize set will perform equivalently to Marshal alone.
  67. UseCachedSize bool
  68. }
  69. // flags turns the specified MarshalOptions (user-facing) into
  70. // protoiface.MarshalInputFlags (used internally by the marshaler).
  71. //
  72. // See impl.marshalOptions.Options for the inverse operation.
  73. func (o MarshalOptions) flags() protoiface.MarshalInputFlags {
  74. var flags protoiface.MarshalInputFlags
  75. // Note: o.AllowPartial is always forced to true by MarshalOptions.marshal,
  76. // which is why it is not a part of MarshalInputFlags.
  77. if o.Deterministic {
  78. flags |= protoiface.MarshalDeterministic
  79. }
  80. if o.UseCachedSize {
  81. flags |= protoiface.MarshalUseCachedSize
  82. }
  83. return flags
  84. }
  85. // Marshal returns the wire-format encoding of m.
  86. //
  87. // This is the most common entry point for encoding a Protobuf message.
  88. //
  89. // See the [MarshalOptions] type if you need more control.
  90. func Marshal(m Message) ([]byte, error) {
  91. // Treat nil message interface as an empty message; nothing to output.
  92. if m == nil {
  93. return nil, nil
  94. }
  95. out, err := MarshalOptions{}.marshal(nil, m.ProtoReflect())
  96. if len(out.Buf) == 0 && err == nil {
  97. out.Buf = emptyBytesForMessage(m)
  98. }
  99. return out.Buf, err
  100. }
  101. // Marshal returns the wire-format encoding of m.
  102. func (o MarshalOptions) Marshal(m Message) ([]byte, error) {
  103. // Treat nil message interface as an empty message; nothing to output.
  104. if m == nil {
  105. return nil, nil
  106. }
  107. out, err := o.marshal(nil, m.ProtoReflect())
  108. if len(out.Buf) == 0 && err == nil {
  109. out.Buf = emptyBytesForMessage(m)
  110. }
  111. return out.Buf, err
  112. }
  113. // emptyBytesForMessage returns a nil buffer if and only if m is invalid,
  114. // otherwise it returns a non-nil empty buffer.
  115. //
  116. // This is to assist the edge-case where user-code does the following:
  117. //
  118. // m1.OptionalBytes, _ = proto.Marshal(m2)
  119. //
  120. // where they expect the proto2 "optional_bytes" field to be populated
  121. // if any only if m2 is a valid message.
  122. func emptyBytesForMessage(m Message) []byte {
  123. if m == nil || !m.ProtoReflect().IsValid() {
  124. return nil
  125. }
  126. return emptyBuf[:]
  127. }
  128. // MarshalAppend appends the wire-format encoding of m to b,
  129. // returning the result.
  130. //
  131. // This is a less common entry point than [Marshal], which is only needed if you
  132. // need to supply your own buffers for performance reasons.
  133. func (o MarshalOptions) MarshalAppend(b []byte, m Message) ([]byte, error) {
  134. // Treat nil message interface as an empty message; nothing to append.
  135. if m == nil {
  136. return b, nil
  137. }
  138. out, err := o.marshal(b, m.ProtoReflect())
  139. return out.Buf, err
  140. }
  141. // MarshalState returns the wire-format encoding of a message.
  142. //
  143. // This method permits fine-grained control over the marshaler.
  144. // Most users should use [Marshal] instead.
  145. func (o MarshalOptions) MarshalState(in protoiface.MarshalInput) (protoiface.MarshalOutput, error) {
  146. return o.marshal(in.Buf, in.Message)
  147. }
  148. // marshal is a centralized function that all marshal operations go through.
  149. // For profiling purposes, avoid changing the name of this function or
  150. // introducing other code paths for marshal that do not go through this.
  151. func (o MarshalOptions) marshal(b []byte, m protoreflect.Message) (out protoiface.MarshalOutput, err error) {
  152. allowPartial := o.AllowPartial
  153. o.AllowPartial = true
  154. if methods := protoMethods(m); methods != nil && methods.Marshal != nil &&
  155. !(o.Deterministic && methods.Flags&protoiface.SupportMarshalDeterministic == 0) {
  156. in := protoiface.MarshalInput{
  157. Message: m,
  158. Buf: b,
  159. Flags: o.flags(),
  160. }
  161. if methods.Size != nil {
  162. sout := methods.Size(protoiface.SizeInput{
  163. Message: m,
  164. Flags: in.Flags,
  165. })
  166. if cap(b) < len(b)+sout.Size {
  167. in.Buf = make([]byte, len(b), growcap(cap(b), len(b)+sout.Size))
  168. copy(in.Buf, b)
  169. }
  170. in.Flags |= protoiface.MarshalUseCachedSize
  171. }
  172. out, err = methods.Marshal(in)
  173. } else {
  174. out.Buf, err = o.marshalMessageSlow(b, m)
  175. }
  176. if err != nil {
  177. var mismatch *protoerrors.SizeMismatchError
  178. if errors.As(err, &mismatch) {
  179. return out, fmt.Errorf("marshaling %s: %v", string(m.Descriptor().FullName()), err)
  180. }
  181. return out, err
  182. }
  183. if allowPartial {
  184. return out, nil
  185. }
  186. return out, checkInitialized(m)
  187. }
  188. func (o MarshalOptions) marshalMessage(b []byte, m protoreflect.Message) ([]byte, error) {
  189. out, err := o.marshal(b, m)
  190. return out.Buf, err
  191. }
  192. // growcap scales up the capacity of a slice.
  193. //
  194. // Given a slice with a current capacity of oldcap and a desired
  195. // capacity of wantcap, growcap returns a new capacity >= wantcap.
  196. //
  197. // The algorithm is mostly identical to the one used by append as of Go 1.14.
  198. func growcap(oldcap, wantcap int) (newcap int) {
  199. if wantcap > oldcap*2 {
  200. newcap = wantcap
  201. } else if oldcap < 1024 {
  202. // The Go 1.14 runtime takes this case when len(s) < 1024,
  203. // not when cap(s) < 1024. The difference doesn't seem
  204. // significant here.
  205. newcap = oldcap * 2
  206. } else {
  207. newcap = oldcap
  208. for 0 < newcap && newcap < wantcap {
  209. newcap += newcap / 4
  210. }
  211. if newcap <= 0 {
  212. newcap = wantcap
  213. }
  214. }
  215. return newcap
  216. }
  217. func (o MarshalOptions) marshalMessageSlow(b []byte, m protoreflect.Message) ([]byte, error) {
  218. if messageset.IsMessageSet(m.Descriptor()) {
  219. return o.marshalMessageSet(b, m)
  220. }
  221. fieldOrder := order.AnyFieldOrder
  222. if o.Deterministic {
  223. // TODO: This should use a more natural ordering like NumberFieldOrder,
  224. // but doing so breaks golden tests that make invalid assumption about
  225. // output stability of this implementation.
  226. fieldOrder = order.LegacyFieldOrder
  227. }
  228. var err error
  229. order.RangeFields(m, fieldOrder, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
  230. b, err = o.marshalField(b, fd, v)
  231. return err == nil
  232. })
  233. if err != nil {
  234. return b, err
  235. }
  236. b = append(b, m.GetUnknown()...)
  237. return b, nil
  238. }
  239. func (o MarshalOptions) marshalField(b []byte, fd protoreflect.FieldDescriptor, value protoreflect.Value) ([]byte, error) {
  240. switch {
  241. case fd.IsList():
  242. return o.marshalList(b, fd, value.List())
  243. case fd.IsMap():
  244. return o.marshalMap(b, fd, value.Map())
  245. default:
  246. b = protowire.AppendTag(b, fd.Number(), wireTypes[fd.Kind()])
  247. return o.marshalSingular(b, fd, value)
  248. }
  249. }
  250. func (o MarshalOptions) marshalList(b []byte, fd protoreflect.FieldDescriptor, list protoreflect.List) ([]byte, error) {
  251. if fd.IsPacked() && list.Len() > 0 {
  252. b = protowire.AppendTag(b, fd.Number(), protowire.BytesType)
  253. b, pos := appendSpeculativeLength(b)
  254. for i, llen := 0, list.Len(); i < llen; i++ {
  255. var err error
  256. b, err = o.marshalSingular(b, fd, list.Get(i))
  257. if err != nil {
  258. return b, err
  259. }
  260. }
  261. b = finishSpeculativeLength(b, pos)
  262. return b, nil
  263. }
  264. kind := fd.Kind()
  265. for i, llen := 0, list.Len(); i < llen; i++ {
  266. var err error
  267. b = protowire.AppendTag(b, fd.Number(), wireTypes[kind])
  268. b, err = o.marshalSingular(b, fd, list.Get(i))
  269. if err != nil {
  270. return b, err
  271. }
  272. }
  273. return b, nil
  274. }
  275. func (o MarshalOptions) marshalMap(b []byte, fd protoreflect.FieldDescriptor, mapv protoreflect.Map) ([]byte, error) {
  276. keyf := fd.MapKey()
  277. valf := fd.MapValue()
  278. keyOrder := order.AnyKeyOrder
  279. if o.Deterministic {
  280. keyOrder = order.GenericKeyOrder
  281. }
  282. var err error
  283. order.RangeEntries(mapv, keyOrder, func(key protoreflect.MapKey, value protoreflect.Value) bool {
  284. b = protowire.AppendTag(b, fd.Number(), protowire.BytesType)
  285. var pos int
  286. b, pos = appendSpeculativeLength(b)
  287. b, err = o.marshalField(b, keyf, key.Value())
  288. if err != nil {
  289. return false
  290. }
  291. b, err = o.marshalField(b, valf, value)
  292. if err != nil {
  293. return false
  294. }
  295. b = finishSpeculativeLength(b, pos)
  296. return true
  297. })
  298. return b, err
  299. }
  300. // When encoding length-prefixed fields, we speculatively set aside some number of bytes
  301. // for the length, encode the data, and then encode the length (shifting the data if necessary
  302. // to make room).
  303. const speculativeLength = 1
  304. func appendSpeculativeLength(b []byte) ([]byte, int) {
  305. pos := len(b)
  306. b = append(b, "\x00\x00\x00\x00"[:speculativeLength]...)
  307. return b, pos
  308. }
  309. func finishSpeculativeLength(b []byte, pos int) []byte {
  310. mlen := len(b) - pos - speculativeLength
  311. msiz := protowire.SizeVarint(uint64(mlen))
  312. if msiz != speculativeLength {
  313. for i := 0; i < msiz-speculativeLength; i++ {
  314. b = append(b, 0)
  315. }
  316. copy(b[pos+msiz:], b[pos+speculativeLength:])
  317. b = b[:pos+msiz+mlen]
  318. }
  319. protowire.AppendVarint(b[:pos], uint64(mlen))
  320. return b
  321. }