in internal/langserver/handlers/complete/complete.go [18:82]
func CandidatesAtPos(data []byte, filename string, pos hcl.Pos, logger *log.Logger) []lsp.CompletionItem {
file, _ := hclsyntax.ParseConfig(data, filename, hcl.InitialPos)
body, isHcl := file.Body.(*hclsyntax.Body)
if !isHcl {
logger.Printf("file is not hcl")
return nil
}
block := parser.BlockAtPos(body, pos)
candidateList := make([]lsp.CompletionItem, 0)
if block != nil && len(block.Labels) != 0 && strings.HasPrefix(block.Labels[0], "azapi") {
resourceName := fmt.Sprintf("%s.%s", block.Type, block.Labels[0])
resource := tfschema.GetResourceSchema(resourceName)
if resource == nil {
return candidateList
}
if attribute := parser.AttributeAtPos(block, pos); attribute != nil {
property := resource.GetProperty(attribute.Name)
if property != nil {
if property.GenericCandidatesFunc != nil {
candidateList = append(candidateList, property.GenericCandidatesFunc(data, filename, block, attribute, pos, property)...)
} else if property.ValueCandidatesFunc != nil {
prefix := parser.ToLiteral(attribute.Expr)
candidateList = append(candidateList, property.ValueCandidatesFunc(prefix, editRangeFromExprRange(attribute.Expr, pos))...)
}
}
} else {
if subBody := parser.BlockAtPos(block.Body, pos); subBody != nil {
property := resource.GetProperty(subBody.Type)
if property == nil {
return nil
}
if attribute := parser.AttributeAtPos(subBody, pos); attribute != nil {
for _, p := range property.NestedProperties {
if p.Name == attribute.Name && p.ValueCandidatesFunc != nil {
candidateList = append(candidateList, p.ValueCandidatesFunc(nil, editRangeFromExprRange(attribute.Expr, pos))...)
break
}
}
}
} else {
//input a top level property
editRange := lsp.Range{
Start: ilsp.HCLPosToLSP(pos),
End: ilsp.HCLPosToLSP(pos),
}
editRange.Start.Character = 2
candidateList = append(candidateList, tfschema.PropertiesCandidates(resource.Properties, editRange)...)
candidateList = append(candidateList, snippets.CodeSampleCandidates(block, editRange)...)
}
}
}
// the cursor is not in a block
if block == nil {
editRange := lsp.Range{
Start: ilsp.HCLPosToLSP(pos),
End: ilsp.HCLPosToLSP(pos),
}
editRange.Start.Character = 0
candidateList = append(candidateList, snippets.TemplateCandidates(editRange)...)
}
sort.Slice(candidateList, func(i, j int) bool { return candidateList[i].SortText < candidateList[j].SortText })
return candidateList
}