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 (
	

	
	pref 
	piface 
)

func ( *MessageInfo) ( piface.CheckInitializedInput) (piface.CheckInitializedOutput, error) {
	var  pointer
	if ,  := .Message.(*messageState);  {
		 = .pointer()
	} else {
		 = .Message.(*messageReflectWrapper).pointer()
	}
	return piface.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 ( pref.MessageDescriptor) bool {
	if ,  := needsInitCheckMap.Load();  {
		if ,  := .(bool);  {
			return 
		}
	}
	needsInitCheckMu.Lock()
	defer needsInitCheckMu.Unlock()
	return needsInitCheckLocked()
}

func ( pref.MessageDescriptor) ( bool) {
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(); ++ {
Map keys are never messages, so just consider the map value.
		if .IsMap() {
			 = .MapValue()
		}
		 := .Message()
		if  != nil && () {
			return true
		}
	}
	return false