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

	"google.golang.org/protobuf/internal/errors"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/runtime/protoiface"
)

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

func (mi *MessageInfo) checkInitializedPointer(p pointer) error {
	mi.init()
	if !mi.needsInitCheck {
		return nil
	}
	if p.IsNil() {
		for _, f := range mi.orderedCoderFields {
			if f.isRequired {
				return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
			}
		}
		return nil
	}

	var presence presence
	if mi.presenceOffset.IsValid() {
		presence = p.Apply(mi.presenceOffset).PresenceInfo()
	}

	if mi.extensionOffset.IsValid() {
		e := p.Apply(mi.extensionOffset).Extensions()
		if err := mi.isInitExtensions(e); err != nil {
			return err
		}
	}
	for _, f := range mi.orderedCoderFields {
		if !f.isRequired && f.funcs.isInit == nil {
			continue
		}

		if f.presenceIndex != noPresence {
			if !presence.Present(f.presenceIndex) {
				if f.isRequired {
					return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
				}
				continue
			}
			if f.funcs.isInit != nil {
				f.mi.init()
				if f.mi.needsInitCheck {
					if f.isLazy && p.Apply(f.offset).AtomicGetPointer().IsNil() {
						lazy := *p.Apply(mi.lazyOffset).LazyInfoPtr()
						if !lazy.AllowedPartial() {
							// Nothing to see here, it was checked on unmarshal
							continue
						}
						mi.lazyUnmarshal(p, f.num)
					}
					if err := f.funcs.isInit(p.Apply(f.offset), f); err != nil {
						return err
					}
				}
			}
			continue
		}

		fptr := p.Apply(f.offset)
		if f.isPointer && fptr.Elem().IsNil() {
			if f.isRequired {
				return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName()))
			}
			continue
		}
		if f.funcs.isInit == nil {
			continue
		}
		if err := f.funcs.isInit(fptr, f); err != nil {
			return err
		}
	}
	return nil
}

func (mi *MessageInfo) isInitExtensions(ext *map[int32]ExtensionField) error {
	if ext == nil {
		return nil
	}
	for _, x := range *ext {
		ei := getExtensionFieldInfo(x.Type())
		if ei.funcs.isInit == nil || x.isUnexpandedLazy() {
			continue
		}
		v := x.Value()
		if !v.IsValid() {
			continue
		}
		if err := ei.funcs.isInit(v); err != nil {
			return err
		}
	}
	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 needsInitCheck(md protoreflect.MessageDescriptor) bool {
	if v, ok := needsInitCheckMap.Load(md); ok {
		if has, ok := v.(bool); ok {
			return has
		}
	}
	needsInitCheckMu.Lock()
	defer needsInitCheckMu.Unlock()
	return needsInitCheckLocked(md)
}

func needsInitCheckLocked(md protoreflect.MessageDescriptor) (has bool) {
	if v, ok := needsInitCheckMap.Load(md); ok {
		// 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.
		has, ok := v.(bool)
		return ok && has
	}
	needsInitCheckMap.Store(md, struct{}{}) // avoid cycles while descending into this message
	defer func() {
		needsInitCheckMap.Store(md, has)
	}()
	if md.RequiredNumbers().Len() > 0 {
		return true
	}
	if md.ExtensionRanges().Len() > 0 {
		return true
	}
	for i := 0; i < md.Fields().Len(); i++ {
		fd := md.Fields().Get(i)
		// Map keys are never messages, so just consider the map value.
		if fd.IsMap() {
			fd = fd.MapValue()
		}
		fmd := fd.Message()
		if fmd != nil && needsInitCheckLocked(fmd) {
			return true
		}
	}
	return false
}
