// Copyright 2019 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 protojson

import (
	
	
	
	
	

	
	
	
	
	
	
	
	
	
	
)

// Unmarshal reads the given []byte into the given proto.Message.
// The provided message must be mutable (e.g., a non-nil pointer to a message).
func ( []byte,  proto.Message) error {
	return UnmarshalOptions{}.Unmarshal(, )
}

// UnmarshalOptions is a configurable JSON format parser.
type UnmarshalOptions struct {
	pragma.NoUnkeyedLiterals

	// If AllowPartial is set, input for messages that will result in missing
	// required fields will not return an error.
	AllowPartial bool

	// If DiscardUnknown is set, unknown fields are ignored.
	DiscardUnknown bool

	// Resolver is used for looking up types when unmarshaling
	// google.protobuf.Any messages or extension fields.
	// If nil, this defaults to using protoregistry.GlobalTypes.
	Resolver interface {
		protoregistry.MessageTypeResolver
		protoregistry.ExtensionTypeResolver
	}
}

// Unmarshal reads the given []byte and populates the given proto.Message
// using options in the UnmarshalOptions object.
// It will clear the message first before setting the fields.
// If it returns an error, the given message may be partially set.
// The provided message must be mutable (e.g., a non-nil pointer to a message).
func ( UnmarshalOptions) ( []byte,  proto.Message) error {
	return .unmarshal(, )
}

// unmarshal is a centralized function that all unmarshal operations go through.
// For profiling purposes, avoid changing the name of this function or
// introducing other code paths for unmarshal that do not go through this.
func ( UnmarshalOptions) ( []byte,  proto.Message) error {
	proto.Reset()

	if .Resolver == nil {
		.Resolver = protoregistry.GlobalTypes
	}

	 := decoder{json.NewDecoder(), }
	if  := .unmarshalMessage(.ProtoReflect(), false);  != nil {
		return 
	}

	// Check for EOF.
	,  := .Read()
	if  != nil {
		return 
	}
	if .Kind() != json.EOF {
		return .unexpectedTokenError()
	}

	if .AllowPartial {
		return nil
	}
	return proto.CheckInitialized()
}

type decoder struct {
	*json.Decoder
	opts UnmarshalOptions
}

// newError returns an error object with position info.
func ( decoder) ( int,  string,  ...interface{}) error {
	,  := .Position()
	 := fmt.Sprintf("(line %d:%d): ", , )
	return errors.New(+, ...)
}

// unexpectedTokenError returns a syntax error for the given unexpected token.
func ( decoder) ( json.Token) error {
	return .syntaxError(.Pos(), "unexpected token %s", .RawString())
}

// syntaxError returns a syntax error for given position.
func ( decoder) ( int,  string,  ...interface{}) error {
	,  := .Position()
	 := fmt.Sprintf("syntax error (line %d:%d): ", , )
	return errors.New(+, ...)
}

