encode.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  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 jsonpb
  5. import (
  6. "encoding/base64"
  7. "sort"
  8. "github.com/golang/protobuf/v2/internal/encoding/json"
  9. "github.com/golang/protobuf/v2/internal/errors"
  10. "github.com/golang/protobuf/v2/internal/pragma"
  11. "github.com/golang/protobuf/v2/proto"
  12. pref "github.com/golang/protobuf/v2/reflect/protoreflect"
  13. descpb "github.com/golang/protobuf/v2/types/descriptor"
  14. )
  15. // Marshal writes the given proto.Message in JSON format using default options.
  16. func Marshal(m proto.Message) ([]byte, error) {
  17. return MarshalOptions{}.Marshal(m)
  18. }
  19. // MarshalOptions is a configurable JSON format marshaler.
  20. type MarshalOptions struct {
  21. pragma.NoUnkeyedLiterals
  22. // Set Compact to true to have output in a single line with no line breaks.
  23. Compact bool
  24. }
  25. // Marshal returns the given proto.Message in JSON format using options in MarshalOptions object.
  26. func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
  27. indent := " "
  28. if o.Compact {
  29. indent = ""
  30. }
  31. enc, err := newEncoder(indent)
  32. if err != nil {
  33. return nil, err
  34. }
  35. var nerr errors.NonFatal
  36. err = enc.marshalMessage(m.ProtoReflect())
  37. if !nerr.Merge(err) {
  38. return nil, err
  39. }
  40. return enc.Bytes(), nerr.E
  41. }
  42. // encoder encodes protoreflect values into JSON.
  43. type encoder struct {
  44. *json.Encoder
  45. }
  46. func newEncoder(indent string) (encoder, error) {
  47. enc, err := json.NewEncoder(indent)
  48. if err != nil {
  49. return encoder{}, errors.New("error in constructing an encoder: %v", err)
  50. }
  51. return encoder{enc}, nil
  52. }
  53. // marshalMessage marshals the given protoreflect.Message.
  54. func (e encoder) marshalMessage(m pref.Message) error {
  55. e.StartObject()
  56. defer e.EndObject()
  57. var nerr errors.NonFatal
  58. fieldDescs := m.Type().Fields()
  59. knownFields := m.KnownFields()
  60. // Marshal out known fields.
  61. for i := 0; i < fieldDescs.Len(); i++ {
  62. fd := fieldDescs.Get(i)
  63. num := fd.Number()
  64. if !knownFields.Has(num) {
  65. if fd.Cardinality() == pref.Required {
  66. // Treat unset required fields as a non-fatal error.
  67. nerr.AppendRequiredNotSet(string(fd.FullName()))
  68. }
  69. continue
  70. }
  71. name := fd.JSONName()
  72. if err := e.WriteName(name); !nerr.Merge(err) {
  73. return err
  74. }
  75. val := knownFields.Get(num)
  76. if err := e.marshalValue(val, fd); !nerr.Merge(err) {
  77. return err
  78. }
  79. }
  80. // Marshal out extensions.
  81. if err := e.marshalExtensions(knownFields); !nerr.Merge(err) {
  82. return err
  83. }
  84. return nerr.E
  85. }
  86. // marshalValue marshals the given protoreflect.Value.
  87. func (e encoder) marshalValue(val pref.Value, fd pref.FieldDescriptor) error {
  88. var nerr errors.NonFatal
  89. if fd.Cardinality() == pref.Repeated {
  90. // Map or repeated fields.
  91. if fd.IsMap() {
  92. if err := e.marshalMap(val.Map(), fd); !nerr.Merge(err) {
  93. return err
  94. }
  95. } else {
  96. if err := e.marshalList(val.List(), fd); !nerr.Merge(err) {
  97. return err
  98. }
  99. }
  100. } else {
  101. // Required or optional fields.
  102. if err := e.marshalSingular(val, fd); !nerr.Merge(err) {
  103. return err
  104. }
  105. }
  106. return nerr.E
  107. }
  108. // marshalSingular marshals the given non-repeated field value. This includes
  109. // all scalar types, enums, messages, and groups.
  110. func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error {
  111. var nerr errors.NonFatal
  112. switch kind := fd.Kind(); kind {
  113. case pref.BoolKind:
  114. e.WriteBool(val.Bool())
  115. case pref.StringKind:
  116. if err := e.WriteString(val.String()); !nerr.Merge(err) {
  117. return err
  118. }
  119. case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
  120. e.WriteInt(val.Int())
  121. case pref.Uint32Kind, pref.Fixed32Kind:
  122. e.WriteUint(val.Uint())
  123. case pref.Int64Kind, pref.Sint64Kind, pref.Uint64Kind,
  124. pref.Sfixed64Kind, pref.Fixed64Kind:
  125. // 64-bit integers are written out as JSON string.
  126. e.WriteString(val.String())
  127. case pref.FloatKind:
  128. // Encoder.WriteFloat handles the special numbers NaN and infinites.
  129. e.WriteFloat(val.Float(), 32)
  130. case pref.DoubleKind:
  131. // Encoder.WriteFloat handles the special numbers NaN and infinites.
  132. e.WriteFloat(val.Float(), 64)
  133. case pref.BytesKind:
  134. err := e.WriteString(base64.StdEncoding.EncodeToString(val.Bytes()))
  135. if !nerr.Merge(err) {
  136. return err
  137. }
  138. case pref.EnumKind:
  139. num := val.Enum()
  140. if desc := fd.EnumType().Values().ByNumber(num); desc != nil {
  141. err := e.WriteString(string(desc.Name()))
  142. if !nerr.Merge(err) {
  143. return err
  144. }
  145. } else {
  146. // Use numeric value if there is no enum value descriptor.
  147. e.WriteInt(int64(num))
  148. }
  149. case pref.MessageKind, pref.GroupKind:
  150. if err := e.marshalMessage(val.Message()); !nerr.Merge(err) {
  151. return err
  152. }
  153. default:
  154. return errors.New("%v has unknown kind: %v", fd.FullName(), kind)
  155. }
  156. return nerr.E
  157. }
  158. // marshalList marshals the given protoreflect.List.
  159. func (e encoder) marshalList(list pref.List, fd pref.FieldDescriptor) error {
  160. e.StartArray()
  161. defer e.EndArray()
  162. var nerr errors.NonFatal
  163. for i := 0; i < list.Len(); i++ {
  164. item := list.Get(i)
  165. if err := e.marshalSingular(item, fd); !nerr.Merge(err) {
  166. return err
  167. }
  168. }
  169. return nerr.E
  170. }
  171. type mapEntry struct {
  172. key pref.MapKey
  173. value pref.Value
  174. }
  175. // marshalMap marshals given protoreflect.Map.
  176. func (e encoder) marshalMap(mmap pref.Map, fd pref.FieldDescriptor) error {
  177. e.StartObject()
  178. defer e.EndObject()
  179. msgFields := fd.MessageType().Fields()
  180. keyType := msgFields.ByNumber(1)
  181. valType := msgFields.ByNumber(2)
  182. // Get a sorted list based on keyType first.
  183. entries := make([]mapEntry, 0, mmap.Len())
  184. mmap.Range(func(key pref.MapKey, val pref.Value) bool {
  185. entries = append(entries, mapEntry{key: key, value: val})
  186. return true
  187. })
  188. sortMap(keyType.Kind(), entries)
  189. // Write out sorted list.
  190. var nerr errors.NonFatal
  191. for _, entry := range entries {
  192. if err := e.WriteName(entry.key.String()); !nerr.Merge(err) {
  193. return err
  194. }
  195. if err := e.marshalSingular(entry.value, valType); !nerr.Merge(err) {
  196. return err
  197. }
  198. }
  199. return nerr.E
  200. }
  201. // sortMap orders list based on value of key field for deterministic ordering.
  202. func sortMap(keyKind pref.Kind, values []mapEntry) {
  203. sort.Slice(values, func(i, j int) bool {
  204. switch keyKind {
  205. case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind,
  206. pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
  207. return values[i].key.Int() < values[j].key.Int()
  208. case pref.Uint32Kind, pref.Fixed32Kind,
  209. pref.Uint64Kind, pref.Fixed64Kind:
  210. return values[i].key.Uint() < values[j].key.Uint()
  211. }
  212. return values[i].key.String() < values[j].key.String()
  213. })
  214. }
  215. // marshalExtensions marshals extension fields.
  216. func (e encoder) marshalExtensions(knownFields pref.KnownFields) error {
  217. type xtEntry struct {
  218. key string
  219. value pref.Value
  220. xtType pref.ExtensionType
  221. }
  222. xtTypes := knownFields.ExtensionTypes()
  223. // Get a sorted list based on field key first.
  224. entries := make([]xtEntry, 0, xtTypes.Len())
  225. xtTypes.Range(func(xt pref.ExtensionType) bool {
  226. name := xt.FullName()
  227. // If extended type is a MessageSet, set field name to be the message type name.
  228. if isMessageSetExtension(xt) {
  229. name = xt.MessageType().FullName()
  230. }
  231. num := xt.Number()
  232. if knownFields.Has(num) {
  233. // Use [name] format for JSON field name.
  234. pval := knownFields.Get(num)
  235. entries = append(entries, xtEntry{
  236. key: string(name),
  237. value: pval,
  238. xtType: xt,
  239. })
  240. }
  241. return true
  242. })
  243. // Sort extensions lexicographically.
  244. sort.Slice(entries, func(i, j int) bool {
  245. return entries[i].key < entries[j].key
  246. })
  247. // Write out sorted list.
  248. var nerr errors.NonFatal
  249. for _, entry := range entries {
  250. // JSON field name is the proto field name enclosed in [], similar to
  251. // textproto. This is consistent with Go v1 lib. C++ lib v3.7.0 does not
  252. // marshal out extension fields.
  253. if err := e.WriteName("[" + entry.key + "]"); !nerr.Merge(err) {
  254. return err
  255. }
  256. if err := e.marshalValue(entry.value, entry.xtType); !nerr.Merge(err) {
  257. return err
  258. }
  259. }
  260. return nerr.E
  261. }
  262. // isMessageSetExtension reports whether extension extends a message set.
  263. func isMessageSetExtension(xt pref.ExtensionType) bool {
  264. if xt.Name() != "message_set_extension" {
  265. return false
  266. }
  267. mt := xt.MessageType()
  268. if mt == nil {
  269. return false
  270. }
  271. if xt.FullName().Parent() != mt.FullName() {
  272. return false
  273. }
  274. xmt := xt.ExtendedType()
  275. if xmt.Fields().Len() != 0 {
  276. return false
  277. }
  278. opt := xmt.Options().(*descpb.MessageOptions)
  279. if opt == nil {
  280. return false
  281. }
  282. return opt.GetMessageSetWireFormat()
  283. }