]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/hcl2/hclwrite/ast_body.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / hcl2 / hclwrite / ast_body.go
1 package hclwrite
2
3 import (
4 "github.com/hashicorp/hcl2/hcl"
5 "github.com/hashicorp/hcl2/hcl/hclsyntax"
6 "github.com/zclconf/go-cty/cty"
7 )
8
9 type Body struct {
10 inTree
11
12 items nodeSet
13 }
14
15 func newBody() *Body {
16 return &Body{
17 inTree: newInTree(),
18 items: newNodeSet(),
19 }
20 }
21
22 func (b *Body) appendItem(c nodeContent) *node {
23 nn := b.children.Append(c)
24 b.items.Add(nn)
25 return nn
26 }
27
28 func (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.
36 func (b *Body) Clear() {
37 b.children.Clear()
38 }
39
40 func (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.
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)
52 ret[name] = attr
53 }
54 }
55 return ret
56 }
57
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)
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.
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) {
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.
93 func (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.
114 func (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.
129 func (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.
136 func (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.
146 func (b *Body) AppendNewline() {
147 b.AppendUnstructuredTokens(Tokens{
148 {
149 Type: hclsyntax.TokenNewline,
150 Bytes: []byte{'\n'},
151 },
152 })
153 }