ed7453e277
This is a straightforward way to get a hclpack.Body in the common case where the input is already native syntax source code. Since the native syntax is unambiguous about structure, the whole structure can be packed in a single pass with no further information.
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
package hclpack
|
|
|
|
import (
|
|
"github.com/hashicorp/hcl2/hcl"
|
|
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
|
)
|
|
|
|
// PackNativeFile parses the given source code as HCL native syntax and packs
|
|
// it into a hclpack Body ready to be marshalled.
|
|
//
|
|
// If the given source code contains syntax errors then error diagnostics will
|
|
// be returned. A non-nil body might still be returned in this case, which
|
|
// allows a cautious caller to still do certain analyses on the result.
|
|
func PackNativeFile(src []byte, filename string, start hcl.Pos) (*Body, hcl.Diagnostics) {
|
|
f, diags := hclsyntax.ParseConfig(src, filename, start)
|
|
rootBody := f.Body.(*hclsyntax.Body)
|
|
return packNativeBody(rootBody, src), diags
|
|
}
|
|
|
|
func packNativeBody(body *hclsyntax.Body, src []byte) *Body {
|
|
ret := &Body{}
|
|
for name, attr := range body.Attributes {
|
|
exprRng := attr.Expr.Range()
|
|
exprStartRng := attr.Expr.StartRange()
|
|
exprSrc := exprRng.SliceBytes(src)
|
|
ret.setAttribute(name, Attribute{
|
|
Expr: Expression{
|
|
Source: exprSrc,
|
|
SourceType: ExprNative,
|
|
|
|
Range_: exprRng,
|
|
StartRange_: exprStartRng,
|
|
},
|
|
Range: attr.Range(),
|
|
NameRange: attr.NameRange,
|
|
})
|
|
}
|
|
|
|
for _, block := range body.Blocks {
|
|
childBody := packNativeBody(block.Body, src)
|
|
defRange := block.TypeRange
|
|
if len(block.LabelRanges) > 0 {
|
|
defRange = hcl.RangeBetween(defRange, block.LabelRanges[len(block.LabelRanges)-1])
|
|
}
|
|
ret.appendBlock(Block{
|
|
Type: block.Type,
|
|
Labels: block.Labels,
|
|
Body: *childBody,
|
|
TypeRange: block.TypeRange,
|
|
DefRange: defRange,
|
|
LabelRanges: block.LabelRanges,
|
|
})
|
|
}
|
|
|
|
ret.MissingItemRange_ = body.EndRange
|
|
|
|
return ret
|
|
}
|