// Copyright 2018 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 proto

import (
	
	
	
	
	
	
	
	
	
)

// UnmarshalOptions configures the unmarshaler.
//
// Example usage:
//
//	err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m)
type UnmarshalOptions struct {
	pragma.NoUnkeyedLiterals

	// Merge merges the input into the destination message.
	// The default behavior is to always reset the message before unmarshaling,
	// unless Merge is specified.
	Merge bool

	// AllowPartial accepts input for messages that will result in missing
	// required fields. If AllowPartial is false (the default), Unmarshal will
	// return an error if there are any missing required fields.
	AllowPartial bool

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

	// Resolver is used for looking up types when unmarshaling extension fields.
	// If nil, this defaults to using protoregistry.GlobalTypes.
	Resolver interface {
		FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
		FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
	}

	// RecursionLimit limits how deeply messages may be nested.
	// If zero, a default limit is applied.
	RecursionLimit int
}

// Unmarshal parses the wire-format message in b and places the result in m.
// The provided message must be mutable (e.g., a non-nil pointer to a message).
func ( []byte,  Message) error {
	,  := UnmarshalOptions{RecursionLimit: protowire.DefaultRecursionLimit}.unmarshal(, .ProtoReflect())
	return 
}

// Unmarshal parses the wire-format message in b and places the result in m.
// The provided message must be mutable (e.g., a non-nil pointer to a message).
func ( UnmarshalOptions) ( []byte,  Message) error {
	if .RecursionLimit == 0 {
		.RecursionLimit = protowire.DefaultRecursionLimit
	}
	,  := .unmarshal(, .ProtoReflect())
	return 
}

// UnmarshalState parses a wire-format message and places the result in m.
//
// This method permits fine-grained control over the unmarshaler.
// Most users should use Unmarshal instead.
func ( UnmarshalOptions) ( protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
	if .RecursionLimit == 0 {
		.RecursionLimit = protowire.DefaultRecursionLimit
	}
	return .unmarshal(.Buf, .Message)
}

// 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,  protoreflect.Message) ( protoiface.UnmarshalOutput,  error) {
	if .Resolver == nil {
		.Resolver = protoregistry.GlobalTypes
	}
	if !.Merge {
		Reset(.Interface())
	}
	 := .AllowPartial
	.Merge = true
	.AllowPartial = true
	 := protoMethods()
	if  != nil && .Unmarshal != nil &&
		!(.DiscardUnknown && .Flags&protoiface.SupportUnmarshalDiscardUnknown == 0) {
		 := protoiface.UnmarshalInput{
			Message:  ,
			Buf:      ,
			Resolver: .Resolver,
			Depth:    .RecursionLimit,
		}
		if .DiscardUnknown {
			.Flags |= protoiface.UnmarshalDiscardUnknown
		}
		,  = .Unmarshal()
	} else {
		.RecursionLimit--
		if .RecursionLimit < 0 {
			return , errors.New("exceeded max recursion depth")
		}
		 = .unmarshalMessageSlow(, )
	}
	if  != nil {
		return , 
	}
	if  || (.Flags&protoiface.UnmarshalInitialized != 0) {
		return , nil
	}
	return , checkInitialized()
}

func ( UnmarshalOptions) ( []byte,  protoreflect.Message) error {
	,  := .unmarshal(, )
	return 
}

