encode.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  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 protojson
  5. import (
  6. "encoding/base64"
  7. "fmt"
  8. "google.golang.org/protobuf/internal/encoding/json"
  9. "google.golang.org/protobuf/internal/encoding/messageset"
  10. "google.golang.org/protobuf/internal/errors"
  11. "google.golang.org/protobuf/internal/filedesc"
  12. "google.golang.org/protobuf/internal/flags"
  13. "google.golang.org/protobuf/internal/genid"
  14. "google.golang.org/protobuf/internal/order"
  15. "google.golang.org/protobuf/internal/pragma"
  16. "google.golang.org/protobuf/proto"
  17. "google.golang.org/protobuf/reflect/protoreflect"
  18. "google.golang.org/protobuf/reflect/protoregistry"
  19. )
  20. const defaultIndent = " "
  21. // Format formats the message as a multiline string.
  22. // This function is only intended for human consumption and ignores errors.
  23. // Do not depend on the output being stable. It may change over time across
  24. // different versions of the program.
  25. func Format(m proto.Message) string {
  26. return MarshalOptions{Multiline: true}.Format(m)
  27. }
  28. // Marshal writes the given [proto.Message] in JSON format using default options.
  29. // Do not depend on the output being stable. It may change over time across
  30. // different versions of the program.
  31. func Marshal(m proto.Message) ([]byte, error) {
  32. return MarshalOptions{}.Marshal(m)
  33. }
  34. // MarshalOptions is a configurable JSON format marshaler.
  35. type MarshalOptions struct {
  36. pragma.NoUnkeyedLiterals
  37. // Multiline specifies whether the marshaler should format the output in
  38. // indented-form with every textual element on a new line.
  39. // If Indent is an empty string, then an arbitrary indent is chosen.
  40. Multiline bool
  41. // Indent specifies the set of indentation characters to use in a multiline
  42. // formatted output such that every entry is preceded by Indent and
  43. // terminated by a newline. If non-empty, then Multiline is treated as true.
  44. // Indent can only be composed of space or tab characters.
  45. Indent string
  46. // AllowPartial allows messages that have missing required fields to marshal
  47. // without returning an error. If AllowPartial is false (the default),
  48. // Marshal will return error if there are any missing required fields.
  49. AllowPartial bool
  50. // UseProtoNames uses proto field name instead of lowerCamelCase name in JSON
  51. // field names.
  52. UseProtoNames bool
  53. // UseEnumNumbers emits enum values as numbers.
  54. UseEnumNumbers bool
  55. // EmitUnpopulated specifies whether to emit unpopulated fields. It does not
  56. // emit unpopulated oneof fields or unpopulated extension fields.
  57. // The JSON value emitted for unpopulated fields are as follows:
  58. // ╔═══════╤════════════════════════════╗
  59. // ║ JSON │ Protobuf field ║
  60. // ╠═══════╪════════════════════════════╣
  61. // ║ false │ proto3 boolean fields ║
  62. // ║ 0 │ proto3 numeric fields ║
  63. // ║ "" │ proto3 string/bytes fields ║
  64. // ║ null │ proto2 scalar fields ║
  65. // ║ null │ message fields ║
  66. // ║ [] │ list fields ║
  67. // ║ {} │ map fields ║
  68. // ╚═══════╧════════════════════════════╝
  69. EmitUnpopulated bool
  70. // EmitDefaultValues specifies whether to emit default-valued primitive fields,
  71. // empty lists, and empty maps. The fields affected are as follows:
  72. // ╔═══════╤════════════════════════════════════════╗
  73. // ║ JSON │ Protobuf field ║
  74. // ╠═══════╪════════════════════════════════════════╣
  75. // ║ false │ non-optional scalar boolean fields ║
  76. // ║ 0 │ non-optional scalar numeric fields ║
  77. // ║ "" │ non-optional scalar string/byte fields ║
  78. // ║ [] │ empty repeated fields ║
  79. // ║ {} │ empty map fields ║
  80. // ╚═══════╧════════════════════════════════════════╝
  81. //
  82. // Behaves similarly to EmitUnpopulated, but does not emit "null"-value fields,
  83. // i.e. presence-sensing fields that are omitted will remain omitted to preserve
  84. // presence-sensing.
  85. // EmitUnpopulated takes precedence over EmitDefaultValues since the former generates
  86. // a strict superset of the latter.
  87. EmitDefaultValues bool
  88. // Resolver is used for looking up types when expanding google.protobuf.Any
  89. // messages. If nil, this defaults to using protoregistry.GlobalTypes.
  90. Resolver interface {
  91. protoregistry.ExtensionTypeResolver
  92. protoregistry.MessageTypeResolver
  93. }
  94. }
  95. // Format formats the message as a string.
  96. // This method is only intended for human consumption and ignores errors.
  97. // Do not depend on the output being stable. It may change over time across
  98. // different versions of the program.
  99. func (o MarshalOptions) Format(m proto.Message) string {
  100. if m == nil || !m.ProtoReflect().IsValid() {
  101. return "<nil>" // invalid syntax, but okay since this is for debugging
  102. }
  103. o.AllowPartial = true
  104. b, _ := o.Marshal(m)
  105. return string(b)
  106. }
  107. // Marshal marshals the given [proto.Message] in the JSON format using options in
  108. // MarshalOptions. Do not depend on the output being stable. It may change over
  109. // time across different versions of the program.
  110. func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
  111. return o.marshal(nil, m)
  112. }
  113. // MarshalAppend appends the JSON format encoding of m to b,
  114. // returning the result.
  115. func (o MarshalOptions) MarshalAppend(b []byte, m proto.Message) ([]byte, error) {
  116. return o.marshal(b, m)
  117. }
  118. // marshal is a centralized function that all marshal operations go through.
  119. // For profiling purposes, avoid changing the name of this function or
  120. // introducing other code paths for marshal that do not go through this.
  121. func (o MarshalOptions) marshal(b []byte, m proto.Message) ([]byte, error) {
  122. if o.Multiline && o.Indent == "" {
  123. o.Indent = defaultIndent
  124. }
  125. if o.Resolver == nil {
  126. o.Resolver = protoregistry.GlobalTypes
  127. }
  128. internalEnc, err := json.NewEncoder(b, o.Indent)
  129. if err != nil {
  130. return nil, err
  131. }
  132. // Treat nil message interface as an empty message,
  133. // in which case the output in an empty JSON object.
  134. if m == nil {
  135. return append(b, '{', '}'), nil
  136. }
  137. enc := encoder{internalEnc, o}
  138. if err := enc.marshalMessage(m.ProtoReflect(), ""); err != nil {
  139. return nil, err
  140. }
  141. if o.AllowPartial {
  142. return enc.Bytes(), nil
  143. }
  144. return enc.Bytes(), proto.CheckInitialized(m)
  145. }
  146. type encoder struct {
  147. *json.Encoder
  148. opts MarshalOptions
  149. }
  150. // typeFieldDesc is a synthetic field descriptor used for the "@type" field.
  151. var typeFieldDesc = func() protoreflect.FieldDescriptor {
  152. var fd filedesc.Field
  153. fd.L0.FullName = "@type"
  154. fd.L0.Index = -1
  155. fd.L1.Cardinality = protoreflect.Optional
  156. fd.L1.Kind = protoreflect.StringKind
  157. return &fd
  158. }()
  159. // typeURLFieldRanger wraps a protoreflect.Message and modifies its Range method
  160. // to additionally iterate over a synthetic field for the type URL.
  161. type typeURLFieldRanger struct {
  162. order.FieldRanger
  163. typeURL string
  164. }
  165. func (m typeURLFieldRanger) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
  166. if !f(typeFieldDesc, protoreflect.ValueOfString(m.typeURL)) {
  167. return
  168. }
  169. m.FieldRanger.Range(f)
  170. }
  171. // unpopulatedFieldRanger wraps a protoreflect.Message and modifies its Range
  172. // method to additionally iterate over unpopulated fields.
  173. type unpopulatedFieldRanger struct {
  174. protoreflect.Message
  175. skipNull bool
  176. }
  177. func (m unpopulatedFieldRanger) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
  178. fds := m.Descriptor().Fields()
  179. for i := 0; i < fds.Len(); i++ {
  180. fd := fds.Get(i)
  181. if m.Has(fd) || fd.ContainingOneof() != nil {
  182. continue // ignore populated fields and fields within a oneofs
  183. }
  184. v := m.Get(fd)
  185. isProto2Scalar := fd.Syntax() == protoreflect.Proto2 && fd.Default().IsValid()
  186. isSingularMessage := fd.Cardinality() != protoreflect.Repeated && fd.Message() != nil
  187. if isProto2Scalar || isSingularMessage {
  188. if m.skipNull {
  189. continue
  190. }
  191. v = protoreflect.Value{} // use invalid value to emit null
  192. }
  193. if !f(fd, v) {
  194. return
  195. }
  196. }
  197. m.Message.Range(f)
  198. }
  199. // marshalMessage marshals the fields in the given protoreflect.Message.
  200. // If the typeURL is non-empty, then a synthetic "@type" field is injected
  201. // containing the URL as the value.
  202. func (e encoder) marshalMessage(m protoreflect.Message, typeURL string) error {
  203. if !flags.ProtoLegacy && messageset.IsMessageSet(m.Descriptor()) {
  204. return errors.New("no support for proto1 MessageSets")
  205. }
  206. if marshal := wellKnownTypeMarshaler(m.Descriptor().FullName()); marshal != nil {
  207. return marshal(e, m)
  208. }
  209. e.StartObject()
  210. defer e.EndObject()
  211. var fields order.FieldRanger = m
  212. switch {
  213. case e.opts.EmitUnpopulated:
  214. fields = unpopulatedFieldRanger{Message: m, skipNull: false}
  215. case e.opts.EmitDefaultValues:
  216. fields = unpopulatedFieldRanger{Message: m, skipNull: true}
  217. }
  218. if typeURL != "" {
  219. fields = typeURLFieldRanger{fields, typeURL}
  220. }
  221. var err error
  222. order.RangeFields(fields, order.IndexNameFieldOrder, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
  223. name := fd.JSONName()
  224. if e.opts.UseProtoNames {
  225. name = fd.TextName()
  226. }
  227. if err = e.WriteName(name); err != nil {
  228. return false
  229. }
  230. if err = e.marshalValue(v, fd); err != nil {
  231. return false
  232. }
  233. return true
  234. })
  235. return err
  236. }
  237. // marshalValue marshals the given protoreflect.Value.
  238. func (e encoder) marshalValue(val protoreflect.Value, fd protoreflect.FieldDescriptor) error {
  239. switch {
  240. case fd.IsList():
  241. return e.marshalList(val.List(), fd)
  242. case fd.IsMap():
  243. return e.marshalMap(val.Map(), fd)
  244. default:
  245. return e.marshalSingular(val, fd)
  246. }
  247. }
  248. // marshalSingular marshals the given non-repeated field value. This includes
  249. // all scalar types, enums, messages, and groups.
  250. func (e encoder) marshalSingular(val protoreflect.Value, fd protoreflect.FieldDescriptor) error {
  251. if !val.IsValid() {
  252. e.WriteNull()
  253. return nil
  254. }
  255. switch kind := fd.Kind(); kind {
  256. case protoreflect.BoolKind:
  257. e.WriteBool(val.Bool())
  258. case protoreflect.StringKind:
  259. if e.WriteString(val.String()) != nil {
  260. return errors.InvalidUTF8(string(fd.FullName()))
  261. }
  262. case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
  263. e.WriteInt(val.Int())
  264. case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
  265. e.WriteUint(val.Uint())
  266. case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Uint64Kind,
  267. protoreflect.Sfixed64Kind, protoreflect.Fixed64Kind:
  268. // 64-bit integers are written out as JSON string.
  269. e.WriteString(val.String())
  270. case protoreflect.FloatKind:
  271. // Encoder.WriteFloat handles the special numbers NaN and infinites.
  272. e.WriteFloat(val.Float(), 32)
  273. case protoreflect.DoubleKind:
  274. // Encoder.WriteFloat handles the special numbers NaN and infinites.
  275. e.WriteFloat(val.Float(), 64)
  276. case protoreflect.BytesKind:
  277. e.WriteString(base64.StdEncoding.EncodeToString(val.Bytes()))
  278. case protoreflect.EnumKind:
  279. if fd.Enum().FullName() == genid.NullValue_enum_fullname {
  280. e.WriteNull()
  281. } else {
  282. desc := fd.Enum().Values().ByNumber(val.Enum())
  283. if e.opts.UseEnumNumbers || desc == nil {
  284. e.WriteInt(int64(val.Enum()))
  285. } else {
  286. e.WriteString(string(desc.Name()))
  287. }
  288. }
  289. case protoreflect.MessageKind, protoreflect.GroupKind:
  290. if err := e.marshalMessage(val.Message(), ""); err != nil {
  291. return err
  292. }
  293. default:
  294. panic(fmt.Sprintf("%v has unknown kind: %v", fd.FullName(), kind))
  295. }
  296. return nil
  297. }
  298. // marshalList marshals the given protoreflect.List.
  299. func (e encoder) marshalList(list protoreflect.List, fd protoreflect.FieldDescriptor) error {
  300. e.StartArray()
  301. defer e.EndArray()
  302. for i := 0; i < list.Len(); i++ {
  303. item := list.Get(i)
  304. if err := e.marshalSingular(item, fd); err != nil {
  305. return err
  306. }
  307. }
  308. return nil
  309. }
  310. // marshalMap marshals given protoreflect.Map.
  311. func (e encoder) marshalMap(mmap protoreflect.Map, fd protoreflect.FieldDescriptor) error {
  312. e.StartObject()
  313. defer e.EndObject()
  314. var err error
  315. order.RangeEntries(mmap, order.GenericKeyOrder, func(k protoreflect.MapKey, v protoreflect.Value) bool {
  316. if err = e.WriteName(k.String()); err != nil {
  317. return false
  318. }
  319. if err = e.marshalSingular(v, fd.MapValue()); err != nil {
  320. return false
  321. }
  322. return true
  323. })
  324. return err
  325. }