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 impl

import (
	

	
	
	
	
	
	preg 
	
	piface 
)

type unmarshalOptions struct {
	flags    protoiface.UnmarshalInputFlags
	resolver interface {
		FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
		FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
	}
}

func ( unmarshalOptions) () proto.UnmarshalOptions {
	return proto.UnmarshalOptions{
		Merge:          true,
		AllowPartial:   true,
		DiscardUnknown: .DiscardUnknown(),
		Resolver:       .resolver,
	}
}

func ( unmarshalOptions) () bool { return .flags&piface.UnmarshalDiscardUnknown != 0 }

func ( unmarshalOptions) () bool {
	return .flags == 0 && .resolver == preg.GlobalTypes
}

var lazyUnmarshalOptions = unmarshalOptions{
	resolver: preg.GlobalTypes,
}

type unmarshalOutput struct {
	n           int // number of bytes consumed
	initialized bool
}
unmarshal is protoreflect.Methods.Unmarshal.
func ( *MessageInfo) ( piface.UnmarshalInput) (piface.UnmarshalOutput, error) {
	var  pointer
	if ,  := .Message.(*messageState);  {
		 = .pointer()
	} else {
		 = .Message.(*messageReflectWrapper).pointer()
	}
	,  := .unmarshalPointer(.Buf, , 0, unmarshalOptions{
		flags:    .Flags,
		resolver: .Resolver,
	})
	var  piface.UnmarshalOutputFlags
	if .initialized {
		 |= piface.UnmarshalInitialized
	}
	return piface.UnmarshalOutput{
		Flags: ,
	}, 
}
errUnknown is returned during unmarshaling to indicate a parse error that should result in a field being placed in the unknown fields section (for example, when the wire type doesn't match) as opposed to the entire unmarshal operation failing (for example, when a field extends past the available input). This is a sentinel error which should never be visible to the user.
var errUnknown = errors.New("unknown")

func ( *MessageInfo) ( []byte,  pointer,  protowire.Number,  unmarshalOptions) ( unmarshalOutput,  error) {
	.init()
	if flags.ProtoLegacy && .isMessageSet {
		return unmarshalMessageSet(, , , )
	}
	 := true
	var  uint64
	var  *map[int32]ExtensionField
	 := len()
Parse the tag (field number and wire type).
		var  uint64
		if [0] < 0x80 {
			 = uint64([0])
			 = [1:]
		} else if len() >= 2 && [1] < 128 {
			 = uint64([0]&0x7f) + uint64([1])<<7
			 = [2:]
		} else {
			var  int
			,  = protowire.ConsumeVarint()
			if  < 0 {
				return , protowire.ParseError()
			}
			 = [:]
		}
		var  protowire.Number
		if  :=  >> 3;  < uint64(protowire.MinValidNumber) ||  > uint64(protowire.MaxValidNumber) {
			return , errors.New("invalid field number")
		} else {
			 = protowire.Number()
		}
		 := protowire.Type( & 7)

		if  == protowire.EndGroupType {
			if  !=  {
				return , errors.New("mismatching end group marker")
			}
			 = 0
			break
		}

		var  *coderFieldInfo
		if int() < len(.denseCoderFields) {
			 = .denseCoderFields[]
		} else {
			 = .coderFields[]
		}
		var  int
		 := errUnknown
		switch {
		case  != nil:
			if .funcs.unmarshal == nil {
				break
			}
			var  unmarshalOutput
			,  = .funcs.unmarshal(, .Apply(.offset), , , )
			 = .n
			if  != nil {
				break
			}
			 |= .validation.requiredBit
			if .funcs.isInit != nil && !.initialized {
				 = false
			}
Possible extension.
			if  == nil && .extensionOffset.IsValid() {
				 = .Apply(.extensionOffset).Extensions()
				if * == nil {
					* = make(map[int32]ExtensionField)
				}
			}
			if  == nil {
				break
			}
			var  unmarshalOutput
			,  = .unmarshalExtension(, , , *, )
			if  != nil {
				break
			}
			 = .n
			if !.initialized {
				 = false
			}
		}
		if  != nil {
			if  != errUnknown {
				return , 
			}
			 = protowire.ConsumeFieldValue(, , )
			if  < 0 {
				return , protowire.ParseError()
			}
			if !.DiscardUnknown() && .unknownOffset.IsValid() {
				 := .Apply(.unknownOffset).Bytes()
				* = protowire.AppendTag(*, , )
				* = append(*, [:]...)
			}
		}
		 = [:]
	}
	if  != 0 {
		return , errors.New("missing end group marker")
	}
	if .numRequiredFields > 0 && bits.OnesCount64() != int(.numRequiredFields) {
		 = false
	}
	if  {
		.initialized = true
	}
	.n =  - len()
	return , nil
}

func ( *MessageInfo) ( []byte,  protowire.Number,  protowire.Type,  map[int32]ExtensionField,  unmarshalOptions) ( unmarshalOutput,  error) {
	 := [int32()]
	 := .Type()
	if  == nil {
		var  error
		,  = .resolver.FindExtensionByNumber(.Desc.FullName(), )
		if  != nil {
			if  == preg.NotFound {
				return , errUnknown
			}
			return , errors.New("%v: unable to resolve extension %v: %v", .Desc.FullName(), , )
		}
	}
	 := getExtensionFieldInfo()
	if .funcs.unmarshal == nil {
		return , errUnknown
	}
	if flags.LazyUnmarshalExtensions {
		if .IsDefault() && .canLazy() {
			,  := skipExtension(, , , , )
			switch  {
			case ValidationValid:
				if .initialized {
					.appendLazyBytes(, , , , [:.n])
					[int32()] = 
					return , nil
				}
			case ValidationInvalid:
				return , errors.New("invalid wire format")
			case ValidationUnknown:
			}
		}
	}
	 := .Value()
Create a new message, list, or map value to fill in. For enums, create a prototype value to let the unmarshal func know the concrete type.
		 = .New()
	}
	, ,  := .funcs.unmarshal(, , , , )
	if  != nil {
		return , 
	}
	if .funcs.isInit == nil {
		.initialized = true
	}
	.Set(, )
	[int32()] = 
	return , nil
}

func ( []byte,  *extensionFieldInfo,  protowire.Number,  protowire.Type,  unmarshalOptions) ( unmarshalOutput,  ValidationStatus) {
	if .validation.mi == nil {
		return , ValidationUnknown
	}
	.validation.mi.init()
	switch .validation.typ {
	case validationTypeMessage:
		if  != protowire.BytesType {
			return , ValidationUnknown
		}
		,  := protowire.ConsumeBytes()
		if  < 0 {
			return , ValidationUnknown
		}
		,  := .validation.mi.validate(, 0, )
		.n = 
		return , 
	case validationTypeGroup:
		if  != protowire.StartGroupType {
			return , ValidationUnknown
		}
		,  := .validation.mi.validate(, , )
		return , 
	default:
		return , ValidationUnknown
	}