]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/hcl/hcl/ast/ast.go
Initial transfer of provider code
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / hcl / hcl / ast / ast.go
1 // Package ast declares the types used to represent syntax trees for HCL
2 // (HashiCorp Configuration Language)
3 package ast
4
5 import (
6 "fmt"
7 "strings"
8
9 "github.com/hashicorp/hcl/hcl/token"
10 )
11
12 // Node is an element in the abstract syntax tree.
13 type Node interface {
14 node()
15 Pos() token.Pos
16 }
17
18 func (File) node() {}
19 func (ObjectList) node() {}
20 func (ObjectKey) node() {}
21 func (ObjectItem) node() {}
22 func (Comment) node() {}
23 func (CommentGroup) node() {}
24 func (ObjectType) node() {}
25 func (LiteralType) node() {}
26 func (ListType) node() {}
27
28 // File represents a single HCL file
29 type File struct {
30 Node Node // usually a *ObjectList
31 Comments []*CommentGroup // list of all comments in the source
32 }
33
34 func (f *File) Pos() token.Pos {
35 return f.Node.Pos()
36 }
37
38 // ObjectList represents a list of ObjectItems. An HCL file itself is an
39 // ObjectList.
40 type ObjectList struct {
41 Items []*ObjectItem
42 }
43
44 func (o *ObjectList) Add(item *ObjectItem) {
45 o.Items = append(o.Items, item)
46 }
47
48 // Filter filters out the objects with the given key list as a prefix.
49 //
50 // The returned list of objects contain ObjectItems where the keys have
51 // this prefix already stripped off. This might result in objects with
52 // zero-length key lists if they have no children.
53 //
54 // If no matches are found, an empty ObjectList (non-nil) is returned.
55 func (o *ObjectList) Filter(keys ...string) *ObjectList {
56 var result ObjectList
57 for _, item := range o.Items {
58 // If there aren't enough keys, then ignore this
59 if len(item.Keys) < len(keys) {
60 continue
61 }
62
63 match := true
64 for i, key := range item.Keys[:len(keys)] {
65 key := key.Token.Value().(string)
66 if key != keys[i] && !strings.EqualFold(key, keys[i]) {
67 match = false
68 break
69 }
70 }
71 if !match {
72 continue
73 }
74
75 // Strip off the prefix from the children
76 newItem := *item
77 newItem.Keys = newItem.Keys[len(keys):]
78 result.Add(&newItem)
79 }
80
81 return &result
82 }
83
84 // Children returns further nested objects (key length > 0) within this
85 // ObjectList. This should be used with Filter to get at child items.
86 func (o *ObjectList) Children() *ObjectList {
87 var result ObjectList
88 for _, item := range o.Items {
89 if len(item.Keys) > 0 {
90 result.Add(item)
91 }
92 }
93
94 return &result
95 }
96
97 // Elem returns items in the list that are direct element assignments
98 // (key length == 0). This should be used with Filter to get at elements.
99 func (o *ObjectList) Elem() *ObjectList {
100 var result ObjectList
101 for _, item := range o.Items {
102 if len(item.Keys) == 0 {
103 result.Add(item)
104 }
105 }
106
107 return &result
108 }
109
110 func (o *ObjectList) Pos() token.Pos {
111 // always returns the uninitiliazed position
112 return o.Items[0].Pos()
113 }
114
115 // ObjectItem represents a HCL Object Item. An item is represented with a key
116 // (or keys). It can be an assignment or an object (both normal and nested)
117 type ObjectItem struct {
118 // keys is only one length long if it's of type assignment. If it's a
119 // nested object it can be larger than one. In that case "assign" is
120 // invalid as there is no assignments for a nested object.
121 Keys []*ObjectKey
122
123 // assign contains the position of "=", if any
124 Assign token.Pos
125
126 // val is the item itself. It can be an object,list, number, bool or a
127 // string. If key length is larger than one, val can be only of type
128 // Object.
129 Val Node
130
131 LeadComment *CommentGroup // associated lead comment
132 LineComment *CommentGroup // associated line comment
133 }
134
135 func (o *ObjectItem) Pos() token.Pos {
136 // I'm not entirely sure what causes this, but removing this causes
137 // a test failure. We should investigate at some point.
138 if len(o.Keys) == 0 {
139 return token.Pos{}
140 }
141
142 return o.Keys[0].Pos()
143 }
144
145 // ObjectKeys are either an identifier or of type string.
146 type ObjectKey struct {
147 Token token.Token
148 }
149
150 func (o *ObjectKey) Pos() token.Pos {
151 return o.Token.Pos
152 }
153
154 // LiteralType represents a literal of basic type. Valid types are:
155 // token.NUMBER, token.FLOAT, token.BOOL and token.STRING
156 type LiteralType struct {
157 Token token.Token
158
159 // comment types, only used when in a list
160 LeadComment *CommentGroup
161 LineComment *CommentGroup
162 }
163
164 func (l *LiteralType) Pos() token.Pos {
165 return l.Token.Pos
166 }
167
168 // ListStatement represents a HCL List type
169 type ListType struct {
170 Lbrack token.Pos // position of "["
171 Rbrack token.Pos // position of "]"
172 List []Node // the elements in lexical order
173 }
174
175 func (l *ListType) Pos() token.Pos {
176 return l.Lbrack
177 }
178
179 func (l *ListType) Add(node Node) {
180 l.List = append(l.List, node)
181 }
182
183 // ObjectType represents a HCL Object Type
184 type ObjectType struct {
185 Lbrace token.Pos // position of "{"
186 Rbrace token.Pos // position of "}"
187 List *ObjectList // the nodes in lexical order
188 }
189
190 func (o *ObjectType) Pos() token.Pos {
191 return o.Lbrace
192 }
193
194 // Comment node represents a single //, # style or /*- style commment
195 type Comment struct {
196 Start token.Pos // position of / or #
197 Text string
198 }
199
200 func (c *Comment) Pos() token.Pos {
201 return c.Start
202 }
203
204 // CommentGroup node represents a sequence of comments with no other tokens and
205 // no empty lines between.
206 type CommentGroup struct {
207 List []*Comment // len(List) > 0
208 }
209
210 func (c *CommentGroup) Pos() token.Pos {
211 return c.List[0].Pos()
212 }
213
214 //-------------------------------------------------------------------
215 // GoStringer
216 //-------------------------------------------------------------------
217
218 func (o *ObjectKey) GoString() string { return fmt.Sprintf("*%#v", *o) }
219 func (o *ObjectList) GoString() string { return fmt.Sprintf("*%#v", *o) }