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 (
	
	
	
	
	

	
	
	
	
	
	
	
	
	pref 
	
)
Unmarshal reads the given []byte into the given proto.Message.
func ( []byte,  proto.Message) error {
	return UnmarshalOptions{}.Unmarshal(, )
}
UnmarshalOptions is a configurable JSON format parser.
If AllowPartial is set, input for messages that will result in missing required fields will not return an error.
If DiscardUnknown is set, unknown fields are ignored.
Resolver is used for looking up types when unmarshaling google.protobuf.Any messages or extension fields. If nil, this defaults to using protoregistry.GlobalTypes.
Unmarshal reads the given []byte and populates the given proto.Message using options in UnmarshalOptions object. It will clear the message first before setting the fields. If it returns an error, the given message may be partially set.
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) ( pref.Message,  bool) error {
	if  := wellKnownTypeUnmarshaler(.Descriptor().FullName());  != nil {
		return (, )
	}

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

	if  := .unmarshalFields(, );  != nil {
		return 
	}

	return nil
}
unmarshalFields unmarshals the fields into the given protoreflect.Message.
func ( decoder) ( pref.Message,  bool) error {
	 := .Descriptor()
	if !flags.ProtoLegacy && messageset.IsMessageSet() {
		return errors.New("no support for proto1 MessageSets")
	}

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

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.
Only extension names are in [name] format.
			 := pref.FullName([1 : len()-1])
			,  := .findExtension()
			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())
				}
			}
The name can either be the JSON name or the proto field name.
			 = .ByJSONName()
			if  == nil {
				 = .ByName(pref.Name())
The proto name of a group field is in all lowercase, while the textual field name is the group message name.
					 := .ByName(pref.Name(strings.ToLower()))
					if  != nil && .Kind() == pref.GroupKind && .Message().Name() == pref.Name() {
						 = 
					}
				} else if .Kind() == pref.GroupKind && .Message().Name() != pref.Name() {
					 = nil // reset since field name is actually the message name
				}
			}
		}
		if flags.ProtoLegacy {
			if  != nil && .IsWeak() && .Message().IsPlaceholder() {
				 = nil // reset since the weak reference is not linked in
			}
		}

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 
			}
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 
			}
		}
	}
}
findExtension returns protoreflect.ExtensionType from the resolver if found.
func ( decoder) ( pref.FullName) (pref.ExtensionType, error) {
	,  := .opts.Resolver.FindExtensionByName()
	if  == nil {
		return , nil
	}
	return messageset.FindMessageSetExtension(.opts.Resolver, )
}

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

func ( pref.FieldDescriptor) bool {
	 := .Enum()
	return  != nil && .FullName() == genid.NullValue_enum_fullname
}
unmarshalSingular unmarshals to the non-repeated field specified by the given FieldDescriptor.
func ( decoder) ( pref.Message,  pref.FieldDescriptor) error {
	var  pref.Value
	var  error
	switch .Kind() {
	case pref.MessageKind, pref.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) ( pref.FieldDescriptor) (pref.Value, error) {
	const  int = 32
	const  int = 64

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	case json.String:
		 := .ParsedString()
		switch  {
		case "NaN":
			if  == 32 {
				return pref.ValueOfFloat32(float32(math.NaN())), true
			}
			return pref.ValueOfFloat64(math.NaN()), true
		case "Infinity":
			if  == 32 {
				return pref.ValueOfFloat32(float32(math.Inf(+1))), true
			}
			return pref.ValueOfFloat64(math.Inf(+1)), true
		case "-Infinity":
			if  == 32 {
				return pref.ValueOfFloat32(float32(math.Inf(-1))), true
			}
			return pref.ValueOfFloat64(math.Inf(-1)), true
		}
Decode number from string.
		if len() != len(strings.TrimSpace()) {
			return pref.Value{}, false
		}
		 := json.NewDecoder([]byte())
		,  := .Read()
		if  != nil {
			return pref.Value{}, false
		}
		return getFloat(, )
	}
	return pref.Value{}, false
}

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

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

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

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

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

This is only valid for google.protobuf.NullValue.
		if isNullValue() {
			return pref.ValueOfEnum(0), true
		}
	}

	return pref.Value{}, false
}

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

	switch .Kind() {
	case pref.MessageKind, pref.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) ( pref.Map,  pref.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() (pref.Value, error)
	switch .MapValue().Kind() {
	case pref.MessageKind, pref.GroupKind:
		 = func() (pref.Value, error) {
			 := .NewValue()
			if  := .unmarshalMessage(.Message(), false);  != nil {
				return pref.Value{}, 
			}
			return , nil
		}
	default:
		 = func() (pref.Value, error) {
			return .unmarshalScalar(.MapValue())
		}
	}

:
Read field name.
		,  := .Read()
		if  != nil {
			return 
		}
		switch .Kind() {
		default:
			return .unexpectedTokenError()
		case json.ObjectClose:
			break 
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,  pref.FieldDescriptor) (pref.MapKey, error) {
	const  = 32
	const  = 64
	const  = 10

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

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

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

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

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

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

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

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