1
2
3
4
5 package protojson
6
7 import (
8 "encoding/base64"
9 "fmt"
10 "math"
11 "strconv"
12 "strings"
13
14 "google.golang.org/protobuf/encoding/protowire"
15 "google.golang.org/protobuf/internal/encoding/json"
16 "google.golang.org/protobuf/internal/encoding/messageset"
17 "google.golang.org/protobuf/internal/errors"
18 "google.golang.org/protobuf/internal/flags"
19 "google.golang.org/protobuf/internal/genid"
20 "google.golang.org/protobuf/internal/pragma"
21 "google.golang.org/protobuf/internal/set"
22 "google.golang.org/protobuf/proto"
23 "google.golang.org/protobuf/reflect/protoreflect"
24 "google.golang.org/protobuf/reflect/protoregistry"
25 )
26
27
28
29 func Unmarshal(b []byte, m proto.Message) error {
30 return UnmarshalOptions{}.Unmarshal(b, m)
31 }
32
33
34 type UnmarshalOptions struct {
35 pragma.NoUnkeyedLiterals
36
37
38
39 AllowPartial bool
40
41
42 DiscardUnknown bool
43
44
45
46
47 Resolver interface {
48 protoregistry.MessageTypeResolver
49 protoregistry.ExtensionTypeResolver
50 }
51
52
53
54 RecursionLimit int
55 }
56
57
58
59
60
61
62 func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
63 return o.unmarshal(b, m)
64 }
65
66
67
68
69 func (o UnmarshalOptions) unmarshal(b []byte, m proto.Message) error {
70 proto.Reset(m)
71
72 if o.Resolver == nil {
73 o.Resolver = protoregistry.GlobalTypes
74 }
75 if o.RecursionLimit == 0 {
76 o.RecursionLimit = protowire.DefaultRecursionLimit
77 }
78
79 dec := decoder{json.NewDecoder(b), o}
80 if err := dec.unmarshalMessage(m.ProtoReflect(), false); err != nil {
81 return err
82 }
83
84
85 tok, err := dec.Read()
86 if err != nil {
87 return err
88 }
89 if tok.Kind() != json.EOF {
90 return dec.unexpectedTokenError(tok)
91 }
92
93 if o.AllowPartial {
94 return nil
95 }
96 return proto.CheckInitialized(m)
97 }
98
99 type decoder struct {
100 *json.Decoder
101 opts UnmarshalOptions
102 }
103
104
105 func (d decoder) newError(pos int, f string, x ...interface{}) error {
106 line, column := d.Position(pos)
107 head := fmt.Sprintf("(line %d:%d): ", line, column)
108 return errors.New(head+f, x...)
109 }
110
111
112 func (d decoder) unexpectedTokenError(tok json.Token) error {
113 return d.syntaxError(tok.Pos(), "unexpected token %s", tok.RawString())
114 }
115
116
117 func (d decoder) syntaxError(pos int, f string, x ...interface{}) error {
118 line, column := d.Position(pos)
119 head := fmt.Sprintf("syntax error (line %d:%d): ", line, column)
120 return errors.New(head+f, x...)
121 }
122
123
124 func (d decoder) unmarshalMessage(m protoreflect.Message, skipTypeURL bool) error {
125 d.opts.RecursionLimit--
126 if d.opts.RecursionLimit < 0 {
127 return errors.New("exceeded max recursion depth")
128 }
129 if unmarshal := wellKnownTypeUnmarshaler(m.Descriptor().FullName()); unmarshal != nil {
130 return unmarshal(d, m)
131 }
132
133 tok, err := d.Read()
134 if err != nil {
135 return err
136 }
137 if tok.Kind() != json.ObjectOpen {
138 return d.unexpectedTokenError(tok)
139 }
140
141 messageDesc := m.Descriptor()
142 if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) {
143 return errors.New("no support for proto1 MessageSets")
144 }
145
146 var seenNums set.Ints
147 var seenOneofs set.Ints
148 fieldDescs := messageDesc.Fields()
149 for {
150
151 tok, err := d.Read()
152 if err != nil {
153 return err
154 }
155 switch tok.Kind() {
156 default:
157 return d.unexpectedTokenError(tok)
158 case json.ObjectClose:
159 return nil
160 case json.Name:
161
162 }
163
164 name := tok.Name()
165
166
167
168 if skipTypeURL && name == "@type" {
169 d.Read()
170 continue
171 }
172
173
174 var fd protoreflect.FieldDescriptor
175 if strings.HasPrefix(name, "[") && strings.HasSuffix(name, "]") {
176
177 extName := protoreflect.FullName(name[1 : len(name)-1])
178 extType, err := d.opts.Resolver.FindExtensionByName(extName)
179 if err != nil && err != protoregistry.NotFound {
180 return d.newError(tok.Pos(), "unable to resolve %s: %v", tok.RawString(), err)
181 }
182 if extType != nil {
183 fd = extType.TypeDescriptor()
184 if !messageDesc.ExtensionRanges().Has(fd.Number()) || fd.ContainingMessage().FullName() != messageDesc.FullName() {
185 return d.newError(tok.Pos(), "message %v cannot be extended by %v", messageDesc.FullName(), fd.FullName())
186 }
187 }
188 } else {
189
190 fd = fieldDescs.ByJSONName(name)
191 if fd == nil {
192 fd = fieldDescs.ByTextName(name)
193 }
194 }
195 if flags.ProtoLegacy {
196 if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() {
197 fd = nil
198 }
199 }
200
201 if fd == nil {
202
203 if d.opts.DiscardUnknown {
204 if err := d.skipJSONValue(); err != nil {
205 return err
206 }
207 continue
208 }
209 return d.newError(tok.Pos(), "unknown field %v", tok.RawString())
210 }
211
212
213 num := uint64(fd.Number())
214 if seenNums.Has(num) {
215 return d.newError(tok.Pos(), "duplicate field %v", tok.RawString())
216 }
217 seenNums.Set(num)
218
219
220
221 if tok, _ := d.Peek(); tok.Kind() == json.Null && !isKnownValue(fd) && !isNullValue(fd) {
222 d.Read()
223 continue
224 }
225
226 switch {
227 case fd.IsList():
228 list := m.Mutable(fd).List()
229 if err := d.unmarshalList(list, fd); err != nil {
230 return err
231 }
232 case fd.IsMap():
233 mmap := m.Mutable(fd).Map()
234 if err := d.unmarshalMap(mmap, fd); err != nil {
235 return err
236 }
237 default:
238
239 if od := fd.ContainingOneof(); od != nil {
240 idx := uint64(od.Index())
241 if seenOneofs.Has(idx) {
242 return d.newError(tok.Pos(), "error parsing %s, oneof %v is already set", tok.RawString(), od.FullName())
243 }
244 seenOneofs.Set(idx)
245 }
246
247
248 if err := d.unmarshalSingular(m, fd); err != nil {
249 return err
250 }
251 }
252 }
253 }
254
255 func isKnownValue(fd protoreflect.FieldDescriptor) bool {
256 md := fd.Message()
257 return md != nil && md.FullName() == genid.Value_message_fullname
258 }
259
260 func isNullValue(fd protoreflect.FieldDescriptor) bool {
261 ed := fd.Enum()
262 return ed != nil && ed.FullName() == genid.NullValue_enum_fullname
263 }
264
265
266
267 func (d decoder) unmarshalSingular(m protoreflect.Message, fd protoreflect.FieldDescriptor) error {
268 var val protoreflect.Value
269 var err error
270 switch fd.Kind() {
271 case protoreflect.MessageKind, protoreflect.GroupKind:
272 val = m.NewField(fd)
273 err = d.unmarshalMessage(val.Message(), false)
274 default:
275 val, err = d.unmarshalScalar(fd)
276 }
277
278 if err != nil {
279 return err
280 }
281 if val.IsValid() {
282 m.Set(fd, val)
283 }
284 return nil
285 }
286
287
288
289 func (d decoder) unmarshalScalar(fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
290 const b32 int = 32
291 const b64 int = 64
292
293 tok, err := d.Read()
294 if err != nil {
295 return protoreflect.Value{}, err
296 }
297
298 kind := fd.Kind()
299 switch kind {
300 case protoreflect.BoolKind:
301 if tok.Kind() == json.Bool {
302 return protoreflect.ValueOfBool(tok.Bool()), nil
303 }
304
305 case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
306 if v, ok := unmarshalInt(tok, b32); ok {
307 return v, nil
308 }
309
310 case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
311 if v, ok := unmarshalInt(tok, b64); ok {
312 return v, nil
313 }
314
315 case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
316 if v, ok := unmarshalUint(tok, b32); ok {
317 return v, nil
318 }
319
320 case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
321 if v, ok := unmarshalUint(tok, b64); ok {
322 return v, nil
323 }
324
325 case protoreflect.FloatKind:
326 if v, ok := unmarshalFloat(tok, b32); ok {
327 return v, nil
328 }
329
330 case protoreflect.DoubleKind:
331 if v, ok := unmarshalFloat(tok, b64); ok {
332 return v, nil
333 }
334
335 case protoreflect.StringKind:
336 if tok.Kind() == json.String {
337 return protoreflect.ValueOfString(tok.ParsedString()), nil
338 }
339
340 case protoreflect.BytesKind:
341 if v, ok := unmarshalBytes(tok); ok {
342 return v, nil
343 }
344
345 case protoreflect.EnumKind:
346 if v, ok := unmarshalEnum(tok, fd, d.opts.DiscardUnknown); ok {
347 return v, nil
348 }
349
350 default:
351 panic(fmt.Sprintf("unmarshalScalar: invalid scalar kind %v", kind))
352 }
353
354 return protoreflect.Value{}, d.newError(tok.Pos(), "invalid value for %v type: %v", kind, tok.RawString())
355 }
356
357 func unmarshalInt(tok json.Token, bitSize int) (protoreflect.Value, bool) {
358 switch tok.Kind() {
359 case json.Number:
360 return getInt(tok, bitSize)
361
362 case json.String:
363
364 s := strings.TrimSpace(tok.ParsedString())
365 if len(s) != len(tok.ParsedString()) {
366 return protoreflect.Value{}, false
367 }
368 dec := json.NewDecoder([]byte(s))
369 tok, err := dec.Read()
370 if err != nil {
371 return protoreflect.Value{}, false
372 }
373 return getInt(tok, bitSize)
374 }
375 return protoreflect.Value{}, false
376 }
377
378 func getInt(tok json.Token, bitSize int) (protoreflect.Value, bool) {
379 n, ok := tok.Int(bitSize)
380 if !ok {
381 return protoreflect.Value{}, false
382 }
383 if bitSize == 32 {
384 return protoreflect.ValueOfInt32(int32(n)), true
385 }
386 return protoreflect.ValueOfInt64(n), true
387 }
388
389 func unmarshalUint(tok json.Token, bitSize int) (protoreflect.Value, bool) {
390 switch tok.Kind() {
391 case json.Number:
392 return getUint(tok, bitSize)
393
394 case json.String:
395
396 s := strings.TrimSpace(tok.ParsedString())
397 if len(s) != len(tok.ParsedString()) {
398 return protoreflect.Value{}, false
399 }
400 dec := json.NewDecoder([]byte(s))
401 tok, err := dec.Read()
402 if err != nil {
403 return protoreflect.Value{}, false
404 }
405 return getUint(tok, bitSize)
406 }
407 return protoreflect.Value{}, false
408 }
409
410 func getUint(tok json.Token, bitSize int) (protoreflect.Value, bool) {
411 n, ok := tok.Uint(bitSize)
412 if !ok {
413 return protoreflect.Value{}, false
414 }
415 if bitSize == 32 {
416 return protoreflect.ValueOfUint32(uint32(n)), true
417 }
418 return protoreflect.ValueOfUint64(n), true
419 }
420
421 func unmarshalFloat(tok json.Token, bitSize int) (protoreflect.Value, bool) {
422 switch tok.Kind() {
423 case json.Number:
424 return getFloat(tok, bitSize)
425
426 case json.String:
427 s := tok.ParsedString()
428 switch s {
429 case "NaN":
430 if bitSize == 32 {
431 return protoreflect.ValueOfFloat32(float32(math.NaN())), true
432 }
433 return protoreflect.ValueOfFloat64(math.NaN()), true
434 case "Infinity":
435 if bitSize == 32 {
436 return protoreflect.ValueOfFloat32(float32(math.Inf(+1))), true
437 }
438 return protoreflect.ValueOfFloat64(math.Inf(+1)), true
439 case "-Infinity":
440 if bitSize == 32 {
441 return protoreflect.ValueOfFloat32(float32(math.Inf(-1))), true
442 }
443 return protoreflect.ValueOfFloat64(math.Inf(-1)), true
444 }
445
446
447 if len(s) != len(strings.TrimSpace(s)) {
448 return protoreflect.Value{}, false
449 }
450 dec := json.NewDecoder([]byte(s))
451 tok, err := dec.Read()
452 if err != nil {
453 return protoreflect.Value{}, false
454 }
455 return getFloat(tok, bitSize)
456 }
457 return protoreflect.Value{}, false
458 }
459
460 func getFloat(tok json.Token, bitSize int) (protoreflect.Value, bool) {
461 n, ok := tok.Float(bitSize)
462 if !ok {
463 return protoreflect.Value{}, false
464 }
465 if bitSize == 32 {
466 return protoreflect.ValueOfFloat32(float32(n)), true
467 }
468 return protoreflect.ValueOfFloat64(n), true
469 }
470
471 func unmarshalBytes(tok json.Token) (protoreflect.Value, bool) {
472 if tok.Kind() != json.String {
473 return protoreflect.Value{}, false
474 }
475
476 s := tok.ParsedString()
477 enc := base64.StdEncoding
478 if strings.ContainsAny(s, "-_") {
479 enc = base64.URLEncoding
480 }
481 if len(s)%4 != 0 {
482 enc = enc.WithPadding(base64.NoPadding)
483 }
484 b, err := enc.DecodeString(s)
485 if err != nil {
486 return protoreflect.Value{}, false
487 }
488 return protoreflect.ValueOfBytes(b), true
489 }
490
491 func unmarshalEnum(tok json.Token, fd protoreflect.FieldDescriptor, discardUnknown bool) (protoreflect.Value, bool) {
492 switch tok.Kind() {
493 case json.String:
494
495 s := tok.ParsedString()
496 if enumVal := fd.Enum().Values().ByName(protoreflect.Name(s)); enumVal != nil {
497 return protoreflect.ValueOfEnum(enumVal.Number()), true
498 }
499 if discardUnknown {
500 return protoreflect.Value{}, true
501 }
502
503 case json.Number:
504 if n, ok := tok.Int(32); ok {
505 return protoreflect.ValueOfEnum(protoreflect.EnumNumber(n)), true
506 }
507
508 case json.Null:
509
510 if isNullValue(fd) {
511 return protoreflect.ValueOfEnum(0), true
512 }
513 }
514
515 return protoreflect.Value{}, false
516 }
517
518 func (d decoder) unmarshalList(list protoreflect.List, fd protoreflect.FieldDescriptor) error {
519 tok, err := d.Read()
520 if err != nil {
521 return err
522 }
523 if tok.Kind() != json.ArrayOpen {
524 return d.unexpectedTokenError(tok)
525 }
526
527 switch fd.Kind() {
528 case protoreflect.MessageKind, protoreflect.GroupKind:
529 for {
530 tok, err := d.Peek()
531 if err != nil {
532 return err
533 }
534
535 if tok.Kind() == json.ArrayClose {
536 d.Read()
537 return nil
538 }
539
540 val := list.NewElement()
541 if err := d.unmarshalMessage(val.Message(), false); err != nil {
542 return err
543 }
544 list.Append(val)
545 }
546 default:
547 for {
548 tok, err := d.Peek()
549 if err != nil {
550 return err
551 }
552
553 if tok.Kind() == json.ArrayClose {
554 d.Read()
555 return nil
556 }
557
558 val, err := d.unmarshalScalar(fd)
559 if err != nil {
560 return err
561 }
562 if val.IsValid() {
563 list.Append(val)
564 }
565 }
566 }
567
568 return nil
569 }
570
571 func (d decoder) unmarshalMap(mmap protoreflect.Map, fd protoreflect.FieldDescriptor) error {
572 tok, err := d.Read()
573 if err != nil {
574 return err
575 }
576 if tok.Kind() != json.ObjectOpen {
577 return d.unexpectedTokenError(tok)
578 }
579
580
581
582
583 var unmarshalMapValue func() (protoreflect.Value, error)
584 switch fd.MapValue().Kind() {
585 case protoreflect.MessageKind, protoreflect.GroupKind:
586 unmarshalMapValue = func() (protoreflect.Value, error) {
587 val := mmap.NewValue()
588 if err := d.unmarshalMessage(val.Message(), false); err != nil {
589 return protoreflect.Value{}, err
590 }
591 return val, nil
592 }
593 default:
594 unmarshalMapValue = func() (protoreflect.Value, error) {
595 return d.unmarshalScalar(fd.MapValue())
596 }
597 }
598
599 Loop:
600 for {
601
602 tok, err := d.Read()
603 if err != nil {
604 return err
605 }
606 switch tok.Kind() {
607 default:
608 return d.unexpectedTokenError(tok)
609 case json.ObjectClose:
610 break Loop
611 case json.Name:
612
613 }
614
615
616 pkey, err := d.unmarshalMapKey(tok, fd.MapKey())
617 if err != nil {
618 return err
619 }
620
621
622 if mmap.Has(pkey) {
623 return d.newError(tok.Pos(), "duplicate map key %v", tok.RawString())
624 }
625
626
627 pval, err := unmarshalMapValue()
628 if err != nil {
629 return err
630 }
631 if pval.IsValid() {
632 mmap.Set(pkey, pval)
633 }
634 }
635
636 return nil
637 }
638
639
640
641 func (d decoder) unmarshalMapKey(tok json.Token, fd protoreflect.FieldDescriptor) (protoreflect.MapKey, error) {
642 const b32 = 32
643 const b64 = 64
644 const base10 = 10
645
646 name := tok.Name()
647 kind := fd.Kind()
648 switch kind {
649 case protoreflect.StringKind:
650 return protoreflect.ValueOfString(name).MapKey(), nil
651
652 case protoreflect.BoolKind:
653 switch name {
654 case "true":
655 return protoreflect.ValueOfBool(true).MapKey(), nil
656 case "false":
657 return protoreflect.ValueOfBool(false).MapKey(), nil
658 }
659
660 case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
661 if n, err := strconv.ParseInt(name, base10, b32); err == nil {
662 return protoreflect.ValueOfInt32(int32(n)).MapKey(), nil
663 }
664
665 case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
666 if n, err := strconv.ParseInt(name, base10, b64); err == nil {
667 return protoreflect.ValueOfInt64(int64(n)).MapKey(), nil
668 }
669
670 case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
671 if n, err := strconv.ParseUint(name, base10, b32); err == nil {
672 return protoreflect.ValueOfUint32(uint32(n)).MapKey(), nil
673 }
674
675 case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
676 if n, err := strconv.ParseUint(name, base10, b64); err == nil {
677 return protoreflect.ValueOfUint64(uint64(n)).MapKey(), nil
678 }
679
680 default:
681 panic(fmt.Sprintf("invalid kind for map key: %v", kind))
682 }
683
684 return protoreflect.MapKey{}, d.newError(tok.Pos(), "invalid value for %v key: %s", kind, tok.RawString())
685 }
686
View as plain text