Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/river/ast/ast.go
4096 views
1
// Package ast exposes AST elements used by River.
2
//
3
// The various interfaces exposed by ast are all closed; only types within this
4
// package can satisfy an AST interface.
5
package ast
6
7
import (
8
"fmt"
9
"reflect"
10
"strings"
11
12
"github.com/grafana/agent/pkg/river/token"
13
)
14
15
// Node represents any node in the AST.
16
type Node interface {
17
astNode()
18
}
19
20
// Stmt is a type of statement within the body of a file or block.
21
type Stmt interface {
22
Node
23
astStmt()
24
}
25
26
// Expr is an expression within the AST.
27
type Expr interface {
28
Node
29
astExpr()
30
}
31
32
// File is a parsed file.
33
type File struct {
34
Name string // Filename provided to parser
35
Body Body // Content of File
36
Comments []CommentGroup // List of all comments in the File
37
}
38
39
// Body is a list of statements.
40
type Body []Stmt
41
42
// A CommentGroup represents a sequence of comments that are not separated by
43
// any empty lines or other non-comment tokens.
44
type CommentGroup []*Comment
45
46
// A Comment represents a single line or block comment.
47
//
48
// The Text field contains the comment text without any carriage returns (\r)
49
// that may have been present in the source. Since carriage returns get
50
// removed, EndPos will not be accurate for any comment which contained
51
// carriage returns.
52
type Comment struct {
53
StartPos token.Pos // Starting position of comment
54
// Text of the comment. Text will not contain '\n' for line comments.
55
Text string
56
}
57
58
// AttributeStmt is a key-value pair being set in a Body or BlockStmt.
59
type AttributeStmt struct {
60
Name *Ident
61
Value Expr
62
}
63
64
// BlockStmt declares a block.
65
type BlockStmt struct {
66
Name []string
67
NamePos token.Pos
68
Label string
69
LabelPos token.Pos
70
Body Body
71
72
LCurlyPos, RCurlyPos token.Pos
73
}
74
75
// Ident holds an identifier with its position.
76
type Ident struct {
77
Name string
78
NamePos token.Pos
79
}
80
81
// IdentifierExpr refers to a named value.
82
type IdentifierExpr struct {
83
Ident *Ident
84
}
85
86
// LiteralExpr is a constant value of a specific token kind.
87
type LiteralExpr struct {
88
Kind token.Token
89
ValuePos token.Pos
90
91
// Value holds the unparsed literal value. For example, if Kind ==
92
// token.STRING, then Value would be wrapped in the original quotes (e.g.,
93
// `"foobar"`).
94
Value string
95
}
96
97
// ArrayExpr is an array of values.
98
type ArrayExpr struct {
99
Elements []Expr
100
LBrackPos, RBrackPos token.Pos
101
}
102
103
// ObjectExpr declares an object of key-value pairs.
104
type ObjectExpr struct {
105
Fields []*ObjectField
106
LCurlyPos, RCurlyPos token.Pos
107
}
108
109
// ObjectField defines an individual key-value pair within an object.
110
// ObjectField does not implement Node.
111
type ObjectField struct {
112
Name *Ident
113
Quoted bool // True if the name was wrapped in quotes
114
Value Expr
115
}
116
117
// AccessExpr accesses a field in an object value by name.
118
type AccessExpr struct {
119
Value Expr
120
Name *Ident
121
}
122
123
// IndexExpr accesses an index in an array value.
124
type IndexExpr struct {
125
Value, Index Expr
126
LBrackPos, RBrackPos token.Pos
127
}
128
129
// CallExpr invokes a function value with a set of arguments.
130
type CallExpr struct {
131
Value Expr
132
Args []Expr
133
134
LParenPos, RParenPos token.Pos
135
}
136
137
// UnaryExpr performs a unary operation on a single value.
138
type UnaryExpr struct {
139
Kind token.Token
140
KindPos token.Pos
141
Value Expr
142
}
143
144
// BinaryExpr performs a binary operation against two values.
145
type BinaryExpr struct {
146
Kind token.Token
147
KindPos token.Pos
148
Left, Right Expr
149
}
150
151
// ParenExpr represents an expression wrapped in parentheses.
152
type ParenExpr struct {
153
Inner Expr
154
LParenPos, RParenPos token.Pos
155
}
156
157
// Type assertions
158
159
var (
160
_ Node = (*File)(nil)
161
_ Node = (*Body)(nil)
162
_ Node = (*AttributeStmt)(nil)
163
_ Node = (*BlockStmt)(nil)
164
_ Node = (*Ident)(nil)
165
_ Node = (*IdentifierExpr)(nil)
166
_ Node = (*LiteralExpr)(nil)
167
_ Node = (*ArrayExpr)(nil)
168
_ Node = (*ObjectExpr)(nil)
169
_ Node = (*AccessExpr)(nil)
170
_ Node = (*IndexExpr)(nil)
171
_ Node = (*CallExpr)(nil)
172
_ Node = (*UnaryExpr)(nil)
173
_ Node = (*BinaryExpr)(nil)
174
_ Node = (*ParenExpr)(nil)
175
176
_ Stmt = (*AttributeStmt)(nil)
177
_ Stmt = (*BlockStmt)(nil)
178
179
_ Expr = (*IdentifierExpr)(nil)
180
_ Expr = (*LiteralExpr)(nil)
181
_ Expr = (*ArrayExpr)(nil)
182
_ Expr = (*ObjectExpr)(nil)
183
_ Expr = (*AccessExpr)(nil)
184
_ Expr = (*IndexExpr)(nil)
185
_ Expr = (*CallExpr)(nil)
186
_ Expr = (*UnaryExpr)(nil)
187
_ Expr = (*BinaryExpr)(nil)
188
_ Expr = (*ParenExpr)(nil)
189
)
190
191
func (n *File) astNode() {}
192
func (n Body) astNode() {}
193
func (n CommentGroup) astNode() {}
194
func (n *Comment) astNode() {}
195
func (n *AttributeStmt) astNode() {}
196
func (n *BlockStmt) astNode() {}
197
func (n *Ident) astNode() {}
198
func (n *IdentifierExpr) astNode() {}
199
func (n *LiteralExpr) astNode() {}
200
func (n *ArrayExpr) astNode() {}
201
func (n *ObjectExpr) astNode() {}
202
func (n *AccessExpr) astNode() {}
203
func (n *IndexExpr) astNode() {}
204
func (n *CallExpr) astNode() {}
205
func (n *UnaryExpr) astNode() {}
206
func (n *BinaryExpr) astNode() {}
207
func (n *ParenExpr) astNode() {}
208
209
func (n *AttributeStmt) astStmt() {}
210
func (n *BlockStmt) astStmt() {}
211
212
func (n *IdentifierExpr) astExpr() {}
213
func (n *LiteralExpr) astExpr() {}
214
func (n *ArrayExpr) astExpr() {}
215
func (n *ObjectExpr) astExpr() {}
216
func (n *AccessExpr) astExpr() {}
217
func (n *IndexExpr) astExpr() {}
218
func (n *CallExpr) astExpr() {}
219
func (n *UnaryExpr) astExpr() {}
220
func (n *BinaryExpr) astExpr() {}
221
func (n *ParenExpr) astExpr() {}
222
223
// StartPos returns the position of the first character belonging to a Node.
224
func StartPos(n Node) token.Pos {
225
if n == nil || reflect.ValueOf(n).IsZero() {
226
return token.NoPos
227
}
228
switch n := n.(type) {
229
case *File:
230
return StartPos(n.Body)
231
case Body:
232
if len(n) == 0 {
233
return token.NoPos
234
}
235
return StartPos(n[0])
236
case CommentGroup:
237
if len(n) == 0 {
238
return token.NoPos
239
}
240
return StartPos(n[0])
241
case *Comment:
242
return n.StartPos
243
case *AttributeStmt:
244
return StartPos(n.Name)
245
case *BlockStmt:
246
return n.NamePos
247
case *Ident:
248
return n.NamePos
249
case *IdentifierExpr:
250
return StartPos(n.Ident)
251
case *LiteralExpr:
252
return n.ValuePos
253
case *ArrayExpr:
254
return n.LBrackPos
255
case *ObjectExpr:
256
return n.LCurlyPos
257
case *AccessExpr:
258
return StartPos(n.Value)
259
case *IndexExpr:
260
return StartPos(n.Value)
261
case *CallExpr:
262
return StartPos(n.Value)
263
case *UnaryExpr:
264
return n.KindPos
265
case *BinaryExpr:
266
return StartPos(n.Left)
267
case *ParenExpr:
268
return n.LParenPos
269
default:
270
panic(fmt.Sprintf("Unhandled Node type %T", n))
271
}
272
}
273
274
// EndPos returns the position of the final character in a Node.
275
func EndPos(n Node) token.Pos {
276
if n == nil || reflect.ValueOf(n).IsZero() {
277
return token.NoPos
278
}
279
switch n := n.(type) {
280
case *File:
281
return EndPos(n.Body)
282
case Body:
283
if len(n) == 0 {
284
return token.NoPos
285
}
286
return EndPos(n[len(n)-1])
287
case CommentGroup:
288
if len(n) == 0 {
289
return token.NoPos
290
}
291
return EndPos(n[len(n)-1])
292
case *Comment:
293
return n.StartPos.Add(len(n.Text) - 1)
294
case *AttributeStmt:
295
return EndPos(n.Value)
296
case *BlockStmt:
297
return n.RCurlyPos
298
case *Ident:
299
return n.NamePos.Add(len(n.Name) - 1)
300
case *IdentifierExpr:
301
return EndPos(n.Ident)
302
case *LiteralExpr:
303
return n.ValuePos.Add(len(n.Value) - 1)
304
case *ArrayExpr:
305
return n.RBrackPos
306
case *ObjectExpr:
307
return n.RCurlyPos
308
case *AccessExpr:
309
return EndPos(n.Name)
310
case *IndexExpr:
311
return n.RBrackPos
312
case *CallExpr:
313
return n.RParenPos
314
case *UnaryExpr:
315
return EndPos(n.Value)
316
case *BinaryExpr:
317
return EndPos(n.Right)
318
case *ParenExpr:
319
return n.RParenPos
320
default:
321
panic(fmt.Sprintf("Unhandled Node type %T", n))
322
}
323
}
324
325
// GetBlockName retrieves the "." delimited block name.
326
func (block *BlockStmt) GetBlockName() string {
327
return strings.Join(block.Name, ".")
328
}
329
330