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

	
	
	
)

func ( *MessageInfo) ( protoiface.CheckInitializedInput) (protoiface.CheckInitializedOutput, error) {
	var  pointer
	if ,  := .Message.(*messageState);  {
		 = .pointer()
	} else {
		 = .Message.(*messageReflectWrapper).pointer()
	}
	return protoiface.CheckInitializedOutput{}, .checkInitializedPointer()
}

func ( *MessageInfo) ( pointer) error {
	.init()
	if !.needsInitCheck {
		return nil
	}
	if .IsNil() {
		for ,  := range .orderedCoderFields {
			if .isRequired {
				return errors.RequiredNotSet(string(.Desc.Fields().ByNumber(.num).FullName()))
			}
		}
		return nil
	}
	if .extensionOffset.IsValid() {
		 := .Apply(.extensionOffset).Extensions()
		if  := .isInitExtensions();  != nil {
			return 
		}
	}
	for ,  := range .orderedCoderFields {
		if !.isRequired && .funcs.isInit == nil {
			continue
		}
		 := .Apply(.offset)
		if .isPointer && .Elem().IsNil() {
			if .isRequired {
				return errors.RequiredNotSet(string(.Desc.Fields().ByNumber(.num).FullName()))
			}
			continue
		}
		if .funcs.isInit == nil {
			continue
		}
		if  := .funcs.isInit(, );  != nil {
			return 
		}
	}
	return nil
}

func ( *MessageInfo) ( *map[int32]ExtensionField) error {
	if  == nil {
		return nil
	}
	for ,  := range * {
		 := getExtensionFieldInfo(.Type())
		if .funcs.isInit == nil {
			continue
		}
		 := .Value()
		if !.IsValid() {
			continue
		}
		if  := .funcs.isInit();  != nil {
			return 
		}
	}
	return nil
}

var (
	needsInitCheckMu  sync.Mutex
	needsInitCheckMap sync.Map
)

// needsInitCheck reports whether a message needs to be checked for partial initialization.
//
// It returns true if the message transitively includes any required or extension fields.
func ( protoreflect.MessageDescriptor) bool {
	if ,  := needsInitCheckMap.Load();  {
		if ,  := .(bool);  {
			return 
		}
	}
	needsInitCheckMu.Lock()
	defer needsInitCheckMu.Unlock()
	return needsInitCheckLocked()
}

func ( protoreflect.MessageDescriptor) ( bool) {
	if ,  := needsInitCheckMap.Load();  {
		// If has is true, we've previously determined that this message
		// needs init checks.
		//
		// If has is false, we've previously determined that it can never
		// be uninitialized.
		//
		// If has is not a bool, we've just encountered a cycle in the
		// message graph. In this case, it is safe to return false: If
		// the message does have required fields, we'll detect them later
		// in the graph traversal.
		,  := .(bool)
		return  && 
	}
	needsInitCheckMap.Store(, struct{}{}) // avoid cycles while descending into this message
	defer func() {
		needsInitCheckMap.Store(, )
	}()
	if .RequiredNumbers().Len() > 0 {
		return true
	}
	if .ExtensionRanges().Len() > 0 {
		return true
	}
	for  := 0;  < .Fields().Len(); ++ {
		 := .Fields().Get()
		// Map keys are never messages, so just consider the map value.
		if .IsMap() {
			 = .MapValue()
		}
		 := .Message()
		if  != nil && () {
			return true
		}
	}
	return false
}