package wasm

import (
	
	
	
)

// ImportedFunctions returns the definitions of each imported function.
//
// Note: Unlike ExportedFunctions, there is no unique constraint on imports.
func ( *Module) () ( []api.FunctionDefinition) {
	for  := uint32(0);  < .ImportFunctionCount; ++ {
		 = append(, .FunctionDefinition())
	}
	return
}

// ExportedFunctions returns the definitions of each exported function.
func ( *Module) () map[string]api.FunctionDefinition {
	 := map[string]api.FunctionDefinition{}
	for  := range .ExportSection {
		 := &.ExportSection[]
		if .Type == ExternTypeFunc {
			 := .FunctionDefinition(.Index)
			[.Name] = 
		}
	}
	return 
}

// FunctionDefinition returns the FunctionDefinition for the given `index`.
func ( *Module) ( Index) *FunctionDefinition {
	// TODO: function initialization is lazy, but bulk. Make it per function.
	.buildFunctionDefinitions()
	return &.FunctionDefinitionSection[]
}

// buildFunctionDefinitions generates function metadata that can be parsed from
// the module. This must be called after all validation.
func ( *Module) () {
	.functionDefinitionSectionInitOnce.Do(.buildFunctionDefinitionsOnce)
}

func ( *Module) () {
	var  string
	var  NameMap
	var ,  IndirectNameMap
	if .NameSection != nil {
		 = .NameSection.ModuleName
		 = .NameSection.FunctionNames
		 = .NameSection.LocalNames
		 = .NameSection.ResultNames
	}

	 := .ImportFunctionCount
	.FunctionDefinitionSection = make([]FunctionDefinition, +uint32(len(.FunctionSection)))

	 := Index(0)
	for  := range .ImportSection {
		 := &.ImportSection[]
		if .Type != ExternTypeFunc {
			continue
		}

		 := &.FunctionDefinitionSection[]
		.importDesc = 
		.index = 
		.Functype = &.TypeSection[.DescFunc]
		++
	}

	for ,  := range .FunctionSection {
		 := &.CodeSection[]
		 :=  + Index()
		 := &.FunctionDefinitionSection[]
		.index = 
		.Functype = &.TypeSection[]
		.goFunc = .GoFunc
	}

	,  := 0, len()
	for  := range .FunctionDefinitionSection {
		 := &.FunctionDefinitionSection[]
		// The function name section begins with imports, but can be sparse.
		// This keeps track of how far in the name section we've searched.
		 := .index
		var  string
		for ;  < ; ++ {
			 := &[]
			if .Index >  {
				break // we have function names, but starting at a later index.
			} else if .Index ==  {
				 = .Name
				break
			}
		}

		.moduleName = 
		.name = 
		.Debugname = wasmdebug.FuncName(, , )
		.paramNames = paramNames(, , len(.Functype.Params))
		.resultNames = paramNames(, , len(.Functype.Results))

		for  := range .ExportSection {
			 := &.ExportSection[]
			if .Type == ExternTypeFunc && .Index ==  {
				.exportNames = append(.exportNames, .Name)
			}
		}
	}
}

// FunctionDefinition implements api.FunctionDefinition
type FunctionDefinition struct {
	internalapi.WazeroOnlyType
	moduleName string
	index      Index
	name       string
	// Debugname is exported for testing purpose.
	Debugname string
	goFunc    interface{}
	// Functype is exported for testing purpose.
	Functype    *FunctionType
	importDesc  *Import
	exportNames []string
	paramNames  []string
	resultNames []string
}

// ModuleName implements the same method as documented on api.FunctionDefinition.
func ( *FunctionDefinition) () string {
	return .moduleName
}

// Index implements the same method as documented on api.FunctionDefinition.
func ( *FunctionDefinition) () uint32 {
	return .index
}

// Name implements the same method as documented on api.FunctionDefinition.
func ( *FunctionDefinition) () string {
	return .name
}

// DebugName implements the same method as documented on api.FunctionDefinition.
func ( *FunctionDefinition) () string {
	return .Debugname
}

// Import implements the same method as documented on api.FunctionDefinition.
func ( *FunctionDefinition) () (,  string,  bool) {
	if .importDesc != nil {
		 := .importDesc
		, ,  = .Module, .Name, true
	}
	return
}

// ExportNames implements the same method as documented on api.FunctionDefinition.
func ( *FunctionDefinition) () []string {
	return .exportNames
}

// GoFunction implements the same method as documented on api.FunctionDefinition.
func ( *FunctionDefinition) () interface{} {
	return .goFunc
}

// ParamTypes implements api.FunctionDefinition ParamTypes.
func ( *FunctionDefinition) () []ValueType {
	return .Functype.Params
}

// ParamNames implements the same method as documented on api.FunctionDefinition.
func ( *FunctionDefinition) () []string {
	return .paramNames
}

// ResultTypes implements api.FunctionDefinition ResultTypes.
func ( *FunctionDefinition) () []ValueType {
	return .Functype.Results
}

// ResultNames implements the same method as documented on api.FunctionDefinition.
func ( *FunctionDefinition) () []string {
	return .resultNames
}