terraform/vendor/github.com/hashicorp/hcl2/hclwrite/ast_body.go

134 lines
3.1 KiB
Go

package hclwrite
import (
"github.com/hashicorp/hcl2/hcl"
"github.com/hashicorp/hcl2/hcl/hclsyntax"
"github.com/zclconf/go-cty/cty"
)
type Body struct {
inTree
items nodeSet
}
func (b *Body) appendItem(c nodeContent) *node {
nn := b.children.Append(c)
b.items.Add(nn)
return nn
}
func (b *Body) appendItemNode(nn *node) *node {
nn.assertUnattached()
b.children.AppendNode(nn)
b.items.Add(nn)
return nn
}
func (b *Body) AppendUnstructuredTokens(ts Tokens) {
b.inTree.children.Append(ts)
}
// GetAttribute returns the attribute from the body that has the given name,
// or returns nil if there is currently no matching attribute.
func (b *Body) GetAttribute(name string) *Attribute {
for n := range b.items {
if attr, isAttr := n.content.(*Attribute); isAttr {
nameObj := attr.name.content.(*identifier)
if nameObj.hasName(name) {
// We've found it!
return attr
}
}
}
return nil
}
// SetAttributeValue either replaces the expression of an existing attribute
// of the given name or adds a new attribute definition to the end of the block.
//
// The value is given as a cty.Value, and must therefore be a literal. To set
// a variable reference or other traversal, use SetAttributeTraversal.
//
// The return value is the attribute that was either modified in-place or
// created.
func (b *Body) SetAttributeValue(name string, val cty.Value) *Attribute {
attr := b.GetAttribute(name)
expr := NewExpressionLiteral(val)
if attr != nil {
attr.expr = attr.expr.ReplaceWith(expr)
} else {
attr := newAttribute()
attr.init(name, expr)
b.appendItem(attr)
}
return attr
}
// SetAttributeTraversal either replaces the expression of an existing attribute
// of the given name or adds a new attribute definition to the end of the block.
//
// The new expression is given as a hcl.Traversal, which must be an absolute
// traversal. To set a literal value, use SetAttributeValue.
//
// The return value is the attribute that was either modified in-place or
// created.
func (b *Body) SetAttributeTraversal(name string, traversal hcl.Traversal) *Attribute {
panic("Body.SetAttributeTraversal not yet implemented")
}
type Attribute struct {
inTree
leadComments *node
name *node
expr *node
lineComments *node
}
func newAttribute() *Attribute {
return &Attribute{
inTree: newInTree(),
}
}
func (a *Attribute) init(name string, expr *Expression) {
expr.assertUnattached()
nameTok := newIdentToken(name)
nameObj := newIdentifier(nameTok)
a.leadComments = a.children.Append(newComments(nil))
a.name = a.children.Append(nameObj)
a.children.AppendUnstructuredTokens(Tokens{
{
Type: hclsyntax.TokenEqual,
Bytes: []byte{'='},
},
})
a.expr = a.children.Append(expr)
a.expr.list = a.children
a.lineComments = a.children.Append(newComments(nil))
a.children.AppendUnstructuredTokens(Tokens{
{
Type: hclsyntax.TokenNewline,
Bytes: []byte{'\n'},
},
})
}
func (a *Attribute) Expr() *Expression {
return a.expr.content.(*Expression)
}
type Block struct {
inTree
leadComments *node
typeName *node
labels nodeSet
open *node
body *node
close *node
}