blob: 7c6c5a52445fe9ad8b2cf6ae65e63be4377c23f8 [file] [log] [blame]
amit.ghosh258d14c2020-10-02 15:13:38 +02001// Copyright 2015 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/json"
9 "errors"
10 "fmt"
11 "io"
12 "math"
13 "reflect"
14 "strconv"
15 "strings"
16 "time"
17
18 "github.com/golang/protobuf/proto"
19 "google.golang.org/protobuf/encoding/protojson"
20 protoV2 "google.golang.org/protobuf/proto"
21 "google.golang.org/protobuf/reflect/protoreflect"
22 "google.golang.org/protobuf/reflect/protoregistry"
23)
24
25const wrapJSONUnmarshalV2 = false
26
27// UnmarshalNext unmarshals the next JSON object from d into m.
28func UnmarshalNext(d *json.Decoder, m proto.Message) error {
29 return new(Unmarshaler).UnmarshalNext(d, m)
30}
31
32// Unmarshal unmarshals a JSON object from r into m.
33func Unmarshal(r io.Reader, m proto.Message) error {
34 return new(Unmarshaler).Unmarshal(r, m)
35}
36
37// UnmarshalString unmarshals a JSON object from s into m.
38func UnmarshalString(s string, m proto.Message) error {
39 return new(Unmarshaler).Unmarshal(strings.NewReader(s), m)
40}
41
42// Unmarshaler is a configurable object for converting from a JSON
43// representation to a protocol buffer object.
44type Unmarshaler struct {
45 // AllowUnknownFields specifies whether to allow messages to contain
46 // unknown JSON fields, as opposed to failing to unmarshal.
47 AllowUnknownFields bool
48
49 // AnyResolver is used to resolve the google.protobuf.Any well-known type.
50 // If unset, the global registry is used by default.
51 AnyResolver AnyResolver
52}
53
54// JSONPBUnmarshaler is implemented by protobuf messages that customize the way
55// they are unmarshaled from JSON. Messages that implement this should also
56// implement JSONPBMarshaler so that the custom format can be produced.
57//
58// The JSON unmarshaling must follow the JSON to proto specification:
59// https://developers.google.com/protocol-buffers/docs/proto3#json
60//
61// Deprecated: Custom types should implement protobuf reflection instead.
62type JSONPBUnmarshaler interface {
63 UnmarshalJSONPB(*Unmarshaler, []byte) error
64}
65
66// Unmarshal unmarshals a JSON object from r into m.
67func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error {
68 return u.UnmarshalNext(json.NewDecoder(r), m)
69}
70
71// UnmarshalNext unmarshals the next JSON object from d into m.
72func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error {
73 if m == nil {
74 return errors.New("invalid nil message")
75 }
76
77 // Parse the next JSON object from the stream.
78 raw := json.RawMessage{}
79 if err := d.Decode(&raw); err != nil {
80 return err
81 }
82
83 // Check for custom unmarshalers first since they may not properly
84 // implement protobuf reflection that the logic below relies on.
85 if jsu, ok := m.(JSONPBUnmarshaler); ok {
86 return jsu.UnmarshalJSONPB(u, raw)
87 }
88
89 mr := proto.MessageReflect(m)
90
91 // NOTE: For historical reasons, a top-level null is treated as a noop.
92 // This is incorrect, but kept for compatibility.
93 if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" {
94 return nil
95 }
96
97 if wrapJSONUnmarshalV2 {
98 // NOTE: If input message is non-empty, we need to preserve merge semantics
99 // of the old jsonpb implementation. These semantics are not supported by
100 // the protobuf JSON specification.
101 isEmpty := true
102 mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool {
103 isEmpty = false // at least one iteration implies non-empty
104 return false
105 })
106 if !isEmpty {
107 // Perform unmarshaling into a newly allocated, empty message.
108 mr = mr.New()
109
110 // Use a defer to copy all unmarshaled fields into the original message.
111 dst := proto.MessageReflect(m)
112 defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
113 dst.Set(fd, v)
114 return true
115 })
116 }
117
118 // Unmarshal using the v2 JSON unmarshaler.
119 opts := protojson.UnmarshalOptions{
120 DiscardUnknown: u.AllowUnknownFields,
121 }
122 if u.AnyResolver != nil {
123 opts.Resolver = anyResolver{u.AnyResolver}
124 }
125 return opts.Unmarshal(raw, mr.Interface())
126 } else {
127 if err := u.unmarshalMessage(mr, raw); err != nil {
128 return err
129 }
130 return protoV2.CheckInitialized(mr.Interface())
131 }
132}
133
134func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error {
135 md := m.Descriptor()
136 fds := md.Fields()
137
138 if string(in) == "null" && md.FullName() != "google.protobuf.Value" {
139 return nil
140 }
141
142 if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok {
143 return jsu.UnmarshalJSONPB(u, in)
144 }
145
146 switch wellKnownType(md.FullName()) {
147 case "Any":
148 var jsonObject map[string]json.RawMessage
149 if err := json.Unmarshal(in, &jsonObject); err != nil {
150 return err
151 }
152
153 rawTypeURL, ok := jsonObject["@type"]
154 if !ok {
155 return errors.New("Any JSON doesn't have '@type'")
156 }
157 typeURL, err := unquoteString(string(rawTypeURL))
158 if err != nil {
159 return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL)
160 }
161 m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL))
162
163 var m2 protoreflect.Message
164 if u.AnyResolver != nil {
165 mi, err := u.AnyResolver.Resolve(typeURL)
166 if err != nil {
167 return err
168 }
169 m2 = proto.MessageReflect(mi)
170 } else {
171 mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL)
172 if err != nil {
173 if err == protoregistry.NotFound {
174 return fmt.Errorf("could not resolve Any message type: %v", typeURL)
175 }
176 return err
177 }
178 m2 = mt.New()
179 }
180
181 if wellKnownType(m2.Descriptor().FullName()) != "" {
182 rawValue, ok := jsonObject["value"]
183 if !ok {
184 return errors.New("Any JSON doesn't have 'value'")
185 }
186 if err := u.unmarshalMessage(m2, rawValue); err != nil {
187 return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
188 }
189 } else {
190 delete(jsonObject, "@type")
191 rawJSON, err := json.Marshal(jsonObject)
192 if err != nil {
193 return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err)
194 }
195 if err = u.unmarshalMessage(m2, rawJSON); err != nil {
196 return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
197 }
198 }
199
200 rawWire, err := protoV2.Marshal(m2.Interface())
201 if err != nil {
202 return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err)
203 }
204 m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire))
205 return nil
206 case "BoolValue", "BytesValue", "StringValue",
207 "Int32Value", "UInt32Value", "FloatValue",
208 "Int64Value", "UInt64Value", "DoubleValue":
209 fd := fds.ByNumber(1)
210 v, err := u.unmarshalValue(m.NewField(fd), in, fd)
211 if err != nil {
212 return err
213 }
214 m.Set(fd, v)
215 return nil
216 case "Duration":
217 v, err := unquoteString(string(in))
218 if err != nil {
219 return err
220 }
221 d, err := time.ParseDuration(v)
222 if err != nil {
223 return fmt.Errorf("bad Duration: %v", err)
224 }
225
226 sec := d.Nanoseconds() / 1e9
227 nsec := d.Nanoseconds() % 1e9
228 m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
229 m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
230 return nil
231 case "Timestamp":
232 v, err := unquoteString(string(in))
233 if err != nil {
234 return err
235 }
236 t, err := time.Parse(time.RFC3339Nano, v)
237 if err != nil {
238 return fmt.Errorf("bad Timestamp: %v", err)
239 }
240
241 sec := t.Unix()
242 nsec := t.Nanosecond()
243 m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
244 m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
245 return nil
246 case "Value":
247 switch {
248 case string(in) == "null":
249 m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0))
250 case string(in) == "true":
251 m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true))
252 case string(in) == "false":
253 m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false))
254 case hasPrefixAndSuffix('"', in, '"'):
255 s, err := unquoteString(string(in))
256 if err != nil {
257 return fmt.Errorf("unrecognized type for Value %q", in)
258 }
259 m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s))
260 case hasPrefixAndSuffix('[', in, ']'):
261 v := m.Mutable(fds.ByNumber(6))
262 return u.unmarshalMessage(v.Message(), in)
263 case hasPrefixAndSuffix('{', in, '}'):
264 v := m.Mutable(fds.ByNumber(5))
265 return u.unmarshalMessage(v.Message(), in)
266 default:
267 f, err := strconv.ParseFloat(string(in), 0)
268 if err != nil {
269 return fmt.Errorf("unrecognized type for Value %q", in)
270 }
271 m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f))
272 }
273 return nil
274 case "ListValue":
275 var jsonArray []json.RawMessage
276 if err := json.Unmarshal(in, &jsonArray); err != nil {
277 return fmt.Errorf("bad ListValue: %v", err)
278 }
279
280 lv := m.Mutable(fds.ByNumber(1)).List()
281 for _, raw := range jsonArray {
282 ve := lv.NewElement()
283 if err := u.unmarshalMessage(ve.Message(), raw); err != nil {
284 return err
285 }
286 lv.Append(ve)
287 }
288 return nil
289 case "Struct":
290 var jsonObject map[string]json.RawMessage
291 if err := json.Unmarshal(in, &jsonObject); err != nil {
292 return fmt.Errorf("bad StructValue: %v", err)
293 }
294
295 mv := m.Mutable(fds.ByNumber(1)).Map()
296 for key, raw := range jsonObject {
297 kv := protoreflect.ValueOf(key).MapKey()
298 vv := mv.NewValue()
299 if err := u.unmarshalMessage(vv.Message(), raw); err != nil {
300 return fmt.Errorf("bad value in StructValue for key %q: %v", key, err)
301 }
302 mv.Set(kv, vv)
303 }
304 return nil
305 }
306
307 var jsonObject map[string]json.RawMessage
308 if err := json.Unmarshal(in, &jsonObject); err != nil {
309 return err
310 }
311
312 // Handle known fields.
313 for i := 0; i < fds.Len(); i++ {
314 fd := fds.Get(i)
315 if fd.IsWeak() && fd.Message().IsPlaceholder() {
316 continue // weak reference is not linked in
317 }
318
319 // Search for any raw JSON value associated with this field.
320 var raw json.RawMessage
321 name := string(fd.Name())
322 if fd.Kind() == protoreflect.GroupKind {
323 name = string(fd.Message().Name())
324 }
325 if v, ok := jsonObject[name]; ok {
326 delete(jsonObject, name)
327 raw = v
328 }
329 name = string(fd.JSONName())
330 if v, ok := jsonObject[name]; ok {
331 delete(jsonObject, name)
332 raw = v
333 }
334
335 // Unmarshal the field value.
336 if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd)) {
337 continue
338 }
339 v, err := u.unmarshalValue(m.NewField(fd), raw, fd)
340 if err != nil {
341 return err
342 }
343 m.Set(fd, v)
344 }
345
346 // Handle extension fields.
347 for name, raw := range jsonObject {
348 if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") {
349 continue
350 }
351
352 // Resolve the extension field by name.
353 xname := protoreflect.FullName(name[len("[") : len(name)-len("]")])
354 xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname)
355 if xt == nil && isMessageSet(md) {
356 xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension"))
357 }
358 if xt == nil {
359 continue
360 }
361 delete(jsonObject, name)
362 fd := xt.TypeDescriptor()
363 if fd.ContainingMessage().FullName() != m.Descriptor().FullName() {
364 return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName())
365 }
366
367 // Unmarshal the field value.
368 if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd)) {
369 continue
370 }
371 v, err := u.unmarshalValue(m.NewField(fd), raw, fd)
372 if err != nil {
373 return err
374 }
375 m.Set(fd, v)
376 }
377
378 if !u.AllowUnknownFields && len(jsonObject) > 0 {
379 for name := range jsonObject {
380 return fmt.Errorf("unknown field %q in %v", name, md.FullName())
381 }
382 }
383 return nil
384}
385
386func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
387 if md := fd.Message(); md != nil {
388 return md.FullName() == "google.protobuf.Value" && fd.Cardinality() != protoreflect.Repeated
389 }
390 return false
391}
392
393func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
394 switch {
395 case fd.IsList():
396 var jsonArray []json.RawMessage
397 if err := json.Unmarshal(in, &jsonArray); err != nil {
398 return v, err
399 }
400 lv := v.List()
401 for _, raw := range jsonArray {
402 ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd)
403 if err != nil {
404 return v, err
405 }
406 lv.Append(ve)
407 }
408 return v, nil
409 case fd.IsMap():
410 var jsonObject map[string]json.RawMessage
411 if err := json.Unmarshal(in, &jsonObject); err != nil {
412 return v, err
413 }
414 kfd := fd.MapKey()
415 vfd := fd.MapValue()
416 mv := v.Map()
417 for key, raw := range jsonObject {
418 var kv protoreflect.MapKey
419 if kfd.Kind() == protoreflect.StringKind {
420 kv = protoreflect.ValueOf(key).MapKey()
421 } else {
422 v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd)
423 if err != nil {
424 return v, err
425 }
426 kv = v.MapKey()
427 }
428
429 vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd)
430 if err != nil {
431 return v, err
432 }
433 mv.Set(kv, vv)
434 }
435 return v, nil
436 default:
437 return u.unmarshalSingularValue(v, in, fd)
438 }
439}
440
441var nonFinite = map[string]float64{
442 `"NaN"`: math.NaN(),
443 `"Infinity"`: math.Inf(+1),
444 `"-Infinity"`: math.Inf(-1),
445}
446
447func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
448 switch fd.Kind() {
449 case protoreflect.BoolKind:
450 return unmarshalValue(in, new(bool))
451 case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
452 return unmarshalValue(trimQuote(in), new(int32))
453 case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
454 return unmarshalValue(trimQuote(in), new(int64))
455 case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
456 return unmarshalValue(trimQuote(in), new(uint32))
457 case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
458 return unmarshalValue(trimQuote(in), new(uint64))
459 case protoreflect.FloatKind:
460 if f, ok := nonFinite[string(in)]; ok {
461 return protoreflect.ValueOfFloat32(float32(f)), nil
462 }
463 return unmarshalValue(trimQuote(in), new(float32))
464 case protoreflect.DoubleKind:
465 if f, ok := nonFinite[string(in)]; ok {
466 return protoreflect.ValueOfFloat64(float64(f)), nil
467 }
468 return unmarshalValue(trimQuote(in), new(float64))
469 case protoreflect.StringKind:
470 return unmarshalValue(in, new(string))
471 case protoreflect.BytesKind:
472 return unmarshalValue(in, new([]byte))
473 case protoreflect.EnumKind:
474 if hasPrefixAndSuffix('"', in, '"') {
475 vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in)))
476 if vd == nil {
477 return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName())
478 }
479 return protoreflect.ValueOfEnum(vd.Number()), nil
480 }
481 return unmarshalValue(in, new(protoreflect.EnumNumber))
482 case protoreflect.MessageKind, protoreflect.GroupKind:
483 err := u.unmarshalMessage(v.Message(), in)
484 return v, err
485 default:
486 panic(fmt.Sprintf("invalid kind %v", fd.Kind()))
487 }
488}
489
490func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) {
491 err := json.Unmarshal(in, v)
492 return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err
493}
494
495func unquoteString(in string) (out string, err error) {
496 err = json.Unmarshal([]byte(in), &out)
497 return out, err
498}
499
500func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool {
501 if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix {
502 return true
503 }
504 return false
505}
506
507// trimQuote is like unquoteString but simply strips surrounding quotes.
508// This is incorrect, but is behavior done by the legacy implementation.
509func trimQuote(in []byte) []byte {
510 if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' {
511 in = in[1 : len(in)-1]
512 }
513 return in
514}