// 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 (
	
	
	
	
	
	
	
	
	

	
	
	protoV2 
	
	
)

const wrapJSONUnmarshalV2 = false

// UnmarshalNext unmarshals the next JSON object from d into m.
func ( *json.Decoder,  proto.Message) error {
	return new(Unmarshaler).UnmarshalNext(, )
}

// Unmarshal unmarshals a JSON object from r into m.
func ( io.Reader,  proto.Message) error {
	return new(Unmarshaler).Unmarshal(, )
}

// UnmarshalString unmarshals a JSON object from s into m.
func ( string,  proto.Message) error {
	return new(Unmarshaler).Unmarshal(strings.NewReader(), )
}

// 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 ( *Unmarshaler) ( io.Reader,  proto.Message) error {
	return .UnmarshalNext(json.NewDecoder(), )
}

// UnmarshalNext unmarshals the next JSON object from d into m.
func ( *Unmarshaler) ( *json.Decoder,  proto.Message) error {
	if  == nil {
		return errors.New("invalid nil message")
	}

	// Parse the next JSON object from the stream.
	 := json.RawMessage{}
	if  := .Decode(&);  != nil {
		return 
	}

	// Check for custom unmarshalers first since they may not properly
	// implement protobuf reflection that the logic below relies on.
	if ,  := .(JSONPBUnmarshaler);  {
		return .UnmarshalJSONPB(, )
	}

	 := proto.MessageReflect()

	// NOTE: For historical reasons, a top-level null is treated as a noop.
	// This is incorrect, but kept for compatibility.
	if string() == "null" && .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.
		 := true
		.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool {
			 = false // at least one iteration implies non-empty
			return false
		})
		if ! {
			// Perform unmarshaling into a newly allocated, empty message.
			 = .New()

			// Use a defer to copy all unmarshaled fields into the original message.
			 := proto.MessageReflect()
			defer .Range(func( protoreflect.FieldDescriptor,  protoreflect.Value) bool {
				.Set(, )
				return true
			})
		}

		// Unmarshal using the v2 JSON unmarshaler.
		 := protojson.UnmarshalOptions{
			DiscardUnknown: .AllowUnknownFields,
		}
		if .AnyResolver != nil {
			.Resolver = anyResolver{.AnyResolver}
		}
		return .Unmarshal(, .Interface())
	} else {
		if  := .unmarshalMessage(, );  != nil {
			return 
		}
		return protoV2.CheckInitialized(.Interface())
	}
}

