func (self *InheritField) InheritEntity() {
	if self.Field.IsNil() && !self.FromField.IsNil() {
		self.Field.Set(self.FromField)
	}
}
Field is compatible with *interface{}
package parser
import (
	"fmt"
	"reflect"
	"strings"
	"github.com/tliron/kutil/reflection"
	"github.com/tliron/kutil/util"
	"github.com/tliron/puccini/tosca"
)
func (self *Context) GetInheritTasks() Tasks {
	inheritContext := NewInheritContext()
	self.Traverse(logInheritance, func(entityPtr tosca.EntityPtr) bool {
		inheritContext.GetInheritTask(entityPtr)
		return true
	})
	return inheritContext.Tasks
}
type InheritContext struct {
	Tasks            Tasks
	TasksForEntities TasksForEntities
	InheritFields    InheritFields
}
func NewInheritContext() *InheritContext {
	return &InheritContext{make(Tasks), make(TasksForEntities), make(InheritFields)}
}
func (self *InheritContext) GetInheritTask(entityPtr tosca.EntityPtr) *Task {
	task, ok := self.TasksForEntities[entityPtr]
	if !ok {
		path := tosca.GetContext(entityPtr).Path.String()
		if path == "" {
			path = "<root>"
		}
		task = NewTask(path)
		self.Tasks.Add(task)
		self.TasksForEntities[entityPtr] = task
		for dependencyEntityPtr := range self.GetDependencies(entityPtr) {
			task.AddDependency(self.GetInheritTask(dependencyEntityPtr))
		}
		task.Executor = self.NewExecutor(entityPtr)
		logInheritance.Debugf("new task: %s (%d)", task.Name, len(task.Dependencies))
	} else {
		logInheritance.Debugf("task cache hit: %s (%d)", task.Name, len(task.Dependencies))
	}
	return task
}
func (self *InheritContext) NewExecutor(entityPtr tosca.EntityPtr) Executor {
	return func(task *Task) {
		defer task.Done()
		logInheritance.Debugf("task: %s", task.Name)
		lock := util.GetLock(entityPtr)
		lock.Lock()
		defer lock.Unlock()
		for _, inheritField := range self.InheritFields.Get(entityPtr) {
			inheritField.Inherit()
		}
		if inherits, ok := entityPtr.(tosca.Inherits); ok {
			inherits.Inherit()
		}
	}
}
func (self *InheritContext) GetDependencies(entityPtr tosca.EntityPtr) map[tosca.EntityPtr]bool {
	dependencies := make(map[tosca.EntityPtr]bool)
	for _, inheritField := range self.InheritFields.Get(entityPtr) {
		dependencies[inheritField.FromEntityPtr] = true
	}
	entity := reflect.ValueOf(entityPtr).Elem()
	for _, structField := range reflection.GetStructFields(entity.Type()) {
		if reflection.IsMapOfStringToPtrToStruct(structField.Type) {
			field := entity.FieldByName(structField.Name)
			for _, mapKey := range field.MapKeys() {
				element := field.MapIndex(mapKey)
				dependencies[element.Interface()] = true
			}
		} else if reflection.IsSliceOfPtrToStruct(structField.Type) {
			field := entity.FieldByName(structField.Name)
			length := field.Len()
			for i := 0; i < length; i++ {
				element := field.Index(i)
				dependencies[element.Interface()] = true
			}
		}
	}
	return dependencies
}
type InheritField struct {
	Entity        reflect.Value
	FromEntityPtr tosca.EntityPtr
	Key           string
	Field         reflect.Value
	FromField     reflect.Value
}
func (self *InheritField) Inherit() {
	fieldEntityPtr := self.Field.Interface()
	if reflection.IsPtrToString(fieldEntityPtr) {
		self.InheritEntity()
	} else if reflection.IsPtrToInt64(fieldEntityPtr) {
		self.InheritEntity()
	} else if reflection.IsPtrToBool(fieldEntityPtr) {
		self.InheritEntity()
	} else if reflection.IsPtrToSliceOfString(fieldEntityPtr) {
		self.InheritStringsFromSlice()
	} else if reflection.IsPtrToMapOfStringToString(fieldEntityPtr) {
		self.InheritStringsFromMap()
	} else {
		fieldType := self.Field.Type()
		if reflection.IsPtrToStruct(fieldType) {
			self.InheritEntity()
		} else if reflection.IsSliceOfPtrToStruct(fieldType) {
			self.InheritStructsFromSlice()
		} else if reflection.IsMapOfStringToPtrToStruct(fieldType) {
			self.InheritStructsFromMap()
		} else {
			panic(fmt.Sprintf("\"inherit\" tag's field type %q is not supported in struct: %T", fieldType, self.Entity.Interface()))
		}
	}
}