jsonpb.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. // Go support for Protocol Buffers - Google's data interchange format
  2. //
  3. // Copyright 2015 The Go Authors. All rights reserved.
  4. // https://github.com/golang/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. // * Neither the name of Google Inc. nor the names of its
  17. // contributors may be used to endorse or promote products derived from
  18. // this software without specific prior written permission.
  19. //
  20. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. /*
  32. Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON.
  33. It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json.
  34. This package produces a different output than the standard "encoding/json" package,
  35. which does not operate correctly on protocol buffers.
  36. */
  37. package jsonpb
  38. import (
  39. "bytes"
  40. "encoding/json"
  41. "fmt"
  42. "io"
  43. "reflect"
  44. "sort"
  45. "strconv"
  46. "strings"
  47. "github.com/gogo/protobuf/proto"
  48. )
  49. var (
  50. byteArrayType = reflect.TypeOf([]byte{})
  51. )
  52. // Marshaler is a configurable object for converting between
  53. // protocol buffer objects and a JSON representation for them.
  54. type Marshaler struct {
  55. // Whether to render enum values as integers, as opposed to string values.
  56. EnumsAsInts bool
  57. // Whether to render fields with zero values.
  58. EmitDefaults bool
  59. // A string to indent each level by. The presence of this field will
  60. // also cause a space to appear between the field separator and
  61. // value, and for newlines to be appear between fields and array
  62. // elements.
  63. Indent string
  64. }
  65. // Marshal marshals a protocol buffer into JSON.
  66. func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error {
  67. writer := &errWriter{writer: out}
  68. return m.marshalObject(writer, pb, "")
  69. }
  70. // MarshalToString converts a protocol buffer object to JSON string.
  71. func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) {
  72. var buf bytes.Buffer
  73. if err := m.Marshal(&buf, pb); err != nil {
  74. return "", err
  75. }
  76. return buf.String(), nil
  77. }
  78. type int32Slice []int32
  79. // For sorting extensions ids to ensure stable output.
  80. func (s int32Slice) Len() int { return len(s) }
  81. func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
  82. func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  83. // marshalObject writes a struct to the Writer.
  84. func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent string) error {
  85. out.write("{")
  86. if m.Indent != "" {
  87. out.write("\n")
  88. }
  89. s := reflect.ValueOf(v).Elem()
  90. firstField := true
  91. for i := 0; i < s.NumField(); i++ {
  92. value := s.Field(i)
  93. valueField := s.Type().Field(i)
  94. if strings.HasPrefix(valueField.Name, "XXX_") {
  95. continue
  96. }
  97. // IsNil will panic on most value kinds.
  98. switch value.Kind() {
  99. case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
  100. if value.IsNil() {
  101. continue
  102. }
  103. }
  104. if !m.EmitDefaults {
  105. switch value.Kind() {
  106. case reflect.Bool:
  107. if !value.Bool() {
  108. continue
  109. }
  110. case reflect.Int32, reflect.Int64:
  111. if value.Int() == 0 {
  112. continue
  113. }
  114. case reflect.Uint32, reflect.Uint64:
  115. if value.Uint() == 0 {
  116. continue
  117. }
  118. case reflect.Float32, reflect.Float64:
  119. if value.Float() == 0 {
  120. continue
  121. }
  122. case reflect.String:
  123. if value.Len() == 0 {
  124. continue
  125. }
  126. }
  127. }
  128. // Oneof fields need special handling.
  129. if valueField.Tag.Get("protobuf_oneof") != "" {
  130. // value is an interface containing &T{real_value}.
  131. sv := value.Elem().Elem() // interface -> *T -> T
  132. value = sv.Field(0)
  133. valueField = sv.Type().Field(0)
  134. }
  135. prop := jsonProperties(valueField)
  136. if !firstField {
  137. m.writeSep(out)
  138. }
  139. // If the map value is a cast type, it may not implement proto.Message, therefore
  140. // allow the struct tag to declare the underlying message type. Instead of changing
  141. // the signatures of the child types (and because prop.mvalue is not public), use
  142. // CustomType as a passer.
  143. if value.Kind() == reflect.Map {
  144. if tag := valueField.Tag.Get("protobuf"); tag != "" {
  145. for _, v := range strings.Split(tag, ",") {
  146. if !strings.HasPrefix(v, "castvaluetype=") {
  147. continue
  148. }
  149. v = strings.TrimPrefix(v, "castvaluetype=")
  150. prop.CustomType = v
  151. break
  152. }
  153. }
  154. }
  155. if err := m.marshalField(out, prop, value, indent); err != nil {
  156. return err
  157. }
  158. firstField = false
  159. }
  160. // Handle proto2 extensions.
  161. if ep, ok := v.(extendableProto); ok {
  162. extensions := proto.RegisteredExtensions(v)
  163. extensionMap := ep.ExtensionMap()
  164. // Sort extensions for stable output.
  165. ids := make([]int32, 0, len(extensionMap))
  166. for id := range extensionMap {
  167. ids = append(ids, id)
  168. }
  169. sort.Sort(int32Slice(ids))
  170. for _, id := range ids {
  171. desc := extensions[id]
  172. if desc == nil {
  173. // unknown extension
  174. continue
  175. }
  176. ext, extErr := proto.GetExtension(ep, desc)
  177. if extErr != nil {
  178. return extErr
  179. }
  180. value := reflect.ValueOf(ext)
  181. var prop proto.Properties
  182. prop.Parse(desc.Tag)
  183. prop.OrigName = fmt.Sprintf("[%s]", desc.Name)
  184. if !firstField {
  185. m.writeSep(out)
  186. }
  187. if err := m.marshalField(out, &prop, value, indent); err != nil {
  188. return err
  189. }
  190. firstField = false
  191. }
  192. }
  193. if m.Indent != "" {
  194. out.write("\n")
  195. out.write(indent)
  196. }
  197. out.write("}")
  198. return out.err
  199. }
  200. func (m *Marshaler) writeSep(out *errWriter) {
  201. if m.Indent != "" {
  202. out.write(",\n")
  203. } else {
  204. out.write(",")
  205. }
  206. }
  207. // marshalField writes field description and value to the Writer.
  208. func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
  209. if m.Indent != "" {
  210. out.write(indent)
  211. out.write(m.Indent)
  212. }
  213. out.write(`"`)
  214. out.write(prop.OrigName)
  215. out.write(`":`)
  216. if m.Indent != "" {
  217. out.write(" ")
  218. }
  219. if err := m.marshalValue(out, prop, v, indent); err != nil {
  220. return err
  221. }
  222. return nil
  223. }
  224. // marshalValue writes the value to the Writer.
  225. func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
  226. v = reflect.Indirect(v)
  227. // Handle repeated elements.
  228. if v.Type() != byteArrayType && v.Kind() == reflect.Slice {
  229. out.write("[")
  230. comma := ""
  231. for i := 0; i < v.Len(); i++ {
  232. sliceVal := v.Index(i)
  233. out.write(comma)
  234. if m.Indent != "" {
  235. out.write("\n")
  236. out.write(indent)
  237. out.write(m.Indent)
  238. out.write(m.Indent)
  239. }
  240. m.marshalValue(out, prop, sliceVal, indent+m.Indent)
  241. comma = ","
  242. }
  243. if m.Indent != "" {
  244. out.write("\n")
  245. out.write(indent)
  246. out.write(m.Indent)
  247. }
  248. out.write("]")
  249. return out.err
  250. }
  251. // Handle enumerations.
  252. if !m.EnumsAsInts && prop.Enum != "" {
  253. // Unknown enum values will are stringified by the proto library as their
  254. // value. Such values should _not_ be quoted or they will be interpreted
  255. // as an enum string instead of their value.
  256. enumStr := v.Interface().(fmt.Stringer).String()
  257. var valStr string
  258. if v.Kind() == reflect.Ptr {
  259. valStr = strconv.Itoa(int(v.Elem().Int()))
  260. } else {
  261. valStr = strconv.Itoa(int(v.Int()))
  262. }
  263. if m, ok := v.Interface().(interface {
  264. MarshalJSON() ([]byte, error)
  265. }); ok {
  266. data, err := m.MarshalJSON()
  267. if err != nil {
  268. return err
  269. }
  270. enumStr = string(data)
  271. enumStr, err = strconv.Unquote(enumStr)
  272. if err != nil {
  273. return err
  274. }
  275. }
  276. isKnownEnum := enumStr != valStr
  277. if isKnownEnum {
  278. out.write(`"`)
  279. }
  280. out.write(enumStr)
  281. if isKnownEnum {
  282. out.write(`"`)
  283. }
  284. return out.err
  285. }
  286. // Handle nested messages.
  287. if v.Kind() == reflect.Struct {
  288. i := v
  289. if v.CanAddr() {
  290. i = v.Addr()
  291. } else {
  292. i = reflect.New(v.Type())
  293. i.Elem().Set(v)
  294. }
  295. iface := i.Interface()
  296. if iface == nil {
  297. out.write(`null`)
  298. return out.err
  299. }
  300. pm, ok := iface.(proto.Message)
  301. if !ok {
  302. if prop.CustomType == "" {
  303. return fmt.Errorf("%v does not implement proto.Message", v.Type())
  304. }
  305. t := proto.MessageType(prop.CustomType)
  306. if t == nil || !i.Type().ConvertibleTo(t) {
  307. return fmt.Errorf("%v declared custom type %s but it is not convertible to %v", v.Type(), prop.CustomType, t)
  308. }
  309. pm = i.Convert(t).Interface().(proto.Message)
  310. }
  311. return m.marshalObject(out, pm, indent+m.Indent)
  312. }
  313. // Handle maps.
  314. // Since Go randomizes map iteration, we sort keys for stable output.
  315. if v.Kind() == reflect.Map {
  316. out.write(`{`)
  317. keys := v.MapKeys()
  318. sort.Sort(mapKeys(keys))
  319. for i, k := range keys {
  320. if i > 0 {
  321. out.write(`,`)
  322. }
  323. if m.Indent != "" {
  324. out.write("\n")
  325. out.write(indent)
  326. out.write(m.Indent)
  327. out.write(m.Indent)
  328. }
  329. b, err := json.Marshal(k.Interface())
  330. if err != nil {
  331. return err
  332. }
  333. s := string(b)
  334. // If the JSON is not a string value, encode it again to make it one.
  335. if !strings.HasPrefix(s, `"`) {
  336. b, err := json.Marshal(s)
  337. if err != nil {
  338. return err
  339. }
  340. s = string(b)
  341. }
  342. out.write(s)
  343. out.write(`:`)
  344. if m.Indent != "" {
  345. out.write(` `)
  346. }
  347. if err := m.marshalValue(out, prop, v.MapIndex(k), indent+m.Indent); err != nil {
  348. return err
  349. }
  350. }
  351. if m.Indent != "" {
  352. out.write("\n")
  353. out.write(indent)
  354. out.write(m.Indent)
  355. }
  356. out.write(`}`)
  357. return out.err
  358. }
  359. // Default handling defers to the encoding/json library.
  360. b, err := json.Marshal(v.Interface())
  361. if err != nil {
  362. return err
  363. }
  364. needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64)
  365. if needToQuote {
  366. out.write(`"`)
  367. }
  368. out.write(string(b))
  369. if needToQuote {
  370. out.write(`"`)
  371. }
  372. return out.err
  373. }
  374. // Unmarshal unmarshals a JSON object stream into a protocol
  375. // buffer. This function is lenient and will decode any options
  376. // permutations of the related Marshaler.
  377. func Unmarshal(r io.Reader, pb proto.Message) error {
  378. inputValue := json.RawMessage{}
  379. if err := json.NewDecoder(r).Decode(&inputValue); err != nil {
  380. return err
  381. }
  382. return unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue)
  383. }
  384. // UnmarshalString will populate the fields of a protocol buffer based
  385. // on a JSON string. This function is lenient and will decode any options
  386. // permutations of the related Marshaler.
  387. func UnmarshalString(str string, pb proto.Message) error {
  388. return Unmarshal(strings.NewReader(str), pb)
  389. }
  390. // unmarshalValue converts/copies a value into the target.
  391. func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
  392. targetType := target.Type()
  393. // Allocate memory for pointer fields.
  394. if targetType.Kind() == reflect.Ptr {
  395. target.Set(reflect.New(targetType.Elem()))
  396. return unmarshalValue(target.Elem(), inputValue)
  397. }
  398. // Handle nested messages.
  399. if targetType.Kind() == reflect.Struct {
  400. var jsonFields map[string]json.RawMessage
  401. if err := json.Unmarshal(inputValue, &jsonFields); err != nil {
  402. return err
  403. }
  404. sprops := proto.GetProperties(targetType)
  405. for i := 0; i < target.NumField(); i++ {
  406. ft := target.Type().Field(i)
  407. if strings.HasPrefix(ft.Name, "XXX_") {
  408. continue
  409. }
  410. fieldName := jsonProperties(ft).OrigName
  411. valueForField, ok := jsonFields[fieldName]
  412. if !ok {
  413. continue
  414. }
  415. delete(jsonFields, fieldName)
  416. // Handle enums, which have an underlying type of int32,
  417. // and may appear as strings. We do this while handling
  418. // the struct so we have access to the enum info.
  419. // The case of an enum appearing as a number is handled
  420. // by the recursive call to unmarshalValue.
  421. if enum := sprops.Prop[i].Enum; valueForField[0] == '"' && enum != "" {
  422. vmap := proto.EnumValueMap(enum)
  423. // Don't need to do unquoting; valid enum names
  424. // are from a limited character set.
  425. s := valueForField[1 : len(valueForField)-1]
  426. n, ok := vmap[string(s)]
  427. if !ok {
  428. return fmt.Errorf("unknown value %q for enum %s", s, enum)
  429. }
  430. f := target.Field(i)
  431. if f.Kind() == reflect.Ptr { // proto2
  432. f.Set(reflect.New(f.Type().Elem()))
  433. f = f.Elem()
  434. }
  435. f.SetInt(int64(n))
  436. continue
  437. }
  438. if err := unmarshalValue(target.Field(i), valueForField); err != nil {
  439. return err
  440. }
  441. }
  442. // Check for any oneof fields.
  443. for fname, raw := range jsonFields {
  444. if oop, ok := sprops.OneofTypes[fname]; ok {
  445. nv := reflect.New(oop.Type.Elem())
  446. target.Field(oop.Field).Set(nv)
  447. if err := unmarshalValue(nv.Elem().Field(0), raw); err != nil {
  448. return err
  449. }
  450. delete(jsonFields, fname)
  451. }
  452. }
  453. if len(jsonFields) > 0 {
  454. // Pick any field to be the scapegoat.
  455. var f string
  456. for fname := range jsonFields {
  457. f = fname
  458. break
  459. }
  460. return fmt.Errorf("unknown field %q in %v", f, targetType)
  461. }
  462. return nil
  463. }
  464. // Handle arrays (which aren't encoded bytes)
  465. if targetType != byteArrayType && targetType.Kind() == reflect.Slice {
  466. var slc []json.RawMessage
  467. if err := json.Unmarshal(inputValue, &slc); err != nil {
  468. return err
  469. }
  470. len := len(slc)
  471. target.Set(reflect.MakeSlice(targetType, len, len))
  472. for i := 0; i < len; i++ {
  473. if err := unmarshalValue(target.Index(i), slc[i]); err != nil {
  474. return err
  475. }
  476. }
  477. return nil
  478. }
  479. // Handle maps (whose keys are always strings)
  480. if targetType.Kind() == reflect.Map {
  481. var mp map[string]json.RawMessage
  482. if err := json.Unmarshal(inputValue, &mp); err != nil {
  483. return err
  484. }
  485. target.Set(reflect.MakeMap(targetType))
  486. for ks, raw := range mp {
  487. // Unmarshal map key. The core json library already decoded the key into a
  488. // string, so we handle that specially. Other types were quoted post-serialization.
  489. var k reflect.Value
  490. if targetType.Key().Kind() == reflect.String {
  491. k = reflect.ValueOf(ks)
  492. } else {
  493. k = reflect.New(targetType.Key()).Elem()
  494. if err := unmarshalValue(k, json.RawMessage(ks)); err != nil {
  495. return err
  496. }
  497. }
  498. if !k.Type().AssignableTo(targetType.Key()) {
  499. k = k.Convert(targetType.Key())
  500. }
  501. // Unmarshal map value.
  502. v := reflect.New(targetType.Elem()).Elem()
  503. if err := unmarshalValue(v, raw); err != nil {
  504. return err
  505. }
  506. target.SetMapIndex(k, v)
  507. }
  508. return nil
  509. }
  510. // 64-bit integers can be encoded as strings. In this case we drop
  511. // the quotes and proceed as normal.
  512. isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64
  513. if isNum && strings.HasPrefix(string(inputValue), `"`) {
  514. inputValue = inputValue[1 : len(inputValue)-1]
  515. }
  516. // Use the encoding/json for parsing other value types.
  517. return json.Unmarshal(inputValue, target.Addr().Interface())
  518. }
  519. // jsonProperties returns parsed proto.Properties for the field.
  520. func jsonProperties(f reflect.StructField) *proto.Properties {
  521. var prop proto.Properties
  522. prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f)
  523. return &prop
  524. }
  525. // extendableProto is an interface implemented by any protocol buffer that may be extended.
  526. type extendableProto interface {
  527. proto.Message
  528. ExtensionRangeArray() []proto.ExtensionRange
  529. ExtensionMap() map[int32]proto.Extension
  530. }
  531. // Writer wrapper inspired by https://blog.golang.org/errors-are-values
  532. type errWriter struct {
  533. writer io.Writer
  534. err error
  535. }
  536. func (w *errWriter) write(str string) {
  537. if w.err != nil {
  538. return
  539. }
  540. _, w.err = w.writer.Write([]byte(str))
  541. }
  542. // Map fields may have key types of non-float scalars, strings and enums.
  543. // The easiest way to sort them in some deterministic order is to use fmt.
  544. // If this turns out to be inefficient we can always consider other options,
  545. // such as doing a Schwartzian transform.
  546. type mapKeys []reflect.Value
  547. func (s mapKeys) Len() int { return len(s) }
  548. func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  549. func (s mapKeys) Less(i, j int) bool {
  550. return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
  551. }