jsonpb.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  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. "errors"
  42. "fmt"
  43. "io"
  44. "reflect"
  45. "sort"
  46. "strconv"
  47. "strings"
  48. "time"
  49. "github.com/golang/protobuf/proto"
  50. )
  51. var (
  52. byteArrayType = reflect.TypeOf([]byte{})
  53. )
  54. // Marshaler is a configurable object for converting between
  55. // protocol buffer objects and a JSON representation for them.
  56. type Marshaler struct {
  57. // Whether to render enum values as integers, as opposed to string values.
  58. EnumsAsInts bool
  59. // Whether to render fields with zero values.
  60. EmitDefaults bool
  61. // A string to indent each level by. The presence of this field will
  62. // also cause a space to appear between the field separator and
  63. // value, and for newlines to be appear between fields and array
  64. // elements.
  65. Indent string
  66. // Whether to use the original (.proto) name for fields.
  67. OrigName bool
  68. }
  69. // Marshal marshals a protocol buffer into JSON.
  70. func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error {
  71. writer := &errWriter{writer: out}
  72. return m.marshalObject(writer, pb, "", "")
  73. }
  74. // MarshalToString converts a protocol buffer object to JSON string.
  75. func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) {
  76. var buf bytes.Buffer
  77. if err := m.Marshal(&buf, pb); err != nil {
  78. return "", err
  79. }
  80. return buf.String(), nil
  81. }
  82. type int32Slice []int32
  83. // For sorting extensions ids to ensure stable output.
  84. func (s int32Slice) Len() int { return len(s) }
  85. func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
  86. func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  87. type wkt interface {
  88. XXX_WellKnownType() string
  89. }
  90. // marshalObject writes a struct to the Writer.
  91. func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeURL string) error {
  92. s := reflect.ValueOf(v).Elem()
  93. // Handle well-known types.
  94. if wkt, ok := v.(wkt); ok {
  95. switch wkt.XXX_WellKnownType() {
  96. case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
  97. "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
  98. // "Wrappers use the same representation in JSON
  99. // as the wrapped primitive type, ..."
  100. sprop := proto.GetProperties(s.Type())
  101. return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent)
  102. case "Any":
  103. // Any is a bit more involved.
  104. return m.marshalAny(out, v, indent)
  105. case "Duration":
  106. // "Generated output always contains 3, 6, or 9 fractional digits,
  107. // depending on required precision."
  108. s, ns := s.Field(0).Int(), s.Field(1).Int()
  109. d := time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond
  110. x := fmt.Sprintf("%.9f", d.Seconds())
  111. x = strings.TrimSuffix(x, "000")
  112. x = strings.TrimSuffix(x, "000")
  113. out.write(`"`)
  114. out.write(x)
  115. out.write(`s"`)
  116. return out.err
  117. case "Struct":
  118. // Let marshalValue handle the `fields` map.
  119. // TODO: pass the correct Properties if needed.
  120. return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent)
  121. case "Timestamp":
  122. // "RFC 3339, where generated output will always be Z-normalized
  123. // and uses 3, 6 or 9 fractional digits."
  124. s, ns := s.Field(0).Int(), s.Field(1).Int()
  125. t := time.Unix(s, ns).UTC()
  126. // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits).
  127. x := t.Format("2006-01-02T15:04:05.000000000")
  128. x = strings.TrimSuffix(x, "000")
  129. x = strings.TrimSuffix(x, "000")
  130. out.write(`"`)
  131. out.write(x)
  132. out.write(`Z"`)
  133. return out.err
  134. case "Value":
  135. // Value has a single oneof.
  136. kind := s.Field(0)
  137. if kind.IsNil() {
  138. // "absence of any variant indicates an error"
  139. return errors.New("nil Value")
  140. }
  141. // oneof -> *T -> T -> T.F
  142. x := kind.Elem().Elem().Field(0)
  143. // TODO: pass the correct Properties if needed.
  144. return m.marshalValue(out, &proto.Properties{}, x, indent)
  145. }
  146. }
  147. out.write("{")
  148. if m.Indent != "" {
  149. out.write("\n")
  150. }
  151. firstField := true
  152. if typeURL != "" {
  153. if err := m.marshalTypeURL(out, indent, typeURL); err != nil {
  154. return err
  155. }
  156. firstField = false
  157. }
  158. for i := 0; i < s.NumField(); i++ {
  159. value := s.Field(i)
  160. valueField := s.Type().Field(i)
  161. if strings.HasPrefix(valueField.Name, "XXX_") {
  162. continue
  163. }
  164. // IsNil will panic on most value kinds.
  165. switch value.Kind() {
  166. case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
  167. if value.IsNil() {
  168. continue
  169. }
  170. }
  171. if !m.EmitDefaults {
  172. switch value.Kind() {
  173. case reflect.Bool:
  174. if !value.Bool() {
  175. continue
  176. }
  177. case reflect.Int32, reflect.Int64:
  178. if value.Int() == 0 {
  179. continue
  180. }
  181. case reflect.Uint32, reflect.Uint64:
  182. if value.Uint() == 0 {
  183. continue
  184. }
  185. case reflect.Float32, reflect.Float64:
  186. if value.Float() == 0 {
  187. continue
  188. }
  189. case reflect.String:
  190. if value.Len() == 0 {
  191. continue
  192. }
  193. }
  194. }
  195. // Oneof fields need special handling.
  196. if valueField.Tag.Get("protobuf_oneof") != "" {
  197. // value is an interface containing &T{real_value}.
  198. sv := value.Elem().Elem() // interface -> *T -> T
  199. value = sv.Field(0)
  200. valueField = sv.Type().Field(0)
  201. }
  202. prop := jsonProperties(valueField, m.OrigName)
  203. if !firstField {
  204. m.writeSep(out)
  205. }
  206. if err := m.marshalField(out, prop, value, indent); err != nil {
  207. return err
  208. }
  209. firstField = false
  210. }
  211. // Handle proto2 extensions.
  212. if ep, ok := v.(extendableProto); ok {
  213. extensions := proto.RegisteredExtensions(v)
  214. extensionMap := ep.ExtensionMap()
  215. // Sort extensions for stable output.
  216. ids := make([]int32, 0, len(extensionMap))
  217. for id := range extensionMap {
  218. ids = append(ids, id)
  219. }
  220. sort.Sort(int32Slice(ids))
  221. for _, id := range ids {
  222. desc := extensions[id]
  223. if desc == nil {
  224. // unknown extension
  225. continue
  226. }
  227. ext, extErr := proto.GetExtension(ep, desc)
  228. if extErr != nil {
  229. return extErr
  230. }
  231. value := reflect.ValueOf(ext)
  232. var prop proto.Properties
  233. prop.Parse(desc.Tag)
  234. prop.JSONName = fmt.Sprintf("[%s]", desc.Name)
  235. if !firstField {
  236. m.writeSep(out)
  237. }
  238. if err := m.marshalField(out, &prop, value, indent); err != nil {
  239. return err
  240. }
  241. firstField = false
  242. }
  243. }
  244. if m.Indent != "" {
  245. out.write("\n")
  246. out.write(indent)
  247. }
  248. out.write("}")
  249. return out.err
  250. }
  251. func (m *Marshaler) writeSep(out *errWriter) {
  252. if m.Indent != "" {
  253. out.write(",\n")
  254. } else {
  255. out.write(",")
  256. }
  257. }
  258. func (m *Marshaler) marshalAny(out *errWriter, any proto.Message, indent string) error {
  259. // "If the Any contains a value that has a special JSON mapping,
  260. // it will be converted as follows: {"@type": xxx, "value": yyy}.
  261. // Otherwise, the value will be converted into a JSON object,
  262. // and the "@type" field will be inserted to indicate the actual data type."
  263. v := reflect.ValueOf(any).Elem()
  264. turl := v.Field(0).String()
  265. val := v.Field(1).Bytes()
  266. // Only the part of type_url after the last slash is relevant.
  267. mname := turl
  268. if slash := strings.LastIndex(mname, "/"); slash >= 0 {
  269. mname = mname[slash+1:]
  270. }
  271. mt := proto.MessageType(mname)
  272. if mt == nil {
  273. return fmt.Errorf("unknown message type %q", mname)
  274. }
  275. msg := reflect.New(mt.Elem()).Interface().(proto.Message)
  276. if err := proto.Unmarshal(val, msg); err != nil {
  277. return err
  278. }
  279. if _, ok := msg.(wkt); ok {
  280. out.write("{")
  281. if m.Indent != "" {
  282. out.write("\n")
  283. }
  284. if err := m.marshalTypeURL(out, indent, turl); err != nil {
  285. return err
  286. }
  287. m.writeSep(out)
  288. out.write(`"value":`)
  289. if err := m.marshalObject(out, msg, indent, ""); err != nil {
  290. return err
  291. }
  292. if m.Indent != "" {
  293. out.write("\n")
  294. out.write(indent)
  295. }
  296. out.write("}")
  297. return out.err
  298. }
  299. return m.marshalObject(out, msg, indent, turl)
  300. }
  301. func (m *Marshaler) marshalTypeURL(out *errWriter, indent, typeURL string) error {
  302. if m.Indent != "" {
  303. out.write(indent)
  304. out.write(m.Indent)
  305. }
  306. out.write(`"@type":`)
  307. if m.Indent != "" {
  308. out.write(" ")
  309. }
  310. b, err := json.Marshal(typeURL)
  311. if err != nil {
  312. return err
  313. }
  314. out.write(string(b))
  315. return out.err
  316. }
  317. // marshalField writes field description and value to the Writer.
  318. func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
  319. if m.Indent != "" {
  320. out.write(indent)
  321. out.write(m.Indent)
  322. }
  323. out.write(`"`)
  324. out.write(prop.JSONName)
  325. out.write(`":`)
  326. if m.Indent != "" {
  327. out.write(" ")
  328. }
  329. if err := m.marshalValue(out, prop, v, indent); err != nil {
  330. return err
  331. }
  332. return nil
  333. }
  334. // marshalValue writes the value to the Writer.
  335. func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
  336. var err error
  337. v = reflect.Indirect(v)
  338. // Handle repeated elements.
  339. if v.Type() != byteArrayType && v.Kind() == reflect.Slice {
  340. out.write("[")
  341. comma := ""
  342. for i := 0; i < v.Len(); i++ {
  343. sliceVal := v.Index(i)
  344. out.write(comma)
  345. if m.Indent != "" {
  346. out.write("\n")
  347. out.write(indent)
  348. out.write(m.Indent)
  349. out.write(m.Indent)
  350. }
  351. m.marshalValue(out, prop, sliceVal, indent+m.Indent)
  352. comma = ","
  353. }
  354. if m.Indent != "" {
  355. out.write("\n")
  356. out.write(indent)
  357. out.write(m.Indent)
  358. }
  359. out.write("]")
  360. return out.err
  361. }
  362. // Handle well-known types.
  363. // Most are handled up in marshalObject (because 99% are messages).
  364. type wkt interface {
  365. XXX_WellKnownType() string
  366. }
  367. if wkt, ok := v.Interface().(wkt); ok {
  368. switch wkt.XXX_WellKnownType() {
  369. case "NullValue":
  370. out.write("null")
  371. return out.err
  372. }
  373. }
  374. // Handle enumerations.
  375. if !m.EnumsAsInts && prop.Enum != "" {
  376. // Unknown enum values will are stringified by the proto library as their
  377. // value. Such values should _not_ be quoted or they will be interpreted
  378. // as an enum string instead of their value.
  379. enumStr := v.Interface().(fmt.Stringer).String()
  380. var valStr string
  381. if v.Kind() == reflect.Ptr {
  382. valStr = strconv.Itoa(int(v.Elem().Int()))
  383. } else {
  384. valStr = strconv.Itoa(int(v.Int()))
  385. }
  386. isKnownEnum := enumStr != valStr
  387. if isKnownEnum {
  388. out.write(`"`)
  389. }
  390. out.write(enumStr)
  391. if isKnownEnum {
  392. out.write(`"`)
  393. }
  394. return out.err
  395. }
  396. // Handle nested messages.
  397. if v.Kind() == reflect.Struct {
  398. return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent, "")
  399. }
  400. // Handle maps.
  401. // Since Go randomizes map iteration, we sort keys for stable output.
  402. if v.Kind() == reflect.Map {
  403. out.write(`{`)
  404. keys := v.MapKeys()
  405. sort.Sort(mapKeys(keys))
  406. for i, k := range keys {
  407. if i > 0 {
  408. out.write(`,`)
  409. }
  410. if m.Indent != "" {
  411. out.write("\n")
  412. out.write(indent)
  413. out.write(m.Indent)
  414. out.write(m.Indent)
  415. }
  416. b, err := json.Marshal(k.Interface())
  417. if err != nil {
  418. return err
  419. }
  420. s := string(b)
  421. // If the JSON is not a string value, encode it again to make it one.
  422. if !strings.HasPrefix(s, `"`) {
  423. b, err := json.Marshal(s)
  424. if err != nil {
  425. return err
  426. }
  427. s = string(b)
  428. }
  429. out.write(s)
  430. out.write(`:`)
  431. if m.Indent != "" {
  432. out.write(` `)
  433. }
  434. if err := m.marshalValue(out, prop, v.MapIndex(k), indent+m.Indent); err != nil {
  435. return err
  436. }
  437. }
  438. if m.Indent != "" {
  439. out.write("\n")
  440. out.write(indent)
  441. out.write(m.Indent)
  442. }
  443. out.write(`}`)
  444. return out.err
  445. }
  446. // Default handling defers to the encoding/json library.
  447. b, err := json.Marshal(v.Interface())
  448. if err != nil {
  449. return err
  450. }
  451. needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64)
  452. if needToQuote {
  453. out.write(`"`)
  454. }
  455. out.write(string(b))
  456. if needToQuote {
  457. out.write(`"`)
  458. }
  459. return out.err
  460. }
  461. // UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
  462. // This function is lenient and will decode any options permutations of the
  463. // related Marshaler.
  464. func UnmarshalNext(dec *json.Decoder, pb proto.Message) error {
  465. inputValue := json.RawMessage{}
  466. if err := dec.Decode(&inputValue); err != nil {
  467. return err
  468. }
  469. return unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil)
  470. }
  471. // Unmarshal unmarshals a JSON object stream into a protocol
  472. // buffer. This function is lenient and will decode any options
  473. // permutations of the related Marshaler.
  474. func Unmarshal(r io.Reader, pb proto.Message) error {
  475. dec := json.NewDecoder(r)
  476. return UnmarshalNext(dec, pb)
  477. }
  478. // UnmarshalString will populate the fields of a protocol buffer based
  479. // on a JSON string. This function is lenient and will decode any options
  480. // permutations of the related Marshaler.
  481. func UnmarshalString(str string, pb proto.Message) error {
  482. return Unmarshal(strings.NewReader(str), pb)
  483. }
  484. // unmarshalValue converts/copies a value into the target.
  485. // prop may be nil.
  486. func unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error {
  487. targetType := target.Type()
  488. // Allocate memory for pointer fields.
  489. if targetType.Kind() == reflect.Ptr {
  490. target.Set(reflect.New(targetType.Elem()))
  491. return unmarshalValue(target.Elem(), inputValue, prop)
  492. }
  493. // Handle well-known types.
  494. type wkt interface {
  495. XXX_WellKnownType() string
  496. }
  497. if wkt, ok := target.Addr().Interface().(wkt); ok {
  498. switch wkt.XXX_WellKnownType() {
  499. case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
  500. "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
  501. // "Wrappers use the same representation in JSON
  502. // as the wrapped primitive type, except that null is allowed."
  503. // encoding/json will turn JSON `null` into Go `nil`,
  504. // so we don't have to do any extra work.
  505. return unmarshalValue(target.Field(0), inputValue, prop)
  506. case "Any":
  507. return fmt.Errorf("unmarshaling Any not supported yet")
  508. case "Duration":
  509. unq, err := strconv.Unquote(string(inputValue))
  510. if err != nil {
  511. return err
  512. }
  513. d, err := time.ParseDuration(unq)
  514. if err != nil {
  515. return fmt.Errorf("bad Duration: %v", err)
  516. }
  517. ns := d.Nanoseconds()
  518. s := ns / 1e9
  519. ns %= 1e9
  520. target.Field(0).SetInt(s)
  521. target.Field(1).SetInt(ns)
  522. return nil
  523. case "Timestamp":
  524. unq, err := strconv.Unquote(string(inputValue))
  525. if err != nil {
  526. return err
  527. }
  528. t, err := time.Parse(time.RFC3339Nano, unq)
  529. if err != nil {
  530. return fmt.Errorf("bad Timestamp: %v", err)
  531. }
  532. ns := t.UnixNano()
  533. s := ns / 1e9
  534. ns %= 1e9
  535. target.Field(0).SetInt(s)
  536. target.Field(1).SetInt(ns)
  537. return nil
  538. }
  539. }
  540. // Handle enums, which have an underlying type of int32,
  541. // and may appear as strings.
  542. // The case of an enum appearing as a number is handled
  543. // at the bottom of this function.
  544. if inputValue[0] == '"' && prop != nil && prop.Enum != "" {
  545. vmap := proto.EnumValueMap(prop.Enum)
  546. // Don't need to do unquoting; valid enum names
  547. // are from a limited character set.
  548. s := inputValue[1 : len(inputValue)-1]
  549. n, ok := vmap[string(s)]
  550. if !ok {
  551. return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum)
  552. }
  553. if target.Kind() == reflect.Ptr { // proto2
  554. target.Set(reflect.New(targetType.Elem()))
  555. target = target.Elem()
  556. }
  557. target.SetInt(int64(n))
  558. return nil
  559. }
  560. // Handle nested messages.
  561. if targetType.Kind() == reflect.Struct {
  562. var jsonFields map[string]json.RawMessage
  563. if err := json.Unmarshal(inputValue, &jsonFields); err != nil {
  564. return err
  565. }
  566. consumeField := func(prop *proto.Properties) (json.RawMessage, bool) {
  567. // Be liberal in what names we accept; both orig_name and camelName are okay.
  568. fieldNames := acceptedJSONFieldNames(prop)
  569. vOrig, okOrig := jsonFields[fieldNames.orig]
  570. vCamel, okCamel := jsonFields[fieldNames.camel]
  571. if !okOrig && !okCamel {
  572. return nil, false
  573. }
  574. // If, for some reason, both are present in the data, favour the camelName.
  575. var raw json.RawMessage
  576. if okOrig {
  577. raw = vOrig
  578. delete(jsonFields, fieldNames.orig)
  579. }
  580. if okCamel {
  581. raw = vCamel
  582. delete(jsonFields, fieldNames.camel)
  583. }
  584. return raw, true
  585. }
  586. sprops := proto.GetProperties(targetType)
  587. for i := 0; i < target.NumField(); i++ {
  588. ft := target.Type().Field(i)
  589. if strings.HasPrefix(ft.Name, "XXX_") {
  590. continue
  591. }
  592. valueForField, ok := consumeField(sprops.Prop[i])
  593. if !ok {
  594. continue
  595. }
  596. if err := unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil {
  597. return err
  598. }
  599. }
  600. // Check for any oneof fields.
  601. if len(jsonFields) > 0 {
  602. for _, oop := range sprops.OneofTypes {
  603. raw, ok := consumeField(oop.Prop)
  604. if !ok {
  605. continue
  606. }
  607. nv := reflect.New(oop.Type.Elem())
  608. target.Field(oop.Field).Set(nv)
  609. if err := unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil {
  610. return err
  611. }
  612. }
  613. }
  614. if len(jsonFields) > 0 {
  615. // Pick any field to be the scapegoat.
  616. var f string
  617. for fname := range jsonFields {
  618. f = fname
  619. break
  620. }
  621. return fmt.Errorf("unknown field %q in %v", f, targetType)
  622. }
  623. return nil
  624. }
  625. // Handle arrays (which aren't encoded bytes)
  626. if targetType != byteArrayType && targetType.Kind() == reflect.Slice {
  627. var slc []json.RawMessage
  628. if err := json.Unmarshal(inputValue, &slc); err != nil {
  629. return err
  630. }
  631. len := len(slc)
  632. target.Set(reflect.MakeSlice(targetType, len, len))
  633. for i := 0; i < len; i++ {
  634. if err := unmarshalValue(target.Index(i), slc[i], prop); err != nil {
  635. return err
  636. }
  637. }
  638. return nil
  639. }
  640. // Handle maps (whose keys are always strings)
  641. if targetType.Kind() == reflect.Map {
  642. var mp map[string]json.RawMessage
  643. if err := json.Unmarshal(inputValue, &mp); err != nil {
  644. return err
  645. }
  646. target.Set(reflect.MakeMap(targetType))
  647. var keyprop, valprop *proto.Properties
  648. if prop != nil {
  649. // These could still be nil if the protobuf metadata is broken somehow.
  650. // TODO: This won't work because the fields are unexported.
  651. // We should probably just reparse them.
  652. //keyprop, valprop = prop.mkeyprop, prop.mvalprop
  653. }
  654. for ks, raw := range mp {
  655. // Unmarshal map key. The core json library already decoded the key into a
  656. // string, so we handle that specially. Other types were quoted post-serialization.
  657. var k reflect.Value
  658. if targetType.Key().Kind() == reflect.String {
  659. k = reflect.ValueOf(ks)
  660. } else {
  661. k = reflect.New(targetType.Key()).Elem()
  662. if err := unmarshalValue(k, json.RawMessage(ks), keyprop); err != nil {
  663. return err
  664. }
  665. }
  666. // Unmarshal map value.
  667. v := reflect.New(targetType.Elem()).Elem()
  668. if err := unmarshalValue(v, raw, valprop); err != nil {
  669. return err
  670. }
  671. target.SetMapIndex(k, v)
  672. }
  673. return nil
  674. }
  675. // 64-bit integers can be encoded as strings. In this case we drop
  676. // the quotes and proceed as normal.
  677. isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64
  678. if isNum && strings.HasPrefix(string(inputValue), `"`) {
  679. inputValue = inputValue[1 : len(inputValue)-1]
  680. }
  681. // Use the encoding/json for parsing other value types.
  682. return json.Unmarshal(inputValue, target.Addr().Interface())
  683. }
  684. // jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute.
  685. func jsonProperties(f reflect.StructField, origName bool) *proto.Properties {
  686. var prop proto.Properties
  687. prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f)
  688. if origName || prop.JSONName == "" {
  689. prop.JSONName = prop.OrigName
  690. }
  691. return &prop
  692. }
  693. type fieldNames struct {
  694. orig, camel string
  695. }
  696. func acceptedJSONFieldNames(prop *proto.Properties) fieldNames {
  697. opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName}
  698. if prop.JSONName != "" {
  699. opts.camel = prop.JSONName
  700. }
  701. return opts
  702. }
  703. // extendableProto is an interface implemented by any protocol buffer that may be extended.
  704. type extendableProto interface {
  705. proto.Message
  706. ExtensionRangeArray() []proto.ExtensionRange
  707. ExtensionMap() map[int32]proto.Extension
  708. }
  709. // Writer wrapper inspired by https://blog.golang.org/errors-are-values
  710. type errWriter struct {
  711. writer io.Writer
  712. err error
  713. }
  714. func (w *errWriter) write(str string) {
  715. if w.err != nil {
  716. return
  717. }
  718. _, w.err = w.writer.Write([]byte(str))
  719. }
  720. // Map fields may have key types of non-float scalars, strings and enums.
  721. // The easiest way to sort them in some deterministic order is to use fmt.
  722. // If this turns out to be inefficient we can always consider other options,
  723. // such as doing a Schwartzian transform.
  724. type mapKeys []reflect.Value
  725. func (s mapKeys) Len() int { return len(s) }
  726. func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  727. func (s mapKeys) Less(i, j int) bool {
  728. return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
  729. }