aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/hcl2/hclwrite/ast_body.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/hcl2/hclwrite/ast_body.go')
-rw-r--r--vendor/github.com/hashicorp/hcl2/hclwrite/ast_body.go153
1 files changed, 153 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hcl2/hclwrite/ast_body.go b/vendor/github.com/hashicorp/hcl2/hclwrite/ast_body.go
new file mode 100644
index 0000000..cf69fee
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl2/hclwrite/ast_body.go
@@ -0,0 +1,153 @@
1package hclwrite
2
3import (
4 "github.com/hashicorp/hcl2/hcl"
5 "github.com/hashicorp/hcl2/hcl/hclsyntax"
6 "github.com/zclconf/go-cty/cty"
7)
8
9type Body struct {
10 inTree
11
12 items nodeSet
13}
14
15func newBody() *Body {
16 return &Body{
17 inTree: newInTree(),
18 items: newNodeSet(),
19 }
20}
21
22func (b *Body) appendItem(c nodeContent) *node {
23 nn := b.children.Append(c)
24 b.items.Add(nn)
25 return nn
26}
27
28func (b *Body) appendItemNode(nn *node) *node {
29 nn.assertUnattached()
30 b.children.AppendNode(nn)
31 b.items.Add(nn)
32 return nn
33}
34
35// Clear removes all of the items from the body, making it empty.
36func (b *Body) Clear() {
37 b.children.Clear()
38}
39
40func (b *Body) AppendUnstructuredTokens(ts Tokens) {
41 b.inTree.children.Append(ts)
42}
43
44// Attributes returns a new map of all of the attributes in the body, with
45// the attribute names as the keys.
46func (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)
52 ret[name] = attr
53 }
54 }
55 return ret
56}
57
58// Blocks returns a new slice of all the blocks in the body.
59func (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)
64 }
65 }
66 return ret
67}
68
69// GetAttribute returns the attribute from the body that has the given name,
70// or returns nil if there is currently no matching attribute.
71func (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) {
76 // We've found it!
77 return attr
78 }
79 }
80 }
81
82 return nil
83}
84
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.
87//
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.
90//
91// The return value is the attribute that was either modified in-place or
92// created.
93func (b *Body) SetAttributeValue(name string, val cty.Value) *Attribute {
94 attr := b.GetAttribute(name)
95 expr := NewExpressionLiteral(val)
96 if attr != nil {
97 attr.expr = attr.expr.ReplaceWith(expr)
98 } else {
99 attr := newAttribute()
100 attr.init(name, expr)
101 b.appendItem(attr)
102 }
103 return attr
104}
105
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.
108//
109// The new expression is given as a hcl.Traversal, which must be an absolute
110// traversal. To set a literal value, use SetAttributeValue.
111//
112// The return value is the attribute that was either modified in-place or
113// created.
114func (b *Body) SetAttributeTraversal(name string, traversal hcl.Traversal) *Attribute {
115 attr := b.GetAttribute(name)
116 expr := NewExpressionAbsTraversal(traversal)
117 if attr != nil {
118 attr.expr = attr.expr.ReplaceWith(expr)
119 } else {
120 attr := newAttribute()
121 attr.init(name, expr)
122 b.appendItem(attr)
123 }
124 return attr
125}
126
127// AppendBlock appends an existing block (which must not be already attached
128// to a body) to the end of the receiving body.
129func (b *Body) AppendBlock(block *Block) *Block {
130 b.appendItem(block)
131 return block
132}
133
134// AppendNewBlock appends a new nested block to the end of the receiving body
135// with the given type name and labels.
136func (b *Body) AppendNewBlock(typeName string, labels []string) *Block {
137 block := newBlock()
138 block.init(typeName, labels)
139 b.appendItem(block)
140 return block
141}
142
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
145// contents.
146func (b *Body) AppendNewline() {
147 b.AppendUnstructuredTokens(Tokens{
148 {
149 Type: hclsyntax.TokenNewline,
150 Bytes: []byte{'\n'},
151 },
152 })
153}