mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-04 01:12:24 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			530 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			530 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2015 The Go Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package jsonpb
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"math"
 | 
						|
	"reflect"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/golang/protobuf/proto"
 | 
						|
	"google.golang.org/protobuf/encoding/protojson"
 | 
						|
	protoV2 "google.golang.org/protobuf/proto"
 | 
						|
	"google.golang.org/protobuf/reflect/protoreflect"
 | 
						|
	"google.golang.org/protobuf/reflect/protoregistry"
 | 
						|
)
 | 
						|
 | 
						|
const wrapJSONUnmarshalV2 = false
 | 
						|
 | 
						|
// UnmarshalNext unmarshals the next JSON object from d into m.
 | 
						|
func UnmarshalNext(d *json.Decoder, m proto.Message) error {
 | 
						|
	return new(Unmarshaler).UnmarshalNext(d, m)
 | 
						|
}
 | 
						|
 | 
						|
// Unmarshal unmarshals a JSON object from r into m.
 | 
						|
func Unmarshal(r io.Reader, m proto.Message) error {
 | 
						|
	return new(Unmarshaler).Unmarshal(r, m)
 | 
						|
}
 | 
						|
 | 
						|
// UnmarshalString unmarshals a JSON object from s into m.
 | 
						|
func UnmarshalString(s string, m proto.Message) error {
 | 
						|
	return new(Unmarshaler).Unmarshal(strings.NewReader(s), m)
 | 
						|
}
 | 
						|
 | 
						|
// Unmarshaler is a configurable object for converting from a JSON
 | 
						|
// representation to a protocol buffer object.
 | 
						|
type Unmarshaler struct {
 | 
						|
	// AllowUnknownFields specifies whether to allow messages to contain
 | 
						|
	// unknown JSON fields, as opposed to failing to unmarshal.
 | 
						|
	AllowUnknownFields bool
 | 
						|
 | 
						|
	// AnyResolver is used to resolve the google.protobuf.Any well-known type.
 | 
						|
	// If unset, the global registry is used by default.
 | 
						|
	AnyResolver AnyResolver
 | 
						|
}
 | 
						|
 | 
						|
// JSONPBUnmarshaler is implemented by protobuf messages that customize the way
 | 
						|
// they are unmarshaled from JSON. Messages that implement this should also
 | 
						|
// implement JSONPBMarshaler so that the custom format can be produced.
 | 
						|
//
 | 
						|
// The JSON unmarshaling must follow the JSON to proto specification:
 | 
						|
//	https://developers.google.com/protocol-buffers/docs/proto3#json
 | 
						|
//
 | 
						|
// Deprecated: Custom types should implement protobuf reflection instead.
 | 
						|
type JSONPBUnmarshaler interface {
 | 
						|
	UnmarshalJSONPB(*Unmarshaler, []byte) error
 | 
						|
}
 | 
						|
 | 
						|
// Unmarshal unmarshals a JSON object from r into m.
 | 
						|
func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error {
 | 
						|
	return u.UnmarshalNext(json.NewDecoder(r), m)
 | 
						|
}
 | 
						|
 | 
						|
// UnmarshalNext unmarshals the next JSON object from d into m.
 | 
						|