func ( UnmarshalOptions) ( []byte,  protoreflect.Message) error {
	 := .Descriptor()
	if messageset.IsMessageSet() {
		return .unmarshalMessageSet(, )
	}
	 := .Fields()
	for len() > 0 {
		// Parse the tag (field number and wire type).
		, ,  := protowire.ConsumeTag()
		if  < 0 {
			return errDecode
		}
		if  > protowire.MaxValidNumber {
			return errDecode
		}

		// Find the field descriptor for this field number.
		 := .ByNumber()
		if  == nil && .ExtensionRanges().Has() {
			,  := .Resolver.FindExtensionByNumber(.FullName(), )
			if  != nil &&  != protoregistry.NotFound {
				return errors.New("%v: unable to resolve extension %v: %v", .FullName(), , )
			}
			if  != nil {
				 = .TypeDescriptor()
			}
		}
		var  error
		if  == nil {
			 = errUnknown
		} else if flags.ProtoLegacy {
			if .IsWeak() && .Message().IsPlaceholder() {
				 = errUnknown // weak referent is not linked in
			}
		}

		// Parse the field value.
		var  int
		switch {
		case  != nil:
		case .IsList():
			,  = .unmarshalList([:], , .Mutable().List(), )
		case .IsMap():
			,  = .unmarshalMap([:], , .Mutable().Map(), )
		default:
			,  = .unmarshalSingular([:], , , )
		}
		if  != nil {
			if  != errUnknown {
				return 
			}
			 = protowire.ConsumeFieldValue(, , [:])
			if  < 0 {
				return errDecode
			}
			if !.DiscardUnknown {
				.SetUnknown(append(.GetUnknown(), [:+]...))
			}
		}
		 = [+:]
	}
	return nil
}

func ( UnmarshalOptions) ( []byte,  protowire.Type,  protoreflect.Message,  protoreflect.FieldDescriptor) ( int,  error) {
	, ,  := .unmarshalScalar(, , )
	if  != nil {
		return 0, 
	}
	switch .Kind() {
	case protoreflect.GroupKind, protoreflect.MessageKind:
		 := .Mutable().Message()
		if  := .unmarshalMessage(.Bytes(), );  != nil {
			return , 
		}
	default:
		// Non-message scalars replace the previous value.
		.Set(, )
	}
	return , nil
}

func ( UnmarshalOptions) ( []byte,  protowire.Type,  protoreflect.Map,  protoreflect.FieldDescriptor) ( int,  error) {
	if  != protowire.BytesType {
		return 0, errUnknown
	}
	,  = protowire.ConsumeBytes()
	if  < 0 {
		return 0, errDecode
	}
	var (
		 = .MapKey()
		 = .MapValue()
		      protoreflect.Value
		      protoreflect.Value
		  bool
		  bool
	)
	switch .Kind() {
	case protoreflect.GroupKind, protoreflect.MessageKind:
		 = .NewValue()
	}
	// Map entries are represented as a two-element message with fields
	// containing the key and value.
	for len() > 0 {
		, ,  := protowire.ConsumeTag()
		if  < 0 {
			return 0, errDecode
		}
		if  > protowire.MaxValidNumber {
			return 0, errDecode
		}
		 = [:]
		 = errUnknown
		switch  {
		case genid.MapEntry_Key_field_number:
			, ,  = .unmarshalScalar(, , )
			if  != nil {
				break
			}
			 = true
		case genid.MapEntry_Value_field_number:
			var  protoreflect.Value
			, ,  = .unmarshalScalar(, , )
			if  != nil {
				break
			}
			switch .Kind() {
			case protoreflect.GroupKind, protoreflect.MessageKind:
				if  := .unmarshalMessage(.Bytes(), .Message());  != nil {
					return 0, 
				}
			default:
				 = 
			}
			 = true
		}
		if  == errUnknown {
			 = protowire.ConsumeFieldValue(, , )
			if  < 0 {
				return 0, errDecode
			}
		} else if  != nil {
			return 0, 
		}
		 = [:]
	}
	// Every map entry should have entries for key and value, but this is not strictly required.
	if ! {
		 = .Default()
	}
	if ! {
		switch .Kind() {
		case protoreflect.GroupKind, protoreflect.MessageKind:
		default:
			 = .Default()
		}
	}
	.Set(.MapKey(), )
	return , nil
}

// errUnknown is used internally to indicate fields which should be added
// to the unknown field set of a message. It is never returned from an exported
// function.
var errUnknown = errors.New("BUG: internal error (unknown)")

var errDecode = errors.New("cannot parse invalid wire-format data")