blob: 3d4a0680f432bf4dfba55d6924c54e2c325674fe [file] [log] [blame]
Herbie Ongc96a79d2019-03-08 10:49:17 -08001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package jsonpb
6
7import (
8 "encoding/base64"
9 "fmt"
10 "math"
11 "strconv"
12 "strings"
13
14 "github.com/golang/protobuf/v2/internal/encoding/json"
15 "github.com/golang/protobuf/v2/internal/errors"
Herbie Onge52379a2019-03-15 18:00:19 -070016 "github.com/golang/protobuf/v2/internal/pragma"
Herbie Ongc96a79d2019-03-08 10:49:17 -080017 "github.com/golang/protobuf/v2/internal/set"
18 "github.com/golang/protobuf/v2/proto"
19 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
Herbie Onge52379a2019-03-15 18:00:19 -070020 "github.com/golang/protobuf/v2/reflect/protoregistry"
Herbie Ongc96a79d2019-03-08 10:49:17 -080021)
22
23// Unmarshal reads the given []byte into the given proto.Message.
24func Unmarshal(m proto.Message, b []byte) error {
25 return UnmarshalOptions{}.Unmarshal(m, b)
26}
27
28// UnmarshalOptions is a configurable JSON format parser.
Herbie Onge52379a2019-03-15 18:00:19 -070029type UnmarshalOptions struct {
30 pragma.NoUnkeyedLiterals
31
Herbie Ong329be5b2019-03-27 14:47:59 -070032 // AllowPartial accepts input for messages that will result in missing
33 // required fields. If AllowPartial is false (the default), Unmarshal will
34 // return error if there are any missing required fields.
35 AllowPartial bool
36
Herbie Onge52379a2019-03-15 18:00:19 -070037 // Resolver is the registry used for type lookups when unmarshaling extensions
38 // and processing Any. If Resolver is not set, unmarshaling will default to
39 // using protoregistry.GlobalTypes.
40 Resolver *protoregistry.Types
Herbie Ong822de2d2019-03-27 13:16:23 -070041
42 decoder *json.Decoder
Herbie Onge52379a2019-03-15 18:00:19 -070043}
Herbie Ongc96a79d2019-03-08 10:49:17 -080044
45// Unmarshal reads the given []byte and populates the given proto.Message using
46// options in UnmarshalOptions object. It will clear the message first before
47// setting the fields. If it returns an error, the given message may be
48// partially set.
49func (o UnmarshalOptions) Unmarshal(m proto.Message, b []byte) error {
50 mr := m.ProtoReflect()
51 // TODO: Determine if we would like to have an option for merging or only
52 // have merging behavior. We should at least be consistent with textproto
53 // marshaling.
54 resetMessage(mr)
55
Herbie Ong822de2d2019-03-27 13:16:23 -070056 if o.Resolver == nil {
57 o.Resolver = protoregistry.GlobalTypes
Herbie Onge52379a2019-03-15 18:00:19 -070058 }
Herbie Ong822de2d2019-03-27 13:16:23 -070059 o.decoder = json.NewDecoder(b)
Herbie Onge52379a2019-03-15 18:00:19 -070060
Herbie Ongc96a79d2019-03-08 10:49:17 -080061 var nerr errors.NonFatal
Herbie Ong8ac9dd22019-03-27 12:20:50 -070062 if err := o.unmarshalMessage(mr, false); !nerr.Merge(err) {
Herbie Ongc96a79d2019-03-08 10:49:17 -080063 return err
64 }
65
66 // Check for EOF.
Herbie Ong822de2d2019-03-27 13:16:23 -070067 val, err := o.decoder.Read()
Herbie Ongc96a79d2019-03-08 10:49:17 -080068 if err != nil {
69 return err
70 }
71 if val.Type() != json.EOF {
72 return unexpectedJSONError{val}
73 }
74 return nerr.E
75}
76
77// resetMessage clears all fields of given protoreflect.Message.
78func resetMessage(m pref.Message) {
79 knownFields := m.KnownFields()
80 knownFields.Range(func(num pref.FieldNumber, _ pref.Value) bool {
81 knownFields.Clear(num)
82 return true
83 })
84 unknownFields := m.UnknownFields()
85 unknownFields.Range(func(num pref.FieldNumber, _ pref.RawFields) bool {
86 unknownFields.Set(num, nil)
87 return true
88 })
89 extTypes := knownFields.ExtensionTypes()
90 extTypes.Range(func(xt pref.ExtensionType) bool {
91 extTypes.Remove(xt)
92 return true
93 })
94}
95
96// unexpectedJSONError is an error that contains the unexpected json.Value. This
Herbie Ong822de2d2019-03-27 13:16:23 -070097// is returned by methods to provide callers the read json.Value that it did not
98// expect.
Herbie Ongc96a79d2019-03-08 10:49:17 -080099// TODO: Consider moving this to internal/encoding/json for consistency with
100// errors that package returns.
101type unexpectedJSONError struct {
102 value json.Value
103}
104
105func (e unexpectedJSONError) Error() string {
106 return newError("unexpected value %s", e.value).Error()
107}
108
109// newError returns an error object. If one of the values passed in is of
110// json.Value type, it produces an error with position info.
111func newError(f string, x ...interface{}) error {
112 var hasValue bool
113 var line, column int
114 for i := 0; i < len(x); i++ {
115 if val, ok := x[i].(json.Value); ok {
116 line, column = val.Position()
117 hasValue = true
118 break
119 }
120 }
121 e := errors.New(f, x...)
122 if hasValue {
123 return errors.New("(line %d:%d): %v", line, column, e)
124 }
125 return e
126}
127
Herbie Ongc96a79d2019-03-08 10:49:17 -0800128// unmarshalMessage unmarshals a message into the given protoreflect.Message.
Herbie Ong8ac9dd22019-03-27 12:20:50 -0700129func (o UnmarshalOptions) unmarshalMessage(m pref.Message, skipTypeURL bool) error {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800130 var nerr errors.NonFatal
Herbie Ongc96a79d2019-03-08 10:49:17 -0800131
Herbie Onge63c4c42019-03-22 22:20:22 -0700132 if isCustomType(m.Type().FullName()) {
Herbie Ong822de2d2019-03-27 13:16:23 -0700133 return o.unmarshalCustomType(m)
Herbie Onge63c4c42019-03-22 22:20:22 -0700134 }
Herbie Ongc96a79d2019-03-08 10:49:17 -0800135
Herbie Ong822de2d2019-03-27 13:16:23 -0700136 jval, err := o.decoder.Read()
Herbie Ongc96a79d2019-03-08 10:49:17 -0800137 if !nerr.Merge(err) {
138 return err
139 }
140 if jval.Type() != json.StartObject {
141 return unexpectedJSONError{jval}
142 }
143
Herbie Ong8ac9dd22019-03-27 12:20:50 -0700144 if err := o.unmarshalFields(m, skipTypeURL); !nerr.Merge(err) {
Herbie Onge63c4c42019-03-22 22:20:22 -0700145 return err
146 }
147
148 return nerr.E
149}
150
151// unmarshalFields unmarshals the fields into the given protoreflect.Message.
Herbie Ong8ac9dd22019-03-27 12:20:50 -0700152func (o UnmarshalOptions) unmarshalFields(m pref.Message, skipTypeURL bool) error {
Herbie Onge63c4c42019-03-22 22:20:22 -0700153 var nerr errors.NonFatal
154 var reqNums set.Ints
155 var seenNums set.Ints
Herbie Ong8a1d4602019-04-02 20:19:36 -0700156 var seenOneofs set.Ints
Herbie Onge63c4c42019-03-22 22:20:22 -0700157
158 msgType := m.Type()
159 knownFields := m.KnownFields()
160 fieldDescs := msgType.Fields()
161 xtTypes := knownFields.ExtensionTypes()
162
Herbie Ongc96a79d2019-03-08 10:49:17 -0800163Loop:
164 for {
165 // Read field name.
Herbie Ong822de2d2019-03-27 13:16:23 -0700166 jval, err := o.decoder.Read()
Herbie Ongc96a79d2019-03-08 10:49:17 -0800167 if !nerr.Merge(err) {
168 return err
169 }
170 switch jval.Type() {
171 default:
172 return unexpectedJSONError{jval}
173 case json.EndObject:
174 break Loop
175 case json.Name:
176 // Continue below.
177 }
178
179 name, err := jval.Name()
180 if !nerr.Merge(err) {
181 return err
182 }
Herbie Ong8ac9dd22019-03-27 12:20:50 -0700183 // Unmarshaling a non-custom embedded message in Any will contain the
184 // JSON field "@type" which should be skipped because it is not a field
185 // of the embedded message, but simply an artifact of the Any format.
186 if skipTypeURL && name == "@type" {
187 o.decoder.Read()
188 continue
189 }
Herbie Ongc96a79d2019-03-08 10:49:17 -0800190
Herbie Onge52379a2019-03-15 18:00:19 -0700191 // Get the FieldDescriptor.
192 var fd pref.FieldDescriptor
193 if strings.HasPrefix(name, "[") && strings.HasSuffix(name, "]") {
194 // Only extension names are in [name] format.
195 xtName := pref.FullName(name[1 : len(name)-1])
196 xt := xtTypes.ByName(xtName)
197 if xt == nil {
Herbie Ong822de2d2019-03-27 13:16:23 -0700198 xt, err = o.findExtension(xtName)
Herbie Onge52379a2019-03-15 18:00:19 -0700199 if err != nil && err != protoregistry.NotFound {
200 return errors.New("unable to resolve [%v]: %v", xtName, err)
201 }
202 if xt != nil {
203 xtTypes.Register(xt)
204 }
205 }
206 fd = xt
207 } else {
208 // The name can either be the JSON name or the proto field name.
209 fd = fieldDescs.ByJSONName(name)
210 if fd == nil {
211 fd = fieldDescs.ByName(pref.Name(name))
212 }
Herbie Ongc96a79d2019-03-08 10:49:17 -0800213 }
214
215 if fd == nil {
216 // Field is unknown.
217 // TODO: Provide option to ignore unknown message fields.
218 return newError("%v contains unknown field %s", msgType.FullName(), jval)
219 }
220
221 // Do not allow duplicate fields.
222 num := uint64(fd.Number())
223 if seenNums.Has(num) {
224 return newError("%v contains repeated field %s", msgType.FullName(), jval)
225 }
226 seenNums.Set(num)
227
Herbie Onge63c4c42019-03-22 22:20:22 -0700228 // No need to set values for JSON null unless the field type is
Herbie Ong300b9fe2019-03-29 15:42:20 -0700229 // google.protobuf.Value or google.protobuf.NullValue.
230 if o.decoder.Peek() == json.Null && !isKnownValue(fd) && !isNullValue(fd) {
Herbie Ong822de2d2019-03-27 13:16:23 -0700231 o.decoder.Read()
Herbie Ongc96a79d2019-03-08 10:49:17 -0800232 continue
233 }
234
235 if cardinality := fd.Cardinality(); cardinality == pref.Repeated {
236 // Map or list fields have cardinality of repeated.
Herbie Ong822de2d2019-03-27 13:16:23 -0700237 if err := o.unmarshalRepeated(knownFields, fd); !nerr.Merge(err) {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800238 return errors.New("%v|%q: %v", fd.FullName(), name, err)
239 }
240 } else {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700241 // If field is a oneof, check if it has already been set.
242 if od := fd.OneofType(); od != nil {
243 idx := uint64(od.Index())
244 if seenOneofs.Has(idx) {
245 return errors.New("%v: oneof is already set", od.FullName())
246 }
247 seenOneofs.Set(idx)
248 }
249
Herbie Ongc96a79d2019-03-08 10:49:17 -0800250 // Required or optional fields.
Herbie Ong822de2d2019-03-27 13:16:23 -0700251 if err := o.unmarshalSingular(knownFields, fd); !nerr.Merge(err) {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800252 return errors.New("%v|%q: %v", fd.FullName(), name, err)
253 }
Herbie Ong329be5b2019-03-27 14:47:59 -0700254 if !o.AllowPartial && cardinality == pref.Required {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800255 reqNums.Set(num)
256 }
257 }
258 }
259
Herbie Ong329be5b2019-03-27 14:47:59 -0700260 if !o.AllowPartial {
261 // Check for any missing required fields.
262 allReqNums := msgType.RequiredNumbers()
263 if reqNums.Len() != allReqNums.Len() {
264 for i := 0; i < allReqNums.Len(); i++ {
265 if num := allReqNums.Get(i); !reqNums.Has(uint64(num)) {
266 nerr.AppendRequiredNotSet(string(fieldDescs.ByNumber(num).FullName()))
267 }
Herbie Ongc96a79d2019-03-08 10:49:17 -0800268 }
269 }
270 }
271
272 return nerr.E
273}
274
Herbie Onge52379a2019-03-15 18:00:19 -0700275// findExtension returns protoreflect.ExtensionType from the resolver if found.
Herbie Ong822de2d2019-03-27 13:16:23 -0700276func (o UnmarshalOptions) findExtension(xtName pref.FullName) (pref.ExtensionType, error) {
277 xt, err := o.Resolver.FindExtensionByName(xtName)
Herbie Onge52379a2019-03-15 18:00:19 -0700278 if err == nil {
279 return xt, nil
280 }
281
282 // Check if this is a MessageSet extension field.
Herbie Ong822de2d2019-03-27 13:16:23 -0700283 xt, err = o.Resolver.FindExtensionByName(xtName + ".message_set_extension")
Herbie Onge52379a2019-03-15 18:00:19 -0700284 if err == nil && isMessageSetExtension(xt) {
285 return xt, nil
286 }
287 return nil, protoregistry.NotFound
288}
289
Herbie Ong300b9fe2019-03-29 15:42:20 -0700290func isKnownValue(fd pref.FieldDescriptor) bool {
291 md := fd.MessageType()
292 return md != nil && md.FullName() == "google.protobuf.Value"
293}
294
295func isNullValue(fd pref.FieldDescriptor) bool {
296 ed := fd.EnumType()
297 return ed != nil && ed.FullName() == "google.protobuf.NullValue"
298}
299
Herbie Ongc96a79d2019-03-08 10:49:17 -0800300// unmarshalSingular unmarshals to the non-repeated field specified by the given
301// FieldDescriptor.
Herbie Ong822de2d2019-03-27 13:16:23 -0700302func (o UnmarshalOptions) unmarshalSingular(knownFields pref.KnownFields, fd pref.FieldDescriptor) error {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800303 var val pref.Value
304 var err error
305 num := fd.Number()
306
307 switch fd.Kind() {
308 case pref.MessageKind, pref.GroupKind:
309 m := knownFields.NewMessage(num)
Herbie Ong8ac9dd22019-03-27 12:20:50 -0700310 err = o.unmarshalMessage(m, false)
Herbie Ongc96a79d2019-03-08 10:49:17 -0800311 val = pref.ValueOf(m)
312 default:
Herbie Ong822de2d2019-03-27 13:16:23 -0700313 val, err = o.unmarshalScalar(fd)
Herbie Ongc96a79d2019-03-08 10:49:17 -0800314 }
315
316 var nerr errors.NonFatal
317 if !nerr.Merge(err) {
318 return err
319 }
320 knownFields.Set(num, val)
321 return nerr.E
322}
323
324// unmarshalScalar unmarshals to a scalar/enum protoreflect.Value specified by
325// the given FieldDescriptor.
Herbie Ong822de2d2019-03-27 13:16:23 -0700326func (o UnmarshalOptions) unmarshalScalar(fd pref.FieldDescriptor) (pref.Value, error) {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800327 const b32 int = 32
328 const b64 int = 64
329
330 var nerr errors.NonFatal
Herbie Ong822de2d2019-03-27 13:16:23 -0700331 jval, err := o.decoder.Read()
Herbie Ongc96a79d2019-03-08 10:49:17 -0800332 if !nerr.Merge(err) {
333 return pref.Value{}, err
334 }
335
336 kind := fd.Kind()
337 switch kind {
338 case pref.BoolKind:
339 return unmarshalBool(jval)
340
341 case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
342 return unmarshalInt(jval, b32)
343
344 case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
345 return unmarshalInt(jval, b64)
346
347 case pref.Uint32Kind, pref.Fixed32Kind:
348 return unmarshalUint(jval, b32)
349
350 case pref.Uint64Kind, pref.Fixed64Kind:
351 return unmarshalUint(jval, b64)
352
353 case pref.FloatKind:
354 return unmarshalFloat(jval, b32)
355
356 case pref.DoubleKind:
357 return unmarshalFloat(jval, b64)
358
359 case pref.StringKind:
360 pval, err := unmarshalString(jval)
361 if !nerr.Merge(err) {
362 return pval, err
363 }
364 return pval, nerr.E
365
366 case pref.BytesKind:
367 return unmarshalBytes(jval)
368
369 case pref.EnumKind:
370 return unmarshalEnum(jval, fd)
371 }
372
373 panic(fmt.Sprintf("invalid scalar kind %v", kind))
374}
375
376func unmarshalBool(jval json.Value) (pref.Value, error) {
377 if jval.Type() != json.Bool {
378 return pref.Value{}, unexpectedJSONError{jval}
379 }
380 b, err := jval.Bool()
381 return pref.ValueOf(b), err
382}
383
384func unmarshalInt(jval json.Value, bitSize int) (pref.Value, error) {
385 switch jval.Type() {
386 case json.Number:
387 return getInt(jval, bitSize)
388
389 case json.String:
Herbie Onge52379a2019-03-15 18:00:19 -0700390 // Decode number from string.
391 dec := json.NewDecoder([]byte(jval.String()))
Herbie Ongc96a79d2019-03-08 10:49:17 -0800392 var nerr errors.NonFatal
393 jval, err := dec.Read()
394 if !nerr.Merge(err) {
395 return pref.Value{}, err
396 }
397 return getInt(jval, bitSize)
398 }
399 return pref.Value{}, unexpectedJSONError{jval}
400}
401
402func getInt(jval json.Value, bitSize int) (pref.Value, error) {
403 n, err := jval.Int(bitSize)
404 if err != nil {
405 return pref.Value{}, err
406 }
407 if bitSize == 32 {
408 return pref.ValueOf(int32(n)), nil
409 }
410 return pref.ValueOf(n), nil
411}
412
413func unmarshalUint(jval json.Value, bitSize int) (pref.Value, error) {
414 switch jval.Type() {
415 case json.Number:
416 return getUint(jval, bitSize)
417
418 case json.String:
Herbie Onge52379a2019-03-15 18:00:19 -0700419 // Decode number from string.
420 dec := json.NewDecoder([]byte(jval.String()))
Herbie Ongc96a79d2019-03-08 10:49:17 -0800421 var nerr errors.NonFatal
422 jval, err := dec.Read()
423 if !nerr.Merge(err) {
424 return pref.Value{}, err
425 }
426 return getUint(jval, bitSize)
427 }
428 return pref.Value{}, unexpectedJSONError{jval}
429}
430
431func getUint(jval json.Value, bitSize int) (pref.Value, error) {
432 n, err := jval.Uint(bitSize)
433 if err != nil {
434 return pref.Value{}, err
435 }
436 if bitSize == 32 {
437 return pref.ValueOf(uint32(n)), nil
438 }
439 return pref.ValueOf(n), nil
440}
441
442func unmarshalFloat(jval json.Value, bitSize int) (pref.Value, error) {
443 switch jval.Type() {
444 case json.Number:
445 return getFloat(jval, bitSize)
446
447 case json.String:
448 s := jval.String()
449 switch s {
450 case "NaN":
451 if bitSize == 32 {
452 return pref.ValueOf(float32(math.NaN())), nil
453 }
454 return pref.ValueOf(math.NaN()), nil
455 case "Infinity":
456 if bitSize == 32 {
457 return pref.ValueOf(float32(math.Inf(+1))), nil
458 }
459 return pref.ValueOf(math.Inf(+1)), nil
460 case "-Infinity":
461 if bitSize == 32 {
462 return pref.ValueOf(float32(math.Inf(-1))), nil
463 }
464 return pref.ValueOf(math.Inf(-1)), nil
465 }
Herbie Onge52379a2019-03-15 18:00:19 -0700466 // Decode number from string.
467 dec := json.NewDecoder([]byte(s))
Herbie Ongc96a79d2019-03-08 10:49:17 -0800468 var nerr errors.NonFatal
469 jval, err := dec.Read()
470 if !nerr.Merge(err) {
471 return pref.Value{}, err
472 }
473 return getFloat(jval, bitSize)
474 }
475 return pref.Value{}, unexpectedJSONError{jval}
476}
477
478func getFloat(jval json.Value, bitSize int) (pref.Value, error) {
479 n, err := jval.Float(bitSize)
480 if err != nil {
481 return pref.Value{}, err
482 }
483 if bitSize == 32 {
484 return pref.ValueOf(float32(n)), nil
485 }
486 return pref.ValueOf(n), nil
487}
488
489func unmarshalString(jval json.Value) (pref.Value, error) {
490 if jval.Type() != json.String {
491 return pref.Value{}, unexpectedJSONError{jval}
492 }
493 return pref.ValueOf(jval.String()), nil
494}
495
496func unmarshalBytes(jval json.Value) (pref.Value, error) {
497 if jval.Type() != json.String {
498 return pref.Value{}, unexpectedJSONError{jval}
499 }
500
501 s := jval.String()
502 enc := base64.StdEncoding
503 if strings.ContainsAny(s, "-_") {
504 enc = base64.URLEncoding
505 }
506 if len(s)%4 != 0 {
507 enc = enc.WithPadding(base64.NoPadding)
508 }
509 b, err := enc.DecodeString(s)
510 if err != nil {
511 return pref.Value{}, err
512 }
513 return pref.ValueOf(b), nil
514}
515
516func unmarshalEnum(jval json.Value, fd pref.FieldDescriptor) (pref.Value, error) {
517 switch jval.Type() {
518 case json.String:
519 // Lookup EnumNumber based on name.
520 s := jval.String()
521 if enumVal := fd.EnumType().Values().ByName(pref.Name(s)); enumVal != nil {
522 return pref.ValueOf(enumVal.Number()), nil
523 }
524 return pref.Value{}, newError("invalid enum value %q", jval)
525
526 case json.Number:
527 n, err := jval.Int(32)
528 if err != nil {
529 return pref.Value{}, err
530 }
531 return pref.ValueOf(pref.EnumNumber(n)), nil
Herbie Ong300b9fe2019-03-29 15:42:20 -0700532
533 case json.Null:
534 // This is only valid for google.protobuf.NullValue.
535 if isNullValue(fd) {
536 return pref.ValueOf(pref.EnumNumber(0)), nil
537 }
Herbie Ongc96a79d2019-03-08 10:49:17 -0800538 }
539
540 return pref.Value{}, unexpectedJSONError{jval}
541}
542
543// unmarshalRepeated unmarshals into a repeated field.
Herbie Ong822de2d2019-03-27 13:16:23 -0700544func (o UnmarshalOptions) unmarshalRepeated(knownFields pref.KnownFields, fd pref.FieldDescriptor) error {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800545 var nerr errors.NonFatal
546 num := fd.Number()
547 val := knownFields.Get(num)
548 if !fd.IsMap() {
Herbie Ong822de2d2019-03-27 13:16:23 -0700549 if err := o.unmarshalList(val.List(), fd); !nerr.Merge(err) {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800550 return err
551 }
552 } else {
Herbie Ong822de2d2019-03-27 13:16:23 -0700553 if err := o.unmarshalMap(val.Map(), fd); !nerr.Merge(err) {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800554 return err
555 }
556 }
557 return nerr.E
558}
559
560// unmarshalList unmarshals into given protoreflect.List.
Herbie Ong822de2d2019-03-27 13:16:23 -0700561func (o UnmarshalOptions) unmarshalList(list pref.List, fd pref.FieldDescriptor) error {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800562 var nerr errors.NonFatal
Herbie Ong822de2d2019-03-27 13:16:23 -0700563 jval, err := o.decoder.Read()
Herbie Ongc96a79d2019-03-08 10:49:17 -0800564 if !nerr.Merge(err) {
565 return err
566 }
567 if jval.Type() != json.StartArray {
568 return unexpectedJSONError{jval}
569 }
570
571 switch fd.Kind() {
572 case pref.MessageKind, pref.GroupKind:
573 for {
574 m := list.NewMessage()
Herbie Ong8ac9dd22019-03-27 12:20:50 -0700575 err := o.unmarshalMessage(m, false)
Herbie Ongc96a79d2019-03-08 10:49:17 -0800576 if !nerr.Merge(err) {
577 if e, ok := err.(unexpectedJSONError); ok {
578 if e.value.Type() == json.EndArray {
579 // Done with list.
580 return nerr.E
581 }
582 }
583 return err
584 }
585 list.Append(pref.ValueOf(m))
586 }
587 default:
588 for {
Herbie Ong822de2d2019-03-27 13:16:23 -0700589 val, err := o.unmarshalScalar(fd)
Herbie Ongc96a79d2019-03-08 10:49:17 -0800590 if !nerr.Merge(err) {
591 if e, ok := err.(unexpectedJSONError); ok {
592 if e.value.Type() == json.EndArray {
593 // Done with list.
594 return nerr.E
595 }
596 }
597 return err
598 }
599 list.Append(val)
600 }
601 }
602 return nerr.E
603}
604
605// unmarshalMap unmarshals into given protoreflect.Map.
Herbie Ong822de2d2019-03-27 13:16:23 -0700606func (o UnmarshalOptions) unmarshalMap(mmap pref.Map, fd pref.FieldDescriptor) error {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800607 var nerr errors.NonFatal
608
Herbie Ong822de2d2019-03-27 13:16:23 -0700609 jval, err := o.decoder.Read()
Herbie Ongc96a79d2019-03-08 10:49:17 -0800610 if !nerr.Merge(err) {
611 return err
612 }
613 if jval.Type() != json.StartObject {
614 return unexpectedJSONError{jval}
615 }
616
617 fields := fd.MessageType().Fields()
618 keyDesc := fields.ByNumber(1)
619 valDesc := fields.ByNumber(2)
620
621 // Determine ahead whether map entry is a scalar type or a message type in
622 // order to call the appropriate unmarshalMapValue func inside the for loop
623 // below.
624 unmarshalMapValue := func() (pref.Value, error) {
Herbie Ong822de2d2019-03-27 13:16:23 -0700625 return o.unmarshalScalar(valDesc)
Herbie Ongc96a79d2019-03-08 10:49:17 -0800626 }
627 switch valDesc.Kind() {
628 case pref.MessageKind, pref.GroupKind:
629 unmarshalMapValue = func() (pref.Value, error) {
Herbie Onge63c4c42019-03-22 22:20:22 -0700630 var nerr errors.NonFatal
Herbie Ongc96a79d2019-03-08 10:49:17 -0800631 m := mmap.NewMessage()
Herbie Ong8ac9dd22019-03-27 12:20:50 -0700632 if err := o.unmarshalMessage(m, false); !nerr.Merge(err) {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800633 return pref.Value{}, err
634 }
Herbie Onge63c4c42019-03-22 22:20:22 -0700635 return pref.ValueOf(m), nerr.E
Herbie Ongc96a79d2019-03-08 10:49:17 -0800636 }
637 }
638
639Loop:
640 for {
641 // Read field name.
Herbie Ong822de2d2019-03-27 13:16:23 -0700642 jval, err := o.decoder.Read()
Herbie Ongc96a79d2019-03-08 10:49:17 -0800643 if !nerr.Merge(err) {
644 return err
645 }
646 switch jval.Type() {
647 default:
648 return unexpectedJSONError{jval}
649 case json.EndObject:
650 break Loop
651 case json.Name:
652 // Continue.
653 }
654
655 name, err := jval.Name()
656 if !nerr.Merge(err) {
657 return err
658 }
659
660 // Unmarshal field name.
661 pkey, err := unmarshalMapKey(name, keyDesc)
662 if !nerr.Merge(err) {
663 return err
664 }
665
666 // Check for duplicate field name.
667 if mmap.Has(pkey) {
668 return newError("duplicate map key %q", jval)
669 }
670
671 // Read and unmarshal field value.
672 pval, err := unmarshalMapValue()
673 if !nerr.Merge(err) {
674 return err
675 }
676
677 mmap.Set(pkey, pval)
678 }
679
680 return nerr.E
681}
682
683// unmarshalMapKey converts given string into a protoreflect.MapKey. A map key type is any
684// integral or string type.
685func unmarshalMapKey(name string, fd pref.FieldDescriptor) (pref.MapKey, error) {
686 const b32 = 32
687 const b64 = 64
688 const base10 = 10
689
690 kind := fd.Kind()
691 switch kind {
692 case pref.StringKind:
693 return pref.ValueOf(name).MapKey(), nil
694
695 case pref.BoolKind:
696 switch name {
697 case "true":
698 return pref.ValueOf(true).MapKey(), nil
699 case "false":
700 return pref.ValueOf(false).MapKey(), nil
701 }
702 return pref.MapKey{}, errors.New("invalid value for boolean key %q", name)
703
704 case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
705 n, err := strconv.ParseInt(name, base10, b32)
706 if err != nil {
707 return pref.MapKey{}, err
708 }
709 return pref.ValueOf(int32(n)).MapKey(), nil
710
711 case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
712 n, err := strconv.ParseInt(name, base10, b64)
713 if err != nil {
714 return pref.MapKey{}, err
715 }
716 return pref.ValueOf(int64(n)).MapKey(), nil
717
718 case pref.Uint32Kind, pref.Fixed32Kind:
719 n, err := strconv.ParseUint(name, base10, b32)
720 if err != nil {
721 return pref.MapKey{}, err
722 }
723 return pref.ValueOf(uint32(n)).MapKey(), nil
724
725 case pref.Uint64Kind, pref.Fixed64Kind:
726 n, err := strconv.ParseUint(name, base10, b64)
727 if err != nil {
728 return pref.MapKey{}, err
729 }
730 return pref.ValueOf(uint64(n)).MapKey(), nil
731 }
732
733 panic(fmt.Sprintf("%s: invalid kind %s for map key", fd.FullName(), kind))
734}