// unmarshalMessage unmarshals a message into the given protoreflect.Message.
func ( decoder) ( protoreflect.Message,  bool) error {
	if  := wellKnownTypeUnmarshaler(.Descriptor().FullName());  != nil {
		return (, )
	}

	,  := .Read()
	if  != nil {
		return 
	}
	if .Kind() != json.ObjectOpen {
		return .unexpectedTokenError()
	}

	 := .Descriptor()
	if !flags.ProtoLegacy && messageset.IsMessageSet() {
		return errors.New("no support for proto1 MessageSets")
	}

	var  set.Ints
	var  set.Ints
	 := .Fields()
	for {
		// Read field name.
		,  := .Read()
		if  != nil {
			return 
		}
		switch .Kind() {
		default:
			return .unexpectedTokenError()
		case json.ObjectClose:
			return nil
		case json.Name:
			// Continue below.
		}

		 := .Name()
		// Unmarshaling a non-custom embedded message in Any will contain the
		// JSON field "@type" which should be skipped because it is not a field
		// of the embedded message, but simply an artifact of the Any format.
		if  &&  == "@type" {
			.Read()
			continue
		}

		// Get the FieldDescriptor.
		var  protoreflect.FieldDescriptor
		if strings.HasPrefix(, "[") && strings.HasSuffix(, "]") {
			// Only extension names are in [name] format.
			 := protoreflect.FullName([1 : len()-1])
			,  := .opts.Resolver.FindExtensionByName()
			if  != nil &&  != protoregistry.NotFound {
				return .newError(.Pos(), "unable to resolve %s: %v", .RawString(), )
			}
			if  != nil {
				 = .TypeDescriptor()
				if !.ExtensionRanges().Has(.Number()) || .ContainingMessage().FullName() != .FullName() {
					return .newError(.Pos(), "message %v cannot be extended by %v", .FullName(), .FullName())
				}
			}
		} else {
			// The name can either be the JSON name or the proto field name.
			 = .ByJSONName()
			if  == nil {
				 = .ByTextName()
			}
		}
		if flags.ProtoLegacy {
			if  != nil && .IsWeak() && .Message().IsPlaceholder() {
				 = nil // reset since the weak reference is not linked in
			}
		}

		if  == nil {
			// Field is unknown.
			if .opts.DiscardUnknown {
				if  := .skipJSONValue();  != nil {
					return 
				}
				continue
			}
			return .newError(.Pos(), "unknown field %v", .RawString())
		}

		// Do not allow duplicate fields.
		 := uint64(.Number())
		if .Has() {
			return .newError(.Pos(), "duplicate field %v", .RawString())
		}
		.Set()

		// No need to set values for JSON null unless the field type is
		// google.protobuf.Value or google.protobuf.NullValue.
		if ,  := .Peek(); .Kind() == json.Null && !isKnownValue() && !isNullValue() {
			.Read()
			continue
		}

		switch {
		case .IsList():
			 := .Mutable().List()
			if  := .unmarshalList(, );  != nil {
				return 
			}
		case .IsMap():
			 := .Mutable().Map()
			if  := .unmarshalMap(, );  != nil {
				return 
			}
		default:
			// If field is a oneof, check if it has already been set.
			if  := .ContainingOneof();  != nil {
				 := uint64(.Index())
				if .Has() {
					return .newError(.Pos(), "error parsing %s, oneof %v is already set", .RawString(), .FullName())
				}
				.Set()
			}

			// Required or optional fields.
			if  := .unmarshalSingular(, );  != nil {
				return 
			}
		}
	}
}

func ( protoreflect.FieldDescriptor) bool {
	 := .Message()
	return  != nil && .FullName() == genid.Value_message_fullname
}

func ( protoreflect.FieldDescriptor) bool {
	 := .Enum()
	return  != nil && .FullName() == genid.NullValue_enum_fullname
}

// unmarshalSingular unmarshals to the non-repeated field specified
// by the given FieldDescriptor.
func ( decoder) ( protoreflect.Message,  protoreflect.FieldDescriptor) error {
	var  protoreflect.Value
	var  error
	switch .Kind() {
	case protoreflect.MessageKind, protoreflect.GroupKind:
		 = .NewField()
		 = .unmarshalMessage(.Message(), false)
	default:
		,  = .unmarshalScalar()
	}

	if  != nil {
		return 
	}
	.Set(, )
	return nil
}

// unmarshalScalar unmarshals to a scalar/enum protoreflect.Value specified by
// the given FieldDescriptor.
func ( decoder) ( protoreflect.FieldDescriptor) (protoreflect.Value, error) {
	const  int = 32
	const  int = 64

	,  := .Read()
	if  != nil {
		return protoreflect.Value{}, 
	}

	 := .Kind()
	switch  {
	case protoreflect.BoolKind:
		if .Kind() == json.Bool {
			return protoreflect.ValueOfBool(.Bool()), nil
		}

	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
		if ,  := unmarshalInt(, );  {
			return , nil
		}

	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
		if ,  := unmarshalInt(, );  {
			return , nil
		}

	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
		if ,  := unmarshalUint(, );  {
			return , nil
		}

	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
		if ,  := unmarshalUint(, );  {
			return , nil
		}

	case protoreflect.FloatKind:
		if ,  := unmarshalFloat(, );  {
			return , nil
		}

	case protoreflect.DoubleKind:
		if ,  := unmarshalFloat(, );  {
			return , nil
		}

	case protoreflect.StringKind:
		if .Kind() == json.String {
			return protoreflect.ValueOfString(.ParsedString()), nil
		}

	case protoreflect.BytesKind:
		if ,  := unmarshalBytes();  {
			return , nil
		}

	case protoreflect.EnumKind:
		if ,  := unmarshalEnum(, );  {
			return , nil
		}

	default:
		panic(fmt.Sprintf("unmarshalScalar: invalid scalar kind %v", ))
	}

	return protoreflect.Value{}, .newError(.Pos(), "invalid value for %v type: %v", , .RawString())
}

