blob: 02c8298b364dfcc8952b079469b5981c21f80db2 [file] [log] [blame]
Zack Williamse940c7a2019-08-21 14:25:39 -07001package dynamic
2
3// JSON marshalling and unmarshalling for dynamic messages
4
5import (
6 "bytes"
7 "encoding/base64"
8 "encoding/json"
9 "fmt"
10 "io"
11 "io/ioutil"
12 "math"
13 "reflect"
14 "sort"
15 "strconv"
16 "strings"
17
18 "github.com/golang/protobuf/jsonpb"
19 "github.com/golang/protobuf/proto"
20 "github.com/golang/protobuf/protoc-gen-go/descriptor"
21 // link in the well-known-types that have a special JSON format
22 _ "github.com/golang/protobuf/ptypes/any"
23 _ "github.com/golang/protobuf/ptypes/duration"
24 _ "github.com/golang/protobuf/ptypes/empty"
25 _ "github.com/golang/protobuf/ptypes/struct"
26 _ "github.com/golang/protobuf/ptypes/timestamp"
27 _ "github.com/golang/protobuf/ptypes/wrappers"
28
29 "github.com/jhump/protoreflect/desc"
30)
31
32var wellKnownTypeNames = map[string]struct{}{
33 "google.protobuf.Any": {},
34 "google.protobuf.Empty": {},
35 "google.protobuf.Duration": {},
36 "google.protobuf.Timestamp": {},
37 // struct.proto
38 "google.protobuf.Struct": {},
39 "google.protobuf.Value": {},
40 "google.protobuf.ListValue": {},
41 // wrappers.proto
42 "google.protobuf.DoubleValue": {},
43 "google.protobuf.FloatValue": {},
44 "google.protobuf.Int64Value": {},
45 "google.protobuf.UInt64Value": {},
46 "google.protobuf.Int32Value": {},
47 "google.protobuf.UInt32Value": {},
48 "google.protobuf.BoolValue": {},
49 "google.protobuf.StringValue": {},
50 "google.protobuf.BytesValue": {},
51}
52
53// MarshalJSON serializes this message to bytes in JSON format, returning an
54// error if the operation fails. The resulting bytes will be a valid UTF8
55// string.
56//
57// This method uses a compact form: no newlines, and spaces between fields and
58// between field identifiers and values are elided.
59//
60// This method is convenient shorthand for invoking MarshalJSONPB with a default
61// (zero value) marshaler:
62//
63// m.MarshalJSONPB(&jsonpb.Marshaler{})
64//
65// So enums are serialized using enum value name strings, and values that are
66// not present (including those with default/zero value for messages defined in
67// "proto3" syntax) are omitted.
68func (m *Message) MarshalJSON() ([]byte, error) {
69 return m.MarshalJSONPB(&jsonpb.Marshaler{})
70}
71
72// MarshalJSONIndent serializes this message to bytes in JSON format, returning
73// an error if the operation fails. The resulting bytes will be a valid UTF8
74// string.
75//
76// This method uses a "pretty-printed" form, with each field on its own line and
77// spaces between field identifiers and values. Indentation of two spaces is
78// used.
79//
80// This method is convenient shorthand for invoking MarshalJSONPB with a default
81// (zero value) marshaler:
82//
83// m.MarshalJSONPB(&jsonpb.Marshaler{Indent: " "})
84//
85// So enums are serialized using enum value name strings, and values that are
86// not present (including those with default/zero value for messages defined in
87// "proto3" syntax) are omitted.
88func (m *Message) MarshalJSONIndent() ([]byte, error) {
89 return m.MarshalJSONPB(&jsonpb.Marshaler{Indent: " "})
90}
91
92// MarshalJSONPB serializes this message to bytes in JSON format, returning an
93// error if the operation fails. The resulting bytes will be a valid UTF8
94// string. The given marshaler is used to convey options used during marshaling.
95//
96// If this message contains nested messages that are generated message types (as
97// opposed to dynamic messages), the given marshaler is used to marshal it.
98//
99// When marshaling any nested messages, any jsonpb.AnyResolver configured in the
100// given marshaler is augmented with knowledge of message types known to this
101// message's descriptor (and its enclosing file and set of transitive
102// dependencies).
103func (m *Message) MarshalJSONPB(opts *jsonpb.Marshaler) ([]byte, error) {
104 var b indentBuffer
105 b.indent = opts.Indent
106 if len(opts.Indent) == 0 {
107 b.indentCount = -1
108 }
109 b.comma = true
110 if err := m.marshalJSON(&b, opts); err != nil {
111 return nil, err
112 }
113 return b.Bytes(), nil
114}
115
116func (m *Message) marshalJSON(b *indentBuffer, opts *jsonpb.Marshaler) error {
Joey Armstrong903c69d2024-02-01 19:46:39 -0500117 if m == nil {
118 _, err := b.WriteString("null")
119 return err
120 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700121 if r, changed := wrapResolver(opts.AnyResolver, m.mf, m.md.GetFile()); changed {
122 newOpts := *opts
123 newOpts.AnyResolver = r
124 opts = &newOpts
125 }
126
127 if ok, err := marshalWellKnownType(m, b, opts); ok {
128 return err
129 }
130
131 err := b.WriteByte('{')
132 if err != nil {
133 return err
134 }
135 err = b.start()
136 if err != nil {
137 return err
138 }
139
140 var tags []int
141 if opts.EmitDefaults {
142 tags = m.allKnownFieldTags()
143 } else {
144 tags = m.knownFieldTags()
145 }
146
147 first := true
148
149 for _, tag := range tags {
150 itag := int32(tag)
151 fd := m.FindFieldDescriptor(itag)
152
153 v, ok := m.values[itag]
154 if !ok {
155 if fd.GetOneOf() != nil {
156 // don't print defaults for fields in a oneof
157 continue
158 }
159 v = fd.GetDefaultValue()
160 }
161
162 err := b.maybeNext(&first)
163 if err != nil {
164 return err
165 }
166 err = marshalKnownFieldJSON(b, fd, v, opts)
167 if err != nil {
168 return err
169 }
170 }
171
172 err = b.end()
173 if err != nil {
174 return err
175 }
176 err = b.WriteByte('}')
177 if err != nil {
178 return err
179 }
180
181 return nil
182}
183
184func marshalWellKnownType(m *Message, b *indentBuffer, opts *jsonpb.Marshaler) (bool, error) {
185 fqn := m.md.GetFullyQualifiedName()
186 if _, ok := wellKnownTypeNames[fqn]; !ok {
187 return false, nil
188 }
189
190 msgType := proto.MessageType(fqn)
191 if msgType == nil {
192 // wtf?
193 panic(fmt.Sprintf("could not find registered message type for %q", fqn))
194 }
195
196 // convert dynamic message to well-known type and let jsonpb marshal it
197 msg := reflect.New(msgType.Elem()).Interface().(proto.Message)
198 if err := m.MergeInto(msg); err != nil {
199 return true, err
200 }
201 return true, opts.Marshal(b, msg)
202}
203
204func marshalKnownFieldJSON(b *indentBuffer, fd *desc.FieldDescriptor, v interface{}, opts *jsonpb.Marshaler) error {
205 var jsonName string
206 if opts.OrigName {
207 jsonName = fd.GetName()
208 } else {
209 jsonName = fd.AsFieldDescriptorProto().GetJsonName()
210 if jsonName == "" {
211 jsonName = fd.GetName()
212 }
213 }
214 if fd.IsExtension() {
215 var scope string
216 switch parent := fd.GetParent().(type) {
217 case *desc.FileDescriptor:
218 scope = parent.GetPackage()
219 default:
220 scope = parent.GetFullyQualifiedName()
221 }
222 if scope == "" {
223 jsonName = fmt.Sprintf("[%s]", jsonName)
224 } else {
225 jsonName = fmt.Sprintf("[%s.%s]", scope, jsonName)
226 }
227 }
228 err := writeJsonString(b, jsonName)
229 if err != nil {
230 return err
231 }
232 err = b.sep()
233 if err != nil {
234 return err
235 }
236
237 if isNil(v) {
238 _, err := b.WriteString("null")
239 return err
240 }
241
242 if fd.IsMap() {
243 err = b.WriteByte('{')
244 if err != nil {
245 return err
246 }
247 err = b.start()
248 if err != nil {
249 return err
250 }
251
252 md := fd.GetMessageType()
253 vfd := md.FindFieldByNumber(2)
254
255 mp := v.(map[interface{}]interface{})
256 keys := make([]interface{}, 0, len(mp))
257 for k := range mp {
258 keys = append(keys, k)
259 }
260 sort.Sort(sortable(keys))
261 first := true
262 for _, mk := range keys {
263 mv := mp[mk]
264 err := b.maybeNext(&first)
265 if err != nil {
266 return err
267 }
268
269 err = marshalKnownFieldMapEntryJSON(b, mk, vfd, mv, opts)
270 if err != nil {
271 return err
272 }
273 }
274
275 err = b.end()
276 if err != nil {
277 return err
278 }
279 return b.WriteByte('}')
280
281 } else if fd.IsRepeated() {
282 err = b.WriteByte('[')
283 if err != nil {
284 return err
285 }
286 err = b.start()
287 if err != nil {
288 return err
289 }
290
291 sl := v.([]interface{})
292 first := true
293 for _, slv := range sl {
294 err := b.maybeNext(&first)
295 if err != nil {
296 return err
297 }
298 err = marshalKnownFieldValueJSON(b, fd, slv, opts)
299 if err != nil {
300 return err
301 }
302 }
303
304 err = b.end()
305 if err != nil {
306 return err
307 }
308 return b.WriteByte(']')
309
310 } else {
311 return marshalKnownFieldValueJSON(b, fd, v, opts)
312 }
313}
314
Scott Baker4a35a702019-11-26 08:17:33 -0800315// sortable is used to sort map keys. Values will be integers (int32, int64, uint32, and uint64),
316// bools, or strings.
317type sortable []interface{}
318
319func (s sortable) Len() int {
320 return len(s)
321}
322
323func (s sortable) Less(i, j int) bool {
324 vi := s[i]
325 vj := s[j]
326 switch reflect.TypeOf(vi).Kind() {
327 case reflect.Int32:
328 return vi.(int32) < vj.(int32)
329 case reflect.Int64:
330 return vi.(int64) < vj.(int64)
331 case reflect.Uint32:
332 return vi.(uint32) < vj.(uint32)
333 case reflect.Uint64:
334 return vi.(uint64) < vj.(uint64)
335 case reflect.String:
336 return vi.(string) < vj.(string)
337 case reflect.Bool:
338 return !vi.(bool) && vj.(bool)
339 default:
340 panic(fmt.Sprintf("cannot compare keys of type %v", reflect.TypeOf(vi)))
341 }
342}
343
344func (s sortable) Swap(i, j int) {
345 s[i], s[j] = s[j], s[i]
346}
347
Zack Williamse940c7a2019-08-21 14:25:39 -0700348func isNil(v interface{}) bool {
349 if v == nil {
350 return true
351 }
352 rv := reflect.ValueOf(v)
353 return rv.Kind() == reflect.Ptr && rv.IsNil()
354}
355
356func marshalKnownFieldMapEntryJSON(b *indentBuffer, mk interface{}, vfd *desc.FieldDescriptor, mv interface{}, opts *jsonpb.Marshaler) error {
357 rk := reflect.ValueOf(mk)
358 var strkey string
359 switch rk.Kind() {
360 case reflect.Bool:
361 strkey = strconv.FormatBool(rk.Bool())
362 case reflect.Int32, reflect.Int64:
363 strkey = strconv.FormatInt(rk.Int(), 10)
364 case reflect.Uint32, reflect.Uint64:
365 strkey = strconv.FormatUint(rk.Uint(), 10)
366 case reflect.String:
367 strkey = rk.String()
368 default:
369 return fmt.Errorf("invalid map key value: %v (%v)", mk, rk.Type())
370 }
Joey Armstrong903c69d2024-02-01 19:46:39 -0500371 err := writeJsonString(b, strkey)
Zack Williamse940c7a2019-08-21 14:25:39 -0700372 if err != nil {
373 return err
374 }
375 err = b.sep()
376 if err != nil {
377 return err
378 }
379 return marshalKnownFieldValueJSON(b, vfd, mv, opts)
380}
381
382func marshalKnownFieldValueJSON(b *indentBuffer, fd *desc.FieldDescriptor, v interface{}, opts *jsonpb.Marshaler) error {
383 rv := reflect.ValueOf(v)
384 switch rv.Kind() {
Scott Baker4a35a702019-11-26 08:17:33 -0800385 case reflect.Int64:
386 return writeJsonString(b, strconv.FormatInt(rv.Int(), 10))
387 case reflect.Int32:
Zack Williamse940c7a2019-08-21 14:25:39 -0700388 ed := fd.GetEnumType()
389 if !opts.EnumsAsInts && ed != nil {
390 n := int32(rv.Int())
391 vd := ed.FindValueByNumber(n)
392 if vd == nil {
393 _, err := b.WriteString(strconv.FormatInt(rv.Int(), 10))
394 return err
395 } else {
396 return writeJsonString(b, vd.GetName())
397 }
398 } else {
399 _, err := b.WriteString(strconv.FormatInt(rv.Int(), 10))
400 return err
401 }
Scott Baker4a35a702019-11-26 08:17:33 -0800402 case reflect.Uint64:
403 return writeJsonString(b, strconv.FormatUint(rv.Uint(), 10))
404 case reflect.Uint32:
Zack Williamse940c7a2019-08-21 14:25:39 -0700405 _, err := b.WriteString(strconv.FormatUint(rv.Uint(), 10))
406 return err
407 case reflect.Float32, reflect.Float64:
408 f := rv.Float()
409 var str string
410 if math.IsNaN(f) {
411 str = `"NaN"`
412 } else if math.IsInf(f, 1) {
413 str = `"Infinity"`
414 } else if math.IsInf(f, -1) {
415 str = `"-Infinity"`
416 } else {
417 var bits int
418 if rv.Kind() == reflect.Float32 {
419 bits = 32
420 } else {
421 bits = 64
422 }
423 str = strconv.FormatFloat(rv.Float(), 'g', -1, bits)
424 }
425 _, err := b.WriteString(str)
426 return err
427 case reflect.Bool:
428 _, err := b.WriteString(strconv.FormatBool(rv.Bool()))
429 return err
430 case reflect.Slice:
431 bstr := base64.StdEncoding.EncodeToString(rv.Bytes())
432 return writeJsonString(b, bstr)
433 case reflect.String:
434 return writeJsonString(b, rv.String())
435 default:
436 // must be a message
Joey Armstrong903c69d2024-02-01 19:46:39 -0500437 if isNil(v) {
438 _, err := b.WriteString("null")
439 return err
440 }
441
Zack Williamse940c7a2019-08-21 14:25:39 -0700442 if dm, ok := v.(*Message); ok {
443 return dm.marshalJSON(b, opts)
Joey Armstrong903c69d2024-02-01 19:46:39 -0500444 }
445
446 var err error
447 if b.indentCount <= 0 || len(b.indent) == 0 {
448 err = opts.Marshal(b, v.(proto.Message))
Zack Williamse940c7a2019-08-21 14:25:39 -0700449 } else {
Joey Armstrong903c69d2024-02-01 19:46:39 -0500450 str, err := opts.MarshalToString(v.(proto.Message))
451 if err != nil {
452 return err
453 }
454 indent := strings.Repeat(b.indent, b.indentCount)
455 pos := 0
456 // add indention prefix to each line
457 for pos < len(str) {
458 start := pos
459 nextPos := strings.Index(str[pos:], "\n")
460 if nextPos == -1 {
461 nextPos = len(str)
462 } else {
463 nextPos = pos + nextPos + 1 // include newline
Zack Williamse940c7a2019-08-21 14:25:39 -0700464 }
Joey Armstrong903c69d2024-02-01 19:46:39 -0500465 line := str[start:nextPos]
466 if pos > 0 {
467 _, err = b.WriteString(indent)
Zack Williamse940c7a2019-08-21 14:25:39 -0700468 if err != nil {
469 return err
470 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700471 }
Joey Armstrong903c69d2024-02-01 19:46:39 -0500472 _, err = b.WriteString(line)
473 if err != nil {
474 return err
475 }
476 pos = nextPos
Zack Williamse940c7a2019-08-21 14:25:39 -0700477 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700478 }
Joey Armstrong903c69d2024-02-01 19:46:39 -0500479 return err
Zack Williamse940c7a2019-08-21 14:25:39 -0700480 }
481}
482
483func writeJsonString(b *indentBuffer, s string) error {
484 if sbytes, err := json.Marshal(s); err != nil {
485 return err
486 } else {
487 _, err := b.Write(sbytes)
488 return err
489 }
490}
491
492// UnmarshalJSON de-serializes the message that is present, in JSON format, in
493// the given bytes into this message. It first resets the current message. It
494// returns an error if the given bytes do not contain a valid encoding of this
495// message type in JSON format.
496//
497// This method is shorthand for invoking UnmarshalJSONPB with a default (zero
498// value) unmarshaler:
499//
500// m.UnmarshalMergeJSONPB(&jsonpb.Unmarshaler{}, js)
501//
502// So unknown fields will result in an error, and no provided jsonpb.AnyResolver
503// will be used when parsing google.protobuf.Any messages.
504func (m *Message) UnmarshalJSON(js []byte) error {
505 return m.UnmarshalJSONPB(&jsonpb.Unmarshaler{}, js)
506}
507
508// UnmarshalMergeJSON de-serializes the message that is present, in JSON format,
509// in the given bytes into this message. Unlike UnmarshalJSON, it does not first
510// reset the message, instead merging the data in the given bytes into the
511// existing data in this message.
512func (m *Message) UnmarshalMergeJSON(js []byte) error {
513 return m.UnmarshalMergeJSONPB(&jsonpb.Unmarshaler{}, js)
514}
515
516// UnmarshalJSONPB de-serializes the message that is present, in JSON format, in
517// the given bytes into this message. The given unmarshaler conveys options used
518// when parsing the JSON. This function first resets the current message. It
519// returns an error if the given bytes do not contain a valid encoding of this
520// message type in JSON format.
521//
522// The decoding is lenient:
523// 1. The JSON can refer to fields either by their JSON name or by their
524// declared name.
525// 2. The JSON can use either numeric values or string names for enum values.
526//
527// When instantiating nested messages, if this message's associated factory
528// returns a generated message type (as opposed to a dynamic message), the given
529// unmarshaler is used to unmarshal it.
530//
531// When unmarshaling any nested messages, any jsonpb.AnyResolver configured in
532// the given unmarshaler is augmented with knowledge of message types known to
533// this message's descriptor (and its enclosing file and set of transitive
534// dependencies).
535func (m *Message) UnmarshalJSONPB(opts *jsonpb.Unmarshaler, js []byte) error {
536 m.Reset()
537 if err := m.UnmarshalMergeJSONPB(opts, js); err != nil {
538 return err
539 }
540 return m.Validate()
541}
542
543// UnmarshalMergeJSONPB de-serializes the message that is present, in JSON
544// format, in the given bytes into this message. The given unmarshaler conveys
545// options used when parsing the JSON. Unlike UnmarshalJSONPB, it does not first
546// reset the message, instead merging the data in the given bytes into the
547// existing data in this message.
548func (m *Message) UnmarshalMergeJSONPB(opts *jsonpb.Unmarshaler, js []byte) error {
549 r := newJsReader(js)
550 err := m.unmarshalJson(r, opts)
551 if err != nil {
552 return err
553 }
554 if t, err := r.poll(); err != io.EOF {
555 b, _ := ioutil.ReadAll(r.unread())
556 s := fmt.Sprintf("%v%s", t, string(b))
557 return fmt.Errorf("superfluous data found after JSON object: %q", s)
558 }
559 return nil
560}
561
562func unmarshalWellKnownType(m *Message, r *jsReader, opts *jsonpb.Unmarshaler) (bool, error) {
563 fqn := m.md.GetFullyQualifiedName()
564 if _, ok := wellKnownTypeNames[fqn]; !ok {
565 return false, nil
566 }
567
568 msgType := proto.MessageType(fqn)
569 if msgType == nil {
570 // wtf?
571 panic(fmt.Sprintf("could not find registered message type for %q", fqn))
572 }
573
574 // extract json value from r
575 var js json.RawMessage
576 if err := json.NewDecoder(r.unread()).Decode(&js); err != nil {
577 return true, err
578 }
579 if err := r.skip(); err != nil {
580 return true, err
581 }
582
583 // unmarshal into well-known type and then convert to dynamic message
584 msg := reflect.New(msgType.Elem()).Interface().(proto.Message)
585 if err := opts.Unmarshal(bytes.NewReader(js), msg); err != nil {
586 return true, err
587 }
588 return true, m.MergeFrom(msg)
589}
590
591func (m *Message) unmarshalJson(r *jsReader, opts *jsonpb.Unmarshaler) error {
592 if r, changed := wrapResolver(opts.AnyResolver, m.mf, m.md.GetFile()); changed {
593 newOpts := *opts
594 newOpts.AnyResolver = r
595 opts = &newOpts
596 }
597
598 if ok, err := unmarshalWellKnownType(m, r, opts); ok {
599 return err
600 }
601
602 t, err := r.peek()
603 if err != nil {
604 return err
605 }
606 if t == nil {
607 // if json is simply "null" we do nothing
608 r.poll()
609 return nil
610 }
611
612 if err := r.beginObject(); err != nil {
613 return err
614 }
615
616 for r.hasNext() {
617 f, err := r.nextObjectKey()
618 if err != nil {
619 return err
620 }
621 fd := m.FindFieldDescriptorByJSONName(f)
622 if fd == nil {
623 if opts.AllowUnknownFields {
624 r.skip()
625 continue
626 }
627 return fmt.Errorf("message type %s has no known field named %s", m.md.GetFullyQualifiedName(), f)
628 }
629 v, err := unmarshalJsField(fd, r, m.mf, opts)
630 if err != nil {
631 return err
632 }
633 if v != nil {
634 if err := mergeField(m, fd, v); err != nil {
635 return err
636 }
637 } else if fd.GetOneOf() != nil {
638 // preserve explicit null for oneof fields (this is a little odd but
639 // mimics the behavior of jsonpb with oneofs in generated message types)
640 if fd.GetMessageType() != nil {
641 typ := m.mf.GetKnownTypeRegistry().GetKnownType(fd.GetMessageType().GetFullyQualifiedName())
642 if typ != nil {
643 // typed nil
644 if typ.Kind() != reflect.Ptr {
645 typ = reflect.PtrTo(typ)
646 }
647 v = reflect.Zero(typ).Interface()
648 } else {
649 // can't use nil dynamic message, so we just use empty one instead
650 v = m.mf.NewDynamicMessage(fd.GetMessageType())
651 }
652 if err := m.setField(fd, v); err != nil {
653 return err
654 }
655 } else {
656 // not a message... explicit null makes no sense
657 return fmt.Errorf("message type %s cannot set field %s to null: it is not a message type", m.md.GetFullyQualifiedName(), f)
658 }
659 } else {
660 m.clearField(fd)
661 }
662 }
663
664 if err := r.endObject(); err != nil {
665 return err
666 }
667
668 return nil
669}
670
671func isWellKnownValue(fd *desc.FieldDescriptor) bool {
672 return !fd.IsRepeated() && fd.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE &&
673 fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.Value"
674}
675
676func isWellKnownListValue(fd *desc.FieldDescriptor) bool {
Joey Armstrong903c69d2024-02-01 19:46:39 -0500677 // we look for ListValue; but we also look for Value, which can be assigned a ListValue
Zack Williamse940c7a2019-08-21 14:25:39 -0700678 return !fd.IsRepeated() && fd.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE &&
Joey Armstrong903c69d2024-02-01 19:46:39 -0500679 (fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.ListValue" ||
680 fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.Value")
Zack Williamse940c7a2019-08-21 14:25:39 -0700681}
682
683func unmarshalJsField(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler) (interface{}, error) {
684 t, err := r.peek()
685 if err != nil {
686 return nil, err
687 }
688 if t == nil && !isWellKnownValue(fd) {
689 // if value is null, just return nil
690 // (unless field is google.protobuf.Value, in which case
691 // we fall through to parse it as an instance where its
692 // underlying value is set to a NullValue)
693 r.poll()
694 return nil, nil
695 }
696
697 if t == json.Delim('{') && fd.IsMap() {
698 entryType := fd.GetMessageType()
699 keyType := entryType.FindFieldByNumber(1)
700 valueType := entryType.FindFieldByNumber(2)
701 mp := map[interface{}]interface{}{}
702
703 // TODO: if there are just two map keys "key" and "value" and they have the right type of values,
704 // treat this JSON object as a single map entry message. (In keeping with support of map fields as
705 // if they were normal repeated field of entry messages as well as supporting a transition from
706 // optional to repeated...)
707
708 if err := r.beginObject(); err != nil {
709 return nil, err
710 }
711 for r.hasNext() {
Joey Armstrong903c69d2024-02-01 19:46:39 -0500712 kk, err := unmarshalJsFieldElement(keyType, r, mf, opts, false)
Zack Williamse940c7a2019-08-21 14:25:39 -0700713 if err != nil {
714 return nil, err
715 }
Joey Armstrong903c69d2024-02-01 19:46:39 -0500716 vv, err := unmarshalJsFieldElement(valueType, r, mf, opts, true)
Zack Williamse940c7a2019-08-21 14:25:39 -0700717 if err != nil {
718 return nil, err
719 }
720 mp[kk] = vv
721 }
722 if err := r.endObject(); err != nil {
723 return nil, err
724 }
725
726 return mp, nil
727 } else if t == json.Delim('[') && !isWellKnownListValue(fd) {
728 // We support parsing an array, even if field is not repeated, to mimic support in proto
729 // binary wire format that supports changing an optional field to repeated and vice versa.
730 // If the field is not repeated, we only keep the last value in the array.
731
732 if err := r.beginArray(); err != nil {
733 return nil, err
734 }
735 var sl []interface{}
736 var v interface{}
737 for r.hasNext() {
738 var err error
Joey Armstrong903c69d2024-02-01 19:46:39 -0500739 v, err = unmarshalJsFieldElement(fd, r, mf, opts, false)
Zack Williamse940c7a2019-08-21 14:25:39 -0700740 if err != nil {
741 return nil, err
742 }
743 if fd.IsRepeated() && v != nil {
744 sl = append(sl, v)
745 }
746 }
747 if err := r.endArray(); err != nil {
748 return nil, err
749 }
750 if fd.IsMap() {
751 mp := map[interface{}]interface{}{}
752 for _, m := range sl {
753 msg := m.(*Message)
754 kk, err := msg.TryGetFieldByNumber(1)
755 if err != nil {
756 return nil, err
757 }
758 vv, err := msg.TryGetFieldByNumber(2)
759 if err != nil {
760 return nil, err
761 }
762 mp[kk] = vv
763 }
764 return mp, nil
765 } else if fd.IsRepeated() {
766 return sl, nil
767 } else {
768 return v, nil
769 }
770 } else {
771 // We support parsing a singular value, even if field is repeated, to mimic support in proto
772 // binary wire format that supports changing an optional field to repeated and vice versa.
773 // If the field is repeated, we store value as singleton slice of that one value.
774
Joey Armstrong903c69d2024-02-01 19:46:39 -0500775 v, err := unmarshalJsFieldElement(fd, r, mf, opts, false)
Zack Williamse940c7a2019-08-21 14:25:39 -0700776 if err != nil {
777 return nil, err
778 }
779 if v == nil {
780 return nil, nil
781 }
782 if fd.IsRepeated() {
783 return []interface{}{v}, nil
784 } else {
785 return v, nil
786 }
787 }
788}
789
Joey Armstrong903c69d2024-02-01 19:46:39 -0500790func unmarshalJsFieldElement(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler, allowNilMessage bool) (interface{}, error) {
Zack Williamse940c7a2019-08-21 14:25:39 -0700791 t, err := r.peek()
792 if err != nil {
793 return nil, err
794 }
795
796 switch fd.GetType() {
797 case descriptor.FieldDescriptorProto_TYPE_MESSAGE,
798 descriptor.FieldDescriptorProto_TYPE_GROUP:
Joey Armstrong903c69d2024-02-01 19:46:39 -0500799
800 if t == nil && allowNilMessage {
801 // if json is simply "null" return a nil pointer
802 r.poll()
803 return nilMessage(fd.GetMessageType()), nil
804 }
805
Zack Williamse940c7a2019-08-21 14:25:39 -0700806 m := mf.NewMessage(fd.GetMessageType())
807 if dm, ok := m.(*Message); ok {
808 if err := dm.unmarshalJson(r, opts); err != nil {
809 return nil, err
810 }
811 } else {
812 var msg json.RawMessage
813 if err := json.NewDecoder(r.unread()).Decode(&msg); err != nil {
814 return nil, err
815 }
816 if err := r.skip(); err != nil {
817 return nil, err
818 }
819 if err := opts.Unmarshal(bytes.NewReader([]byte(msg)), m); err != nil {
820 return nil, err
821 }
822 }
823 return m, nil
824
825 case descriptor.FieldDescriptorProto_TYPE_ENUM:
826 if e, err := r.nextNumber(); err != nil {
827 return nil, err
828 } else {
829 // value could be string or number
830 if i, err := e.Int64(); err != nil {
831 // number cannot be parsed, so see if it's an enum value name
832 vd := fd.GetEnumType().FindValueByName(string(e))
833 if vd != nil {
834 return vd.GetNumber(), nil
835 } else {
836 return nil, fmt.Errorf("enum %q does not have value named %q", fd.GetEnumType().GetFullyQualifiedName(), e)
837 }
838 } else if i > math.MaxInt32 || i < math.MinInt32 {
839 return nil, NumericOverflowError
840 } else {
841 return int32(i), err
842 }
843 }
844
845 case descriptor.FieldDescriptorProto_TYPE_INT32,
846 descriptor.FieldDescriptorProto_TYPE_SINT32,
847 descriptor.FieldDescriptorProto_TYPE_SFIXED32:
848 if i, err := r.nextInt(); err != nil {
849 return nil, err
850 } else if i > math.MaxInt32 || i < math.MinInt32 {
851 return nil, NumericOverflowError
852 } else {
853 return int32(i), err
854 }
855
856 case descriptor.FieldDescriptorProto_TYPE_INT64,
857 descriptor.FieldDescriptorProto_TYPE_SINT64,
858 descriptor.FieldDescriptorProto_TYPE_SFIXED64:
859 return r.nextInt()
860
861 case descriptor.FieldDescriptorProto_TYPE_UINT32,
862 descriptor.FieldDescriptorProto_TYPE_FIXED32:
863 if i, err := r.nextUint(); err != nil {
864 return nil, err
865 } else if i > math.MaxUint32 {
866 return nil, NumericOverflowError
867 } else {
868 return uint32(i), err
869 }
870
871 case descriptor.FieldDescriptorProto_TYPE_UINT64,
872 descriptor.FieldDescriptorProto_TYPE_FIXED64:
873 return r.nextUint()
874
875 case descriptor.FieldDescriptorProto_TYPE_BOOL:
876 if str, ok := t.(string); ok {
877 if str == "true" {
878 r.poll() // consume token
879 return true, err
880 } else if str == "false" {
881 r.poll() // consume token
882 return false, err
883 }
884 }
885 return r.nextBool()
886
887 case descriptor.FieldDescriptorProto_TYPE_FLOAT:
888 if f, err := r.nextFloat(); err != nil {
889 return nil, err
890 } else {
891 return float32(f), nil
892 }
893
894 case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
895 return r.nextFloat()
896
897 case descriptor.FieldDescriptorProto_TYPE_BYTES:
898 return r.nextBytes()
899
900 case descriptor.FieldDescriptorProto_TYPE_STRING:
901 return r.nextString()
902
903 default:
904 return nil, fmt.Errorf("unknown field type: %v", fd.GetType())
905 }
906}
907
908type jsReader struct {
909 reader *bytes.Reader
910 dec *json.Decoder
911 current json.Token
912 peeked bool
913}
914
915func newJsReader(b []byte) *jsReader {
916 reader := bytes.NewReader(b)
917 dec := json.NewDecoder(reader)
918 dec.UseNumber()
919 return &jsReader{reader: reader, dec: dec}
920}
921
922func (r *jsReader) unread() io.Reader {
923 bufs := make([]io.Reader, 3)
924 var peeked []byte
925 if r.peeked {
926 if _, ok := r.current.(json.Delim); ok {
927 peeked = []byte(fmt.Sprintf("%v", r.current))
928 } else {
929 peeked, _ = json.Marshal(r.current)
930 }
931 }
932 readerCopy := *r.reader
933 decCopy := *r.dec
934
935 bufs[0] = bytes.NewReader(peeked)
936 bufs[1] = decCopy.Buffered()
937 bufs[2] = &readerCopy
938 return &concatReader{bufs: bufs}
939}
940
941func (r *jsReader) hasNext() bool {
942 return r.dec.More()
943}
944
945func (r *jsReader) peek() (json.Token, error) {
946 if r.peeked {
947 return r.current, nil
948 }
949 t, err := r.dec.Token()
950 if err != nil {
951 return nil, err
952 }
953 r.peeked = true
954 r.current = t
955 return t, nil
956}
957
958func (r *jsReader) poll() (json.Token, error) {
959 if r.peeked {
960 ret := r.current
961 r.current = nil
962 r.peeked = false
963 return ret, nil
964 }
965 return r.dec.Token()
966}
967
968func (r *jsReader) beginObject() error {
969 _, err := r.expect(func(t json.Token) bool { return t == json.Delim('{') }, nil, "start of JSON object: '{'")
970 return err
971}
972
973func (r *jsReader) endObject() error {
974 _, err := r.expect(func(t json.Token) bool { return t == json.Delim('}') }, nil, "end of JSON object: '}'")
975 return err
976}
977
978func (r *jsReader) beginArray() error {
979 _, err := r.expect(func(t json.Token) bool { return t == json.Delim('[') }, nil, "start of array: '['")
980 return err
981}
982
983func (r *jsReader) endArray() error {
984 _, err := r.expect(func(t json.Token) bool { return t == json.Delim(']') }, nil, "end of array: ']'")
985 return err
986}
987
988func (r *jsReader) nextObjectKey() (string, error) {
989 return r.nextString()
990}
991
992func (r *jsReader) nextString() (string, error) {
993 t, err := r.expect(func(t json.Token) bool { _, ok := t.(string); return ok }, "", "string")
994 if err != nil {
995 return "", err
996 }
997 return t.(string), nil
998}
999
1000func (r *jsReader) nextBytes() ([]byte, error) {
1001 str, err := r.nextString()
1002 if err != nil {
1003 return nil, err
1004 }
1005 return base64.StdEncoding.DecodeString(str)
1006}
1007
1008func (r *jsReader) nextBool() (bool, error) {
1009 t, err := r.expect(func(t json.Token) bool { _, ok := t.(bool); return ok }, false, "boolean")
1010 if err != nil {
1011 return false, err
1012 }
1013 return t.(bool), nil
1014}
1015
1016func (r *jsReader) nextInt() (int64, error) {
1017 n, err := r.nextNumber()
1018 if err != nil {
1019 return 0, err
1020 }
1021 return n.Int64()
1022}
1023
1024func (r *jsReader) nextUint() (uint64, error) {
1025 n, err := r.nextNumber()
1026 if err != nil {
1027 return 0, err
1028 }
1029 return strconv.ParseUint(string(n), 10, 64)
1030}
1031
1032func (r *jsReader) nextFloat() (float64, error) {
1033 n, err := r.nextNumber()
1034 if err != nil {
1035 return 0, err
1036 }
1037 return n.Float64()
1038}
1039
1040func (r *jsReader) nextNumber() (json.Number, error) {
1041 t, err := r.expect(func(t json.Token) bool { return reflect.TypeOf(t).Kind() == reflect.String }, "0", "number")
1042 if err != nil {
1043 return "", err
1044 }
1045 switch t := t.(type) {
1046 case json.Number:
1047 return t, nil
1048 case string:
1049 return json.Number(t), nil
1050 }
1051 return "", fmt.Errorf("expecting a number but got %v", t)
1052}
1053
1054func (r *jsReader) skip() error {
1055 t, err := r.poll()
1056 if err != nil {
1057 return err
1058 }
1059 if t == json.Delim('[') {
1060 if err := r.skipArray(); err != nil {
1061 return err
1062 }
1063 } else if t == json.Delim('{') {
1064 if err := r.skipObject(); err != nil {
1065 return err
1066 }
1067 }
1068 return nil
1069}
1070
1071func (r *jsReader) skipArray() error {
1072 for r.hasNext() {
1073 if err := r.skip(); err != nil {
1074 return err
1075 }
1076 }
1077 if err := r.endArray(); err != nil {
1078 return err
1079 }
1080 return nil
1081}
1082
1083func (r *jsReader) skipObject() error {
1084 for r.hasNext() {
1085 // skip object key
1086 if err := r.skip(); err != nil {
1087 return err
1088 }
1089 // and value
1090 if err := r.skip(); err != nil {
1091 return err
1092 }
1093 }
1094 if err := r.endObject(); err != nil {
1095 return err
1096 }
1097 return nil
1098}
1099
1100func (r *jsReader) expect(predicate func(json.Token) bool, ifNil interface{}, expected string) (interface{}, error) {
1101 t, err := r.poll()
1102 if err != nil {
1103 return nil, err
1104 }
1105 if t == nil && ifNil != nil {
1106 return ifNil, nil
1107 }
1108 if !predicate(t) {
1109 return t, fmt.Errorf("bad input: expecting %s ; instead got %v", expected, t)
1110 }
1111 return t, nil
1112}
1113
1114type concatReader struct {
1115 bufs []io.Reader
1116 curr int
1117}
1118
1119func (r *concatReader) Read(p []byte) (n int, err error) {
1120 for {
1121 if r.curr >= len(r.bufs) {
1122 err = io.EOF
1123 return
1124 }
1125 var c int
1126 c, err = r.bufs[r.curr].Read(p)
1127 n += c
1128 if err != io.EOF {
1129 return
1130 }
1131 r.curr++
1132 p = p[c:]
1133 }
1134}
1135
1136// AnyResolver returns a jsonpb.AnyResolver that uses the given file descriptors
1137// to resolve message names. It uses the given factory, which may be nil, to
1138// instantiate messages. The messages that it returns when resolving a type name
1139// may often be dynamic messages.
1140func AnyResolver(mf *MessageFactory, files ...*desc.FileDescriptor) jsonpb.AnyResolver {
1141 return &anyResolver{mf: mf, files: files}
1142}
1143
1144type anyResolver struct {
1145 mf *MessageFactory
1146 files []*desc.FileDescriptor
1147 ignored map[*desc.FileDescriptor]struct{}
1148 other jsonpb.AnyResolver
1149}
1150
1151func wrapResolver(r jsonpb.AnyResolver, mf *MessageFactory, f *desc.FileDescriptor) (jsonpb.AnyResolver, bool) {
1152 if r, ok := r.(*anyResolver); ok {
1153 if _, ok := r.ignored[f]; ok {
1154 // if the current resolver is ignoring this file, it's because another
1155 // (upstream) resolver is already handling it, so nothing to do
1156 return r, false
1157 }
1158 for _, file := range r.files {
1159 if file == f {
1160 // no need to wrap!
1161 return r, false
1162 }
1163 }
1164 // ignore files that will be checked by the resolver we're wrapping
1165 // (we'll just delegate and let it search those files)
1166 ignored := map[*desc.FileDescriptor]struct{}{}
1167 for i := range r.ignored {
1168 ignored[i] = struct{}{}
1169 }
1170 ignore(r.files, ignored)
1171 return &anyResolver{mf: mf, files: []*desc.FileDescriptor{f}, ignored: ignored, other: r}, true
1172 }
1173 return &anyResolver{mf: mf, files: []*desc.FileDescriptor{f}, other: r}, true
1174}
1175
1176func ignore(files []*desc.FileDescriptor, ignored map[*desc.FileDescriptor]struct{}) {
1177 for _, f := range files {
1178 if _, ok := ignored[f]; ok {
1179 continue
1180 }
1181 ignored[f] = struct{}{}
1182 ignore(f.GetDependencies(), ignored)
1183 }
1184}
1185
1186func (r *anyResolver) Resolve(typeUrl string) (proto.Message, error) {
1187 mname := typeUrl
1188 if slash := strings.LastIndex(mname, "/"); slash >= 0 {
1189 mname = mname[slash+1:]
1190 }
1191
1192 // see if the user-specified resolver is able to do the job
1193 if r.other != nil {
1194 msg, err := r.other.Resolve(typeUrl)
1195 if err == nil {
1196 return msg, nil
1197 }
1198 }
1199
1200 // try to find the message in our known set of files
1201 checked := map[*desc.FileDescriptor]struct{}{}
1202 for _, f := range r.files {
1203 md := r.findMessage(f, mname, checked)
1204 if md != nil {
1205 return r.mf.NewMessage(md), nil
1206 }
1207 }
1208 // failing that, see if the message factory knows about this type
1209 var ktr *KnownTypeRegistry
1210 if r.mf != nil {
1211 ktr = r.mf.ktr
1212 } else {
1213 ktr = (*KnownTypeRegistry)(nil)
1214 }
1215 m := ktr.CreateIfKnown(mname)
1216 if m != nil {
1217 return m, nil
1218 }
1219
1220 // no other resolver to fallback to? mimic default behavior
1221 mt := proto.MessageType(mname)
1222 if mt == nil {
1223 return nil, fmt.Errorf("unknown message type %q", mname)
1224 }
1225 return reflect.New(mt.Elem()).Interface().(proto.Message), nil
1226}
1227
1228func (r *anyResolver) findMessage(fd *desc.FileDescriptor, msgName string, checked map[*desc.FileDescriptor]struct{}) *desc.MessageDescriptor {
1229 // if this is an ignored descriptor, skip
1230 if _, ok := r.ignored[fd]; ok {
1231 return nil
1232 }
1233
1234 // bail if we've already checked this file
1235 if _, ok := checked[fd]; ok {
1236 return nil
1237 }
1238 checked[fd] = struct{}{}
1239
1240 // see if this file has the message
1241 md := fd.FindMessage(msgName)
1242 if md != nil {
1243 return md
1244 }
1245
1246 // if not, recursively search the file's imports
1247 for _, dep := range fd.GetDependencies() {
1248 md = r.findMessage(dep, msgName, checked)
1249 if md != nil {
1250 return md
1251 }
1252 }
1253 return nil
1254}
1255
1256var _ jsonpb.AnyResolver = (*anyResolver)(nil)