func ( *Unmarshaler) ( protoreflect.Message,  []byte) error {
	 := .Descriptor()
	 := .Fields()

	if ,  := proto.MessageV1(.Interface()).(JSONPBUnmarshaler);  {
		return .UnmarshalJSONPB(, )
	}

	if string() == "null" && .FullName() != "google.protobuf.Value" {
		return nil
	}

	switch wellKnownType(.FullName()) {
	case "Any":
		var  map[string]json.RawMessage
		if  := json.Unmarshal(, &);  != nil {
			return 
		}

		,  := ["@type"]
		if ! {
			return errors.New("Any JSON doesn't have '@type'")
		}
		,  := unquoteString(string())
		if  != nil {
			return fmt.Errorf("can't unmarshal Any's '@type': %q", )
		}
		.Set(.ByNumber(1), protoreflect.ValueOfString())

		var  protoreflect.Message
		if .AnyResolver != nil {
			,  := .AnyResolver.Resolve()
			if  != nil {
				return 
			}
			 = proto.MessageReflect()
		} else {
			,  := protoregistry.GlobalTypes.FindMessageByURL()
			if  != nil {
				if  == protoregistry.NotFound {
					return fmt.Errorf("could not resolve Any message type: %v", )
				}
				return 
			}
			 = .New()
		}

		if wellKnownType(.Descriptor().FullName()) != "" {
			,  := ["value"]
			if ! {
				return errors.New("Any JSON doesn't have 'value'")
			}
			if  := .(, );  != nil {
				return fmt.Errorf("can't unmarshal Any nested proto %v: %v", , )
			}
		} else {
			delete(, "@type")
			,  := json.Marshal()
			if  != nil {
				return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", )
			}
			if  = .(, );  != nil {
				return fmt.Errorf("can't unmarshal Any nested proto %v: %v", , )
			}
		}

		,  := protoV2.Marshal(.Interface())
		if  != nil {
			return fmt.Errorf("can't marshal proto %v into Any.Value: %v", , )
		}
		.Set(.ByNumber(2), protoreflect.ValueOfBytes())
		return nil
	case "BoolValue", "BytesValue", "StringValue",
		"Int32Value", "UInt32Value", "FloatValue",
		"Int64Value", "UInt64Value", "DoubleValue":
		 := .ByNumber(1)
		,  := .unmarshalValue(.NewField(), , )
		if  != nil {
			return 
		}
		.Set(, )
		return nil
	case "Duration":
		,  := unquoteString(string())
		if  != nil {
			return 
		}
		,  := time.ParseDuration()
		if  != nil {
			return fmt.Errorf("bad Duration: %v", )
		}

		 := .Nanoseconds() / 1e9
		 := .Nanoseconds() % 1e9
		.Set(.ByNumber(1), protoreflect.ValueOfInt64(int64()))
		.Set(.ByNumber(2), protoreflect.ValueOfInt32(int32()))
		return nil
	case "Timestamp":
		,  := unquoteString(string())
		if  != nil {
			return 
		}
		,  := time.Parse(time.RFC3339Nano, )
		if  != nil {
			return fmt.Errorf("bad Timestamp: %v", )
		}

		 := .Unix()
		 := .Nanosecond()
		.Set(.ByNumber(1), protoreflect.ValueOfInt64(int64()))
		.Set(.ByNumber(2), protoreflect.ValueOfInt32(int32()))
		return nil
	case "Value":
		switch {
		case string() == "null":
			.Set(.ByNumber(1), protoreflect.ValueOfEnum(0))
		case string() == "true":
			.Set(.ByNumber(4), protoreflect.ValueOfBool(true))
		case string() == "false":
			.Set(.ByNumber(4), protoreflect.ValueOfBool(false))
		case hasPrefixAndSuffix('"', , '"'):
			,  := unquoteString(string())
			if  != nil {
				return fmt.Errorf("unrecognized type for Value %q", )
			}
			.Set(.ByNumber(3), protoreflect.ValueOfString())
		case hasPrefixAndSuffix('[', , ']'):
			 := .Mutable(.ByNumber(6))
			return .(.Message(), )
		case hasPrefixAndSuffix('{', , '}'):
			 := .Mutable(.ByNumber(5))
			return .(.Message(), )
		default:
			,  := strconv.ParseFloat(string(), 0)
			if  != nil {
				return fmt.Errorf("unrecognized type for Value %q", )
			}
			.Set(.ByNumber(2), protoreflect.ValueOfFloat64())
		}
		return nil
	case "ListValue":
		var  []json.RawMessage
		if  := json.Unmarshal(, &);  != nil {
			return fmt.Errorf("bad ListValue: %v", )
		}

		 := .Mutable(.ByNumber(1)).List()
		for ,  := range  {
			 := .NewElement()
			if  := .(.Message(), );  != nil {
				return 
			}
			.Append()
		}
		return nil
	case "Struct":
		var  map[string]json.RawMessage
		if  := json.Unmarshal(, &);  != nil {
			return fmt.Errorf("bad StructValue: %v", )
		}

		 := .Mutable(.ByNumber(1)).Map()
		for ,  := range  {
			 := protoreflect.ValueOf().MapKey()
			 := .NewValue()
			if  := .(.Message(), );  != nil {
				return fmt.Errorf("bad value in StructValue for key %q: %v", , )
			}
			.Set(, )
		}
		return nil
	}

	var  map[string]json.RawMessage
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	// Handle known fields.
	for  := 0;  < .Len(); ++ {
		 := .Get()
		if .IsWeak() && .Message().IsPlaceholder() {
			continue //  weak reference is not linked in
		}

		// Search for any raw JSON value associated with this field.
		var  json.RawMessage
		 := string(.Name())
		if .Kind() == protoreflect.GroupKind {
			 = string(.Message().Name())
		}
		if ,  := [];  {
			delete(, )
			 = 
		}
		 = string(.JSONName())
		if ,  := [];  {
			delete(, )
			 = 
		}

		 := .NewField()
		// Unmarshal the field value.
		if  == nil || (string() == "null" && !isSingularWellKnownValue() && !isSingularJSONPBUnmarshaler(, )) {
			continue
		}
		,  := .unmarshalValue(, , )
		if  != nil {
			return 
		}
		.Set(, )
	}

	// Handle extension fields.
	for ,  := range  {
		if !strings.HasPrefix(, "[") || !strings.HasSuffix(, "]") {
			continue
		}

		// Resolve the extension field by name.
		 := protoreflect.FullName([len("[") : len()-len("]")])
		,  := protoregistry.GlobalTypes.FindExtensionByName()
		if  == nil && isMessageSet() {
			, _ = protoregistry.GlobalTypes.FindExtensionByName(.Append("message_set_extension"))
		}
		if  == nil {
			continue
		}
		delete(, )
		 := .TypeDescriptor()
		if .ContainingMessage().FullName() != .Descriptor().FullName() {
			return fmt.Errorf("extension field %q does not extend message %q", , .Descriptor().FullName())
		}

		 := .NewField()
		// Unmarshal the field value.
		if  == nil || (string() == "null" && !isSingularWellKnownValue() && !isSingularJSONPBUnmarshaler(, )) {
			continue
		}
		,  := .unmarshalValue(, , )
		if  != nil {
			return 
		}
		.Set(, )
	}

	if !.AllowUnknownFields && len() > 0 {
		for  := range  {
			return fmt.Errorf("unknown field %q in %v", , .FullName())
		}
	}
	return nil
}

