func parseSnippet()

in internal/langserver/handlers/snippets/snippets_gen.go [13:101]


func parseSnippet(filepath string) (*Snippet, error) {
	// #nosec G304
	data, err := os.ReadFile(filepath)
	if err != nil {
		return nil, err
	}
	file, diags := hclsyntax.ParseConfig(data, filepath, hcl.InitialPos)
	if diags.HasErrors() {
		return nil, diags
	}

	blocks := file.Body.(*hclsyntax.Body).Blocks
	if len(blocks) == 0 {
		return nil, fmt.Errorf("no block found in %s", filepath)
	}

	addrTypeMap := make(map[string]string)
	for _, block := range blocks {
		if block.Type == "resource" || block.Type == "data" {
			typeValue := ""
			for _, attr := range block.Body.Attributes {
				if attr.Name == "type" {
					typeValue = strings.Trim(stringValue(data, attr.Expr.Range()), `"`)
					break
				}
			}
			addr := strings.Join(block.Labels, ".")
			if block.Type == "data" {
				addr = "data." + addr
			}
			addrTypeMap[addr] = typeValue
		}
	}

	lastBlock := blocks[len(blocks)-1]
	if lastBlock.Labels[0] != "azapi_resource" {
		// skip non azapi_resource block
		return nil, nil
	}
	typeValue := ""
	fields := make([]Field, 0)
	index := 1
	for _, attr := range lastBlock.Body.Attributes {
		if attr.Name == "type" {
			typeValue = strings.Trim(stringValue(data, attr.Expr.Range()), `"`)
		}
		value := stringValue(data, attr.Range())
		vars := attr.Expr.Variables()
		for _, variable := range vars {
			rawContent := stringValue(data, variable.SourceRange())
			placeholder := placeholderContent(rawContent, addrTypeMap)
			format := `${%d:"%s"}`
			if attr.Name == "name" || attr.Name == "location" {
				format = `"${%d:%s}"`
			}
			value = strings.ReplaceAll(value, rawContent, fmt.Sprintf(format, index, placeholder))
			index++
		}
		fields = append(fields, Field{
			Name:  attr.Name,
			Value: value,
		})
	}
	for _, block := range lastBlock.Body.Blocks {
		value := stringValue(data, block.Range())
		for _, attr := range block.Body.Attributes {
			vars := attr.Expr.Variables()
			for _, variable := range vars {
				rawContent := stringValue(data, variable.SourceRange())
				placeholder := placeholderContent(rawContent, addrTypeMap)
				value = strings.ReplaceAll(value, rawContent, fmt.Sprintf("${%d:%s}", index, placeholder))
				index++
			}
		}
		fields = append(fields, Field{
			Name:  block.Type,
			Value: value,
		})
	}

	slices.SortFunc(fields, func(i, j Field) int {
		return i.Order() - j.Order()
	})

	return &Snippet{
		AzureResourceType: parseResourceType(typeValue),
		Fields:            fields,
	}, nil
}