4 "github.com/hashicorp/hcl2/hcl"
5 "github.com/hashicorp/hcl2/hcl/hclsyntax"
6 "github.com/zclconf/go-cty/cty"
15 func newBody() *Body {
22 func (b *Body) appendItem(c nodeContent) *node {
23 nn := b.children.Append(c)
28 func (b *Body) appendItemNode(nn *node) *node {
30 b.children.AppendNode(nn)
35 // Clear removes all of the items from the body, making it empty.
36 func (b *Body) Clear() {
40 func (b *Body) AppendUnstructuredTokens(ts Tokens) {
41 b.inTree.children.Append(ts)
44 // Attributes returns a new map of all of the attributes in the body, with
45 // the attribute names as the keys.
46 func (b *Body) Attributes() map[string]*Attribute {
47 ret := make(map[string]*Attribute)
48 for n := range b.items {
49 if attr, isAttr := n.content.(*Attribute); isAttr {
50 nameObj := attr.name.content.(*identifier)
51 name := string(nameObj.token.Bytes)
58 // Blocks returns a new slice of all the blocks in the body.
59 func (b *Body) Blocks() []*Block {
60 ret := make([]*Block, 0, len(b.items))
61 for n := range b.items {
62 if block, isBlock := n.content.(*Block); isBlock {
63 ret = append(ret, block)
69 // GetAttribute returns the attribute from the body that has the given name,
70 // or returns nil if there is currently no matching attribute.
71 func (b *Body) GetAttribute(name string) *Attribute {
72 for n := range b.items {
73 if attr, isAttr := n.content.(*Attribute); isAttr {
74 nameObj := attr.name.content.(*identifier)
75 if nameObj.hasName(name) {
85 // SetAttributeValue either replaces the expression of an existing attribute
86 // of the given name or adds a new attribute definition to the end of the block.
88 // The value is given as a cty.Value, and must therefore be a literal. To set
89 // a variable reference or other traversal, use SetAttributeTraversal.
91 // The return value is the attribute that was either modified in-place or
93 func (b *Body) SetAttributeValue(name string, val cty.Value) *Attribute {
94 attr := b.GetAttribute(name)
95 expr := NewExpressionLiteral(val)
97 attr.expr = attr.expr.ReplaceWith(expr)
99 attr := newAttribute()
100 attr.init(name, expr)
106 // SetAttributeTraversal either replaces the expression of an existing attribute
107 // of the given name or adds a new attribute definition to the end of the body.
109 // The new expression is given as a hcl.Traversal, which must be an absolute
110 // traversal. To set a literal value, use SetAttributeValue.
112 // The return value is the attribute that was either modified in-place or
114 func (b *Body) SetAttributeTraversal(name string, traversal hcl.Traversal) *Attribute {
115 attr := b.GetAttribute(name)
116 expr := NewExpressionAbsTraversal(traversal)
118 attr.expr = attr.expr.ReplaceWith(expr)
120 attr := newAttribute()
121 attr.init(name, expr)
127 // AppendBlock appends an existing block (which must not be already attached
128 // to a body) to the end of the receiving body.
129 func (b *Body) AppendBlock(block *Block) *Block {
134 // AppendNewBlock appends a new nested block to the end of the receiving body
135 // with the given type name and labels.
136 func (b *Body) AppendNewBlock(typeName string, labels []string) *Block {
138 block.init(typeName, labels)
143 // AppendNewline appends a newline token to th end of the receiving body,
144 // which generally serves as a separator between different sets of body
146 func (b *Body) AppendNewline() {
147 b.AppendUnstructuredTokens(Tokens{
149 Type: hclsyntax.TokenNewline,