func ( protoreflect.FieldDescriptor) bool {
	if  := .Message();  != nil {
		return .FullName() == "google.protobuf.Value" && .Cardinality() != protoreflect.Repeated
	}
	return false
}

func ( protoreflect.Value,  protoreflect.FieldDescriptor) bool {
	if .Message() != nil && .Cardinality() != protoreflect.Repeated {
		,  := proto.MessageV1(.Interface()).(JSONPBUnmarshaler)
		return 
	}
	return false
}

func ( *Unmarshaler) ( protoreflect.Value,  []byte,  protoreflect.FieldDescriptor) (protoreflect.Value, error) {
	switch {
	case .IsList():
		var  []json.RawMessage
		if  := json.Unmarshal(, &);  != nil {
			return , 
		}
		 := .List()
		for ,  := range  {
			,  := .unmarshalSingularValue(.NewElement(), , )
			if  != nil {
				return , 
			}
			.Append()
		}
		return , nil
	case .IsMap():
		var  map[string]json.RawMessage
		if  := json.Unmarshal(, &);  != nil {
			return , 
		}
		 := .MapKey()
		 := .MapValue()
		 := .Map()
		for ,  := range  {
			var  protoreflect.MapKey
			if .Kind() == protoreflect.StringKind {
				 = protoreflect.ValueOf().MapKey()
			} else {
				,  := .unmarshalSingularValue(.Default(), []byte(), )
				if  != nil {
					return , 
				}
				 = .MapKey()
			}

			,  := .unmarshalSingularValue(.NewValue(), , )
			if  != nil {
				return , 
			}
			.Set(, )
		}
		return , nil
	default:
		return .unmarshalSingularValue(, , )
	}
}

var nonFinite = map[string]float64{
	`"NaN"`:       math.NaN(),
	`"Infinity"`:  math.Inf(+1),
	`"-Infinity"`: math.Inf(-1),
}

func ( *Unmarshaler) ( protoreflect.Value,  []byte,  protoreflect.FieldDescriptor) (protoreflect.Value, error) {
	switch .Kind() {
	case protoreflect.BoolKind:
		return unmarshalValue(, new(bool))
	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
		return unmarshalValue(trimQuote(), new(int32))
	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
		return unmarshalValue(trimQuote(), new(int64))
	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
		return unmarshalValue(trimQuote(), new(uint32))
	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
		return unmarshalValue(trimQuote(), new(uint64))
	case protoreflect.FloatKind:
		if ,  := nonFinite[string()];  {
			return protoreflect.ValueOfFloat32(float32()), nil
		}
		return unmarshalValue(trimQuote(), new(float32))
	case protoreflect.DoubleKind:
		if ,  := nonFinite[string()];  {
			return protoreflect.ValueOfFloat64(float64()), nil
		}
		return unmarshalValue(trimQuote(), new(float64))
	case protoreflect.StringKind:
		return unmarshalValue(, new(string))
	case protoreflect.BytesKind:
		return unmarshalValue(, new([]byte))
	case protoreflect.EnumKind:
		if hasPrefixAndSuffix('"', , '"') {
			 := .Enum().Values().ByName(protoreflect.Name(trimQuote()))
			if  == nil {
				return , fmt.Errorf("unknown value %q for enum %s", , .Enum().FullName())
			}
			return protoreflect.ValueOfEnum(.Number()), nil
		}
		return unmarshalValue(, new(protoreflect.EnumNumber))
	case protoreflect.MessageKind, protoreflect.GroupKind:
		 := .unmarshalMessage(.Message(), )
		return , 
	default:
		panic(fmt.Sprintf("invalid kind %v", .Kind()))
	}
}

func ( []byte,  interface{}) (protoreflect.Value, error) {
	 := json.Unmarshal(, )
	return protoreflect.ValueOf(reflect.ValueOf().Elem().Interface()), 
}

func ( string) ( string,  error) {
	 = json.Unmarshal([]byte(), &)
	return , 
}

func ( byte,  []byte,  byte) bool {
	if len() >= 2 && [0] ==  && [len()-1] ==  {
		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 ( []byte) []byte {
	if len() >= 2 && [0] == '"' && [len()-1] == '"' {
		 = [1 : len()-1]
	}
	return 
}