func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error {
 | 
						|
	if m == nil {
 | 
						|
		return errors.New("invalid nil message")
 | 
						|
	}
 | 
						|
 | 
						|
	// Parse the next JSON object from the stream.
 | 
						|
	raw := json.RawMessage{}
 | 
						|
	if err := d.Decode(&raw); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	// Check for custom unmarshalers first since they may not properly
 | 
						|
	// implement protobuf reflection that the logic below relies on.
 | 
						|
	if jsu, ok := m.(JSONPBUnmarshaler); ok {
 | 
						|
		return jsu.UnmarshalJSONPB(u, raw)
 | 
						|
	}
 | 
						|
 | 
						|
	mr := proto.MessageReflect(m)
 | 
						|
 | 
						|
	// NOTE: For historical reasons, a top-level null is treated as a noop.
 | 
						|
	// This is incorrect, but kept for compatibility.
 | 
						|
	if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	if wrapJSONUnmarshalV2 {
 | 
						|
		// NOTE: If input message is non-empty, we need to preserve merge semantics
 | 
						|
		// of the old jsonpb implementation. These semantics are not supported by
 | 
						|
		// the protobuf JSON specification.
 | 
						|
		isEmpty := true
 | 
						|
		mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool {
 | 
						|
			isEmpty = false // at least one iteration implies non-empty
 | 
						|
			return false
 | 
						|
		})
 | 
						|
		if !isEmpty {
 | 
						|
			// Perform unmarshaling into a newly allocated, empty message.
 | 
						|
			mr = mr.New()
 | 
						|
 | 
						|
			// Use a defer to copy all unmarshaled fields into the original message.
 | 
						|
			dst := proto.MessageReflect(m)
 | 
						|
			defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
 | 
						|
				dst.Set(fd, v)
 | 
						|
				return true
 | 
						|
			})
 | 
						|
		}
 | 
						|
 | 
						|
		// Unmarshal using the v2 JSON unmarshaler.
 | 
						|
		opts := protojson.UnmarshalOptions{
 | 
						|
			DiscardUnknown: u.AllowUnknownFields,
 | 
						|
		}
 | 
						|
		if u.AnyResolver != nil {
 | 
						|
			opts.Resolver = anyResolver{u.AnyResolver}
 | 
						|
		}
 | 
						|
		return opts.Unmarshal(raw, mr.Interface())
 | 
						|
	} else {
 | 
						|
		if err := u.unmarshalMessage(mr, raw); err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		return protoV2.CheckInitialized(mr.Interface())
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error {
 | 
						|
	md := m.Descriptor()
 | 
						|
	fds := md.Fields()
 | 
						|
 | 
						|
	if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok {
 | 
						|
		return jsu.UnmarshalJSONPB(u, in)
 | 
						|
	}
 | 
						|
 | 
						|
	if string(in) == "null" && md.FullName() != "google.protobuf.Value" {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	switch wellKnownType(md.FullName()) {
 | 
						|
	case "Any":
 | 
						|
		var jsonObject map[string]json.RawMessage
 | 
						|
		if err := json.Unmarshal(in, &jsonObject); err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
 | 
						|
		rawTypeURL, ok := jsonObject["@type"]
 | 
						|
		if !ok {
 | 
						|
			return errors.New("Any JSON doesn't have '@type'")
 | 
						|
		}
 | 
						|
		typeURL, err := unquoteString(string(rawTypeURL))
 | 
						|
		if err != nil {
 | 
						|
			return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL)
 | 
						|
		}
 | 
						|
		m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL))
 | 
						|
 | 
						|
		var m2 protoreflect.Message
 | 
						|
		if u.AnyResolver != nil {
 | 
						|
			mi, err := u.AnyResolver.Resolve(typeURL)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			m2 = proto.MessageReflect(mi)
 | 
						|
		} else {
 | 
						|
			mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL)
 | 
						|
			if err != nil {
 | 
						|
				if err == protoregistry.NotFound {
 | 
						|
					return fmt.Errorf("could not resolve Any message type: %v", typeURL)
 | 
						|
				}
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			m2 = mt.New()
 | 
						|
		}
 | 
						|
 | 
						|
		if wellKnownType(m2.Descriptor().FullName()) != "" {
 | 
						|
			rawValue, ok := jsonObject["value"]
 | 
						|
			if !ok {
 | 
						|
				return errors.New("Any JSON doesn't have 'value'")
 | 
						|
			}
 | 
						|
			if err := u.unmarshalMessage(m2, rawValue); err != nil {
 | 
						|
				return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			delete(jsonObject, "@type")
 | 
						|
			rawJSON, err := json.Marshal(jsonObject)
 | 
						|
			if err != nil {
 | 
						|
				return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err)
 | 
						|
			}
 | 
						|
			if err = u.unmarshalMessage(m2, rawJSON); err != nil {
 | 
						|
				return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err)
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		rawWire, err := protoV2.Marshal(m2.Interface())
 | 
						|
		if err != nil {
 | 
						|
			return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err)
 | 
						|
		}
 | 
						|
		m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire))
 | 
						|
		return nil
 | 
						|
	case "BoolValue", "BytesValue", "StringValue",
 | 
						|
		"Int32Value", "UInt32Value", "FloatValue",
 | 
						|
		"Int64Value", "UInt64Value", "DoubleValue":
 | 
						|
		fd := fds.ByNumber(1)
 | 
						|
		v, err := u.unmarshalValue(m.NewField(fd), in, fd)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		m.Set(fd, v)
 | 
						|
		return nil
 | 
						|
	case "Duration":
 | 
						|
		v, err := unquoteString(string(in))
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		d, err := time.ParseDuration(v)
 | 
						|
		if err != nil {
 | 
						|
			return fmt.Errorf("bad Duration: %v", err)
 | 
						|
		}
 | 
						|
 | 
						|
		sec := d.Nanoseconds() / 1e9
 | 
						|
		nsec := d.Nanoseconds() % 1e9
 | 
						|
		m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
 | 
						|
		m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
 | 
						|
		return nil
 | 
						|
	case "Timestamp":
 | 
						|
		v, err := unquoteString(string(in))
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		t, err := time.Parse(time.RFC3339Nano, v)
 | 
						|
		if err != nil {
 | 
						|
			return fmt.Errorf("bad Timestamp: %v", err)
 | 
						|
		}
 | 
						|
 | 
						|
		sec := t.Unix()
 | 
						|
		nsec := t.Nanosecond()
 | 
						|
		m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec)))
 | 
						|
		m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec)))
 | 
						|
		return nil
 | 
						|
	case "Value":
 | 
						|
		switch {
 | 
						|
		case string(in) == "null":
 | 
						|
			m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0))
 | 
						|
		case string(in) == "true":
 | 
						|
			m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true))
 | 
						|
		case string(in) == "false":
 | 
						|
			m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false))
 | 
						|
		case hasPrefixAndSuffix('"', in, '"'):
 | 
						|
			s, err := unquoteString(string(in))
 | 
						|
			if err != nil {
 | 
						|
				return fmt.Errorf("unrecognized type for Value %q", in)
 | 
						|
			}
 | 
						|
			m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s))
 | 
						|
		case hasPrefixAndSuffix('[', in, ']'):
 | 
						|
			v := m.Mutable(fds.ByNumber(6))
 | 
						|
			return u.unmarshalMessage(v.Message(), in)
 | 
						|
		case hasPrefixAndSuffix('{', in, '}'):
 | 
						|
			v := m.Mutable(fds.ByNumber(5))
 | 
						|
			return u.unmarshalMessage(v.Message(), in)
 | 
						|
		default:
 | 
						|
			f, err := strconv.ParseFloat(string(in), 0)
 | 
						|
			if err != nil {
 | 
						|
				return fmt.Errorf("unrecognized type for Value %q", in)
 | 
						|
			}
 | 
						|
			m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f))
 | 
						|
		}
 | 
						|
		return nil
 | 
						|
	case "ListValue":
 | 
						|
		var jsonArray []json.RawMessage
 | 
						|
		if err := json.Unmarshal(in, &jsonArray); err != nil {
 | 
						|
			return fmt.Errorf("bad ListValue: %v", err)
 | 
						|
		}
 | 
						|
 | 
						|
		lv := m.Mutable(fds.ByNumber(1)).List()
 | 
						|
		for _, raw := range jsonArray {
 | 
						|
			ve := lv.NewElement()
 | 
						|
			if err := u.unmarshalMessage(ve.Message(), raw); err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			lv.Append(ve)
 | 
						|
		}
 | 
						|
		return nil
 | 
						|
	case "Struct":
 | 
						|
		var jsonObject map[string]json.RawMessage
 | 
						|
		if err := json.Unmarshal(in, &jsonObject); err != nil {
 | 
						|
			return fmt.Errorf("bad StructValue: %v", err)
 | 
						|
		}
 | 
						|
 | 
						|
		mv := m.Mutable(fds.ByNumber(1)).Map()
 | 
						|
		for key, raw := range jsonObject {
 | 
						|
			kv := protoreflect.ValueOf(key).MapKey()
 | 
						|
			vv := mv.NewValue()
 | 
						|
			if err := u.unmarshalMessage(vv.Message(), raw); err != nil {
 | 
						|
				return fmt.Errorf("bad value in StructValue for key %q: %v", key, err)
 | 
						|
			}
 | 
						|
			mv.Set(kv, vv)
 | 
						|
		}
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	var jsonObject map[string]json.RawMessage
 | 
						|
	if err := json.Unmarshal(in, &jsonObject); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	// Handle known fields.
 | 
						|
	for i := 0; i < fds.Len(); i++ {
 | 
						|
		fd := fds.Get(i)
 | 
						|
		if fd.IsWeak() && fd.Message().IsPlaceholder() {
 | 
						|
			continue //  weak reference is not linked in
 | 
						|
		}
 | 
						|
 | 
						|
		// Search for any raw JSON value associated with this field.
 | 
						|
		var raw json.RawMessage
 | 
						|
		name := string(fd.Name())
 | 
						|
		if fd.Kind() == protoreflect.GroupKind {
 | 
						|
			name = string(fd.Message().Name())
 | 
						|
		}
 | 
						|
		if v, ok := jsonObject[name]; ok {
 | 
						|
			delete(jsonObject, name)
 | 
						|
			raw = v
 | 
						|
		}
 | 
						|
		name = string(fd.JSONName())
 | 
						|
		if v, ok := jsonObject[name]; ok {
 | 
						|
			delete(jsonObject, name)
 | 
						|
			raw = v
 | 
						|
		}
 | 
						|
 | 
						|
		field := m.NewField(fd)
 | 
						|
		// Unmarshal the field value.
 | 
						|
		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		v, err := u.unmarshalValue(field, raw, fd)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		m.Set(fd, v)
 | 
						|
	}
 | 
						|
 | 
						|
	// Handle extension fields.
 | 
						|
	for name, raw := range jsonObject {
 | 
						|
		if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		// Resolve the extension field by name.
 | 
						|
		xname := protoreflect.FullName(name[len("[") : len(name)-len("]")])
 | 
						|
		xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname)
 | 
						|
		if xt == nil && isMessageSet(md) {
 | 
						|
			xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension"))
 | 
						|
		}
 | 
						|
		if xt == nil {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		delete(jsonObject, name)
 | 
						|
		fd := xt.TypeDescriptor()
 | 
						|
		if fd.ContainingMessage().FullName() != m.Descriptor().FullName() {
 | 
						|
			return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName())
 | 
						|
		}
 | 
						|
 | 
						|
		field := m.NewField(fd)
 | 
						|
		// Unmarshal the field value.
 | 
						|
		if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		v, err := u.unmarshalValue(field, raw, fd)
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		m.Set(fd, v)
 | 
						|
	}
 | 
						|
 | 
						|
	if !u.AllowUnknownFields && len(jsonObject) > 0 {
 | 
						|
		for name := range jsonObject {
 | 
						|
			return fmt.Errorf("unknown field %q in %v", name, md.FullName())
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool {
 | 
						|
	if fd.Cardinality() == protoreflect.Repeated {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	if md := fd.Message(); md != nil {
 | 
						|
		return md.FullName() == "google.protobuf.Value"
 | 
						|
	}
 | 
						|
	if ed := fd.Enum(); ed != nil {
 | 
						|
		return ed.FullName() == "google.protobuf.NullValue"
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool {
 | 
						|
	if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated {
 | 
						|
		_, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler)
 | 
						|
		return ok
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
 | 
						|
	switch {
 | 
						|
	case fd.IsList():
 | 
						|
		var jsonArray []json.RawMessage
 | 
						|
		if err := json.Unmarshal(in, &jsonArray); err != nil {
 | 
						|
			return v, err
 | 
						|
		}
 | 
						|
		lv := v.List()
 | 
						|
		for _, raw := range jsonArray {
 | 
						|
			ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd)
 | 
						|
			if err != nil {
 | 
						|
				return v, err
 | 
						|
			}
 | 
						|
			lv.Append(ve)
 | 
						|
		}
 | 
						|
		return v, nil
 | 
						|
	case fd.IsMap():
 | 
						|
		var jsonObject map[string]json.RawMessage
 | 
						|
		if err := json.Unmarshal(in, &jsonObject); err != nil {
 | 
						|
			return v, err
 | 
						|
		}
 | 
						|
		kfd := fd.MapKey()
 | 
						|
		vfd := fd.MapValue()
 | 
						|
		mv := v.Map()
 | 
						|
		for key, raw := range jsonObject {
 | 
						|
			var kv protoreflect.MapKey
 | 
						|
			if kfd.Kind() == protoreflect.StringKind {
 | 
						|
				kv = protoreflect.ValueOf(key).MapKey()
 | 
						|
			} else {
 | 
						|
				v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd)
 | 
						|
				if err != nil {
 | 
						|
					return v, err
 | 
						|
				}
 | 
						|
				kv = v.MapKey()
 | 
						|
			}
 | 
						|
 | 
						|
			vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd)
 | 
						|
			if err != nil {
 | 
						|
				return v, err
 | 
						|
			}
 | 
						|
			mv.Set(kv, vv)
 | 
						|
		}
 | 
						|
		return v, nil
 | 
						|
	default:
 | 
						|
		return u.unmarshalSingularValue(v, in, fd)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
var nonFinite = map[string]float64{
 | 
						|
	`"NaN"`:       math.NaN(),
 | 
						|
	`"Infinity"`:  math.Inf(+1),
 | 
						|
	`"-Infinity"`: math.Inf(-1),
 | 
						|
}
 | 
						|
 | 
						|
func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
 | 
						|
	switch fd.Kind() {
 | 
						|
	case protoreflect.BoolKind:
 | 
						|
		return unmarshalValue(in, new(bool))
 | 
						|
	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
 | 
						|
		return unmarshalValue(trimQuote(in), new(int32))
 | 
						|
	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
 | 
						|
		return unmarshalValue(trimQuote(in), new(int64))
 | 
						|
	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
 | 
						|
		return unmarshalValue(trimQuote(in), new(uint32))
 | 
						|
	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
 | 
						|
		return unmarshalValue(trimQuote(in), new(uint64))
 | 
						|
	case protoreflect.FloatKind:
 | 
						|
		if f, ok := nonFinite[string(in)]; ok {
 | 
						|
			return protoreflect.ValueOfFloat32(float32(f)), nil
 | 
						|
		}
 | 
						|
		return unmarshalValue(trimQuote(in), new(float32))
 | 
						|
	case protoreflect.DoubleKind:
 | 
						|
		if f, ok := nonFinite[string(in)]; ok {
 | 
						|
			return protoreflect.ValueOfFloat64(float64(f)), nil
 | 
						|
		}
 | 
						|
		return unmarshalValue(trimQuote(in), new(float64))
 | 
						|
	case protoreflect.StringKind:
 | 
						|
		return unmarshalValue(in, new(string))
 | 
						|
	case protoreflect.BytesKind:
 | 
						|
		return unmarshalValue(in, new([]byte))
 | 
						|
	case protoreflect.EnumKind:
 | 
						|
		if hasPrefixAndSuffix('"', in, '"') {
 | 
						|
			vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in)))
 | 
						|
			if vd == nil {
 | 
						|
				return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName())
 | 
						|
			}
 | 
						|
			return protoreflect.ValueOfEnum(vd.Number()), nil
 | 
						|
		}
 | 
						|
		return unmarshalValue(in, new(protoreflect.EnumNumber))
 | 
						|
	case protoreflect.MessageKind, protoreflect.GroupKind:
 | 
						|
		err := u.unmarshalMessage(v.Message(), in)
 | 
						|
		return v, err
 | 
						|
	default:
 | 
						|
		panic(fmt.Sprintf("invalid kind %v", fd.Kind()))
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) {
 | 
						|
	err := json.Unmarshal(in, v)
 | 
						|
	return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err
 | 
						|
}
 | 
						|
 | 
						|
func unquoteString(in string) (out string, err error) {
 | 
						|
	err = json.Unmarshal([]byte(in), &out)
 | 
						|
	return out, err
 | 
						|
}
 | 
						|
 | 
						|
func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool {
 | 
						|
	if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix {
 | 
						|
		return true
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// trimQuote is like unquoteString but simply strips surrounding quotes.
 | 
						|
// This is incorrect, but is behavior done by the legacy implementation.
 | 
						|
func trimQuote(in []byte) []byte {
 | 
						|
	if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' {
 | 
						|
		in = in[1 : len(in)-1]
 | 
						|
	}
 | 
						|
	return in
 | 
						|
}
 |