gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

decode.go (15804B)


      1 // 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 
      5 package jsonpb
      6 
      7 import (
      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 
     25 const wrapJSONUnmarshalV2 = false
     26 
     27 // UnmarshalNext unmarshals the next JSON object from d into m.
     28 func 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.
     33 func 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.
     38 func 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.
     44 type 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.
     62 type JSONPBUnmarshaler interface {
     63 	UnmarshalJSONPB(*Unmarshaler, []byte) error
     64 }
     65 
     66 // Unmarshal unmarshals a JSON object from r into m.
     67 func (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.
     72 func (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 
    134 func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error {
    135 	md := m.Descriptor()
    136 	fds := md.Fields()
    137 
    138 	if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok {
    139 		return jsu.UnmarshalJSONPB(u, in)
    140 	}
    141 
    142 	if string(in) == "null" && md.FullName() != "google.protobuf.Value" {
    143 		return nil
    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 		field := m.NewField(fd)
    336 		// Unmarshal the field value.
    337 		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
    338 			continue
    339 		}
    340 		v, err := u.unmarshalValue(field, raw, fd)
    341 		if err != nil {
    342 			return err
    343 		}
    344 		m.Set(fd, v)
    345 	}
    346 
    347 	// Handle extension fields.
    348 	for name, raw := range jsonObject {
    349 		if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") {
    350 			continue
    351 		}
    352 
    353 		// Resolve the extension field by name.
    354 		xname := protoreflect.FullName(name[len("[") : len(name)-len("]")])
    355 		xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname)
    356 		if xt == nil && isMessageSet(md) {
    357 			xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension"))
    358 		}
    359 		if xt == nil {
    360 			continue
    361 		}
    362 		delete(jsonObject, name)
    363 		fd := xt.TypeDescriptor()
    364 		if fd.ContainingMessage().FullName() != m.Descriptor().FullName() {
    365 			return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName())
    366 		}
    367 
    368 		field := m.NewField(fd)
    369 		// Unmarshal the field value.
    370 		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
    371 			continue
    372 		}
    373 		v, err := u.unmarshalValue(field, raw, fd)
    374 		if err != nil {
    375 			return err
    376 		}
    377 		m.Set(fd, v)
    378 	}
    379 
    380 	if !u.AllowUnknownFields && len(jsonObject) > 0 {
    381 		for name := range jsonObject {
    382 			return fmt.Errorf("unknown field %q in %v", name, md.FullName())
    383 		}
    384 	}
    385 	return nil
    386 }
    387 
    388 func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
    389 	if fd.Cardinality() == protoreflect.Repeated {
    390 		return false
    391 	}
    392 	if md := fd.Message(); md != nil {
    393 		return md.FullName() == "google.protobuf.Value"
    394 	}
    395 	if ed := fd.Enum(); ed != nil {
    396 		return ed.FullName() == "google.protobuf.NullValue"
    397 	}
    398 	return false
    399 }
    400 
    401 func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool {
    402 	if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated {
    403 		_, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler)
    404 		return ok
    405 	}
    406 	return false
    407 }
    408 
    409 func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
    410 	switch {
    411 	case fd.IsList():
    412 		var jsonArray []json.RawMessage
    413 		if err := json.Unmarshal(in, &jsonArray); err != nil {
    414 			return v, err
    415 		}
    416 		lv := v.List()
    417 		for _, raw := range jsonArray {
    418 			ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd)
    419 			if err != nil {
    420 				return v, err
    421 			}
    422 			lv.Append(ve)
    423 		}
    424 		return v, nil
    425 	case fd.IsMap():
    426 		var jsonObject map[string]json.RawMessage
    427 		if err := json.Unmarshal(in, &jsonObject); err != nil {
    428 			return v, err
    429 		}
    430 		kfd := fd.MapKey()
    431 		vfd := fd.MapValue()
    432 		mv := v.Map()
    433 		for key, raw := range jsonObject {
    434 			var kv protoreflect.MapKey
    435 			if kfd.Kind() == protoreflect.StringKind {
    436 				kv = protoreflect.ValueOf(key).MapKey()
    437 			} else {
    438 				v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd)
    439 				if err != nil {
    440 					return v, err
    441 				}
    442 				kv = v.MapKey()
    443 			}
    444 
    445 			vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd)
    446 			if err != nil {
    447 				return v, err
    448 			}
    449 			mv.Set(kv, vv)
    450 		}
    451 		return v, nil
    452 	default:
    453 		return u.unmarshalSingularValue(v, in, fd)
    454 	}
    455 }
    456 
    457 var nonFinite = map[string]float64{
    458 	`"NaN"`:       math.NaN(),
    459 	`"Infinity"`:  math.Inf(+1),
    460 	`"-Infinity"`: math.Inf(-1),
    461 }
    462 
    463 func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
    464 	switch fd.Kind() {
    465 	case protoreflect.BoolKind:
    466 		return unmarshalValue(in, new(bool))
    467 	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
    468 		return unmarshalValue(trimQuote(in), new(int32))
    469 	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
    470 		return unmarshalValue(trimQuote(in), new(int64))
    471 	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
    472 		return unmarshalValue(trimQuote(in), new(uint32))
    473 	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
    474 		return unmarshalValue(trimQuote(in), new(uint64))
    475 	case protoreflect.FloatKind:
    476 		if f, ok := nonFinite[string(in)]; ok {
    477 			return protoreflect.ValueOfFloat32(float32(f)), nil
    478 		}
    479 		return unmarshalValue(trimQuote(in), new(float32))
    480 	case protoreflect.DoubleKind:
    481 		if f, ok := nonFinite[string(in)]; ok {
    482 			return protoreflect.ValueOfFloat64(float64(f)), nil
    483 		}
    484 		return unmarshalValue(trimQuote(in), new(float64))
    485 	case protoreflect.StringKind:
    486 		return unmarshalValue(in, new(string))
    487 	case protoreflect.BytesKind:
    488 		return unmarshalValue(in, new([]byte))
    489 	case protoreflect.EnumKind:
    490 		if hasPrefixAndSuffix('"', in, '"') {
    491 			vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in)))
    492 			if vd == nil {
    493 				return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName())
    494 			}
    495 			return protoreflect.ValueOfEnum(vd.Number()), nil
    496 		}
    497 		return unmarshalValue(in, new(protoreflect.EnumNumber))
    498 	case protoreflect.MessageKind, protoreflect.GroupKind:
    499 		err := u.unmarshalMessage(v.Message(), in)
    500 		return v, err
    501 	default:
    502 		panic(fmt.Sprintf("invalid kind %v", fd.Kind()))
    503 	}
    504 }
    505 
    506 func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) {
    507 	err := json.Unmarshal(in, v)
    508 	return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err
    509 }
    510 
    511 func unquoteString(in string) (out string, err error) {
    512 	err = json.Unmarshal([]byte(in), &out)
    513 	return out, err
    514 }
    515 
    516 func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool {
    517 	if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix {
    518 		return true
    519 	}
    520 	return false
    521 }
    522 
    523 // trimQuote is like unquoteString but simply strips surrounding quotes.
    524 // This is incorrect, but is behavior done by the legacy implementation.
    525 func trimQuote(in []byte) []byte {
    526 	if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' {
    527 		in = in[1 : len(in)-1]
    528 	}
    529 	return in
    530 }