func ( json.Token,  int) (protoreflect.Value, bool) {
	switch .Kind() {
	case json.Number:
		return getInt(, )

	case json.String:
		// Decode number from string.
		 := strings.TrimSpace(.ParsedString())
		if len() != len(.ParsedString()) {
			return protoreflect.Value{}, false
		}
		 := json.NewDecoder([]byte())
		,  := .Read()
		if  != nil {
			return protoreflect.Value{}, false
		}
		return getInt(, )
	}
	return protoreflect.Value{}, false
}

func ( json.Token,  int) (protoreflect.Value, bool) {
	,  := .Int()
	if ! {
		return protoreflect.Value{}, false
	}
	if  == 32 {
		return protoreflect.ValueOfInt32(int32()), true
	}
	return protoreflect.ValueOfInt64(), true
}

func ( json.Token,  int) (protoreflect.Value, bool) {
	switch .Kind() {
	case json.Number:
		return getUint(, )

	case json.String:
		// Decode number from string.
		 := strings.TrimSpace(.ParsedString())
		if len() != len(.ParsedString()) {
			return protoreflect.Value{}, false
		}
		 := json.NewDecoder([]byte())
		,  := .Read()
		if  != nil {
			return protoreflect.Value{}, false
		}
		return getUint(, )
	}
	return protoreflect.Value{}, false
}

func ( json.Token,  int) (protoreflect.Value, bool) {
	,  := .Uint()
	if ! {
		return protoreflect.Value{}, false
	}
	if  == 32 {
		return protoreflect.ValueOfUint32(uint32()), true
	}
	return protoreflect.ValueOfUint64(), true
}

func ( json.Token,  int) (protoreflect.Value, bool) {
	switch .Kind() {
	case json.Number:
		return getFloat(, )

	case json.String:
		 := .ParsedString()
		switch  {
		case "NaN":
			if  == 32 {
				return protoreflect.ValueOfFloat32(float32(math.NaN())), true
			}
			return protoreflect.ValueOfFloat64(math.NaN()), true
		case "Infinity":
			if  == 32 {
				return protoreflect.ValueOfFloat32(float32(math.Inf(+1))), true
			}
			return protoreflect.ValueOfFloat64(math.Inf(+1)), true
		case "-Infinity":
			if  == 32 {
				return protoreflect.ValueOfFloat32(float32(math.Inf(-1))), true
			}
			return protoreflect.ValueOfFloat64(math.Inf(-1)), true
		}

		// Decode number from string.
		if len() != len(strings.TrimSpace()) {
			return protoreflect.Value{}, false
		}
		 := json.NewDecoder([]byte())
		,  := .Read()
		if  != nil {
			return protoreflect.Value{}, false
		}
		return getFloat(, )
	}
	return protoreflect.Value{}, false
}

func ( json.Token,  int) (protoreflect.Value, bool) {
	,  := .Float()
	if ! {
		return protoreflect.Value{}, false
	}
	if  == 32 {
		return protoreflect.ValueOfFloat32(float32()), true
	}
	return protoreflect.ValueOfFloat64(), true
}

func ( json.Token) (protoreflect.Value, bool) {
	if .Kind() != json.String {
		return protoreflect.Value{}, false
	}

	 := .ParsedString()
	 := base64.StdEncoding
	if strings.ContainsAny(, "-_") {
		 = base64.URLEncoding
	}
	if len()%4 != 0 {
		 = .WithPadding(base64.NoPadding)
	}
	,  := .DecodeString()
	if  != nil {
		return protoreflect.Value{}, false
	}
	return protoreflect.ValueOfBytes(), true
}

func ( json.Token,  protoreflect.FieldDescriptor) (protoreflect.Value, bool) {
	switch .Kind() {
	case json.String:
		// Lookup EnumNumber based on name.
		 := .ParsedString()
		if  := .Enum().Values().ByName(protoreflect.Name());  != nil {
			return protoreflect.ValueOfEnum(.Number()), true
		}

	case json.Number:
		if ,  := .Int(32);  {
			return protoreflect.ValueOfEnum(protoreflect.EnumNumber()), true
		}

	case json.Null:
		// This is only valid for google.protobuf.NullValue.
		if isNullValue() {
			return protoreflect.ValueOfEnum(0), true
		}
	}

	return protoreflect.Value{}, false
}

func ( decoder) ( protoreflect.List,  protoreflect.FieldDescriptor) error {
	,  := .Read()
	if  != nil {
		return 
	}
	if .Kind() != json.ArrayOpen {
		return .unexpectedTokenError()
	}

	switch .Kind() {
	case protoreflect.MessageKind, protoreflect.GroupKind:
		for {
			,  := .Peek()
			if  != nil {
				return 
			}

			if .Kind() == json.ArrayClose {
				.Read()
				return nil
			}

			 := .NewElement()
			if  := .unmarshalMessage(.Message(), false);  != nil {
				return 
			}
			.Append()
		}
	default:
		for {
			,  := .Peek()
			if  != nil {
				return 
			}

			if .Kind() == json.ArrayClose {
				.Read()
				return nil
			}

			,  := .unmarshalScalar()
			if  != nil {
				return 
			}
			.Append()
		}
	}

	return nil
}

func ( decoder) ( protoreflect.Map,  protoreflect.FieldDescriptor) error {
	,  := .Read()
	if  != nil {
		return 
	}
	if .Kind() != json.ObjectOpen {
		return .unexpectedTokenError()
	}

	// Determine ahead whether map entry is a scalar type or a message type in
	// order to call the appropriate unmarshalMapValue func inside the for loop
	// below.
	var  func() (protoreflect.Value, error)
	switch .MapValue().Kind() {
	case protoreflect.MessageKind, protoreflect.GroupKind:
		 = func() (protoreflect.Value, error) {
			 := .NewValue()
			if  := .unmarshalMessage(.Message(), false);  != nil {
				return protoreflect.Value{}, 
			}
			return , nil
		}
	default:
		 = func() (protoreflect.Value, error) {
			return .unmarshalScalar(.MapValue())
		}
	}

:
	for {
		// Read field name.
		,  := .Read()
		if  != nil {
			return 
		}
		switch .Kind() {
		default:
			return .unexpectedTokenError()
		case json.ObjectClose:
			break 
		case json.Name:
			// Continue.
		}

		// Unmarshal field name.
		,  := .unmarshalMapKey(, .MapKey())
		if  != nil {
			return 
		}

		// Check for duplicate field name.
		if .Has() {
			return .newError(.Pos(), "duplicate map key %v", .RawString())
		}

		// Read and unmarshal field value.
		,  := ()
		if  != nil {
			return 
		}

		.Set(, )
	}

	return nil
}

// unmarshalMapKey converts given token of Name kind into a protoreflect.MapKey.
// A map key type is any integral or string type.
func ( decoder) ( json.Token,  protoreflect.FieldDescriptor) (protoreflect.MapKey, error) {
	const  = 32
	const  = 64
	const  = 10

	 := .Name()
	 := .Kind()
	switch  {
	case protoreflect.StringKind:
		return protoreflect.ValueOfString().MapKey(), nil

	case protoreflect.BoolKind:
		switch  {
		case "true":
			return protoreflect.ValueOfBool(true).MapKey(), nil
		case "false":
			return protoreflect.ValueOfBool(false).MapKey(), nil
		}

	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
		if ,  := strconv.ParseInt(, , );  == nil {
			return protoreflect.ValueOfInt32(int32()).MapKey(), nil
		}

	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
		if ,  := strconv.ParseInt(, , );  == nil {
			return protoreflect.ValueOfInt64(int64()).MapKey(), nil
		}

	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
		if ,  := strconv.ParseUint(, , );  == nil {
			return protoreflect.ValueOfUint32(uint32()).MapKey(), nil
		}

	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
		if ,  := strconv.ParseUint(, , );  == nil {
			return protoreflect.ValueOfUint64(uint64()).MapKey(), nil
		}

	default:
		panic(fmt.Sprintf("invalid kind for map key: %v", ))
	}

	return protoreflect.MapKey{}, .newError(.Pos(), "invalid value for %v key: %s", , .RawString())
}