package ast
import (
"fmt"
"reflect"
"strings"
"github.com/grafana/agent/pkg/river/token"
)
type Node interface {
astNode()
}
type Stmt interface {
Node
astStmt()
}
type Expr interface {
Node
astExpr()
}
type File struct {
Name string
Body Body
Comments []CommentGroup
}
type Body []Stmt
type CommentGroup []*Comment
type Comment struct {
StartPos token.Pos
Text string
}
type AttributeStmt struct {
Name *Ident
Value Expr
}
type BlockStmt struct {
Name []string
NamePos token.Pos
Label string
LabelPos token.Pos
Body Body
LCurlyPos, RCurlyPos token.Pos
}
type Ident struct {
Name string
NamePos token.Pos
}
type IdentifierExpr struct {
Ident *Ident
}
type LiteralExpr struct {
Kind token.Token
ValuePos token.Pos
Value string
}
type ArrayExpr struct {
Elements []Expr
LBrackPos, RBrackPos token.Pos
}
type ObjectExpr struct {
Fields []*ObjectField
LCurlyPos, RCurlyPos token.Pos
}
type ObjectField struct {
Name *Ident
Quoted bool
Value Expr
}
type AccessExpr struct {
Value Expr
Name *Ident
}
type IndexExpr struct {
Value, Index Expr
LBrackPos, RBrackPos token.Pos
}
type CallExpr struct {
Value Expr
Args []Expr
LParenPos, RParenPos token.Pos
}
type UnaryExpr struct {
Kind token.Token
KindPos token.Pos
Value Expr
}
type BinaryExpr struct {
Kind token.Token
KindPos token.Pos
Left, Right Expr
}
type ParenExpr struct {
Inner Expr
LParenPos, RParenPos token.Pos
}
var (
_ Node = (*File)(nil)
_ Node = (*Body)(nil)
_ Node = (*AttributeStmt)(nil)
_ Node = (*BlockStmt)(nil)
_ Node = (*Ident)(nil)
_ Node = (*IdentifierExpr)(nil)
_ Node = (*LiteralExpr)(nil)
_ Node = (*ArrayExpr)(nil)
_ Node = (*ObjectExpr)(nil)
_ Node = (*AccessExpr)(nil)
_ Node = (*IndexExpr)(nil)
_ Node = (*CallExpr)(nil)
_ Node = (*UnaryExpr)(nil)
_ Node = (*BinaryExpr)(nil)
_ Node = (*ParenExpr)(nil)
_ Stmt = (*AttributeStmt)(nil)
_ Stmt = (*BlockStmt)(nil)
_ Expr = (*IdentifierExpr)(nil)
_ Expr = (*LiteralExpr)(nil)
_ Expr = (*ArrayExpr)(nil)
_ Expr = (*ObjectExpr)(nil)
_ Expr = (*AccessExpr)(nil)
_ Expr = (*IndexExpr)(nil)
_ Expr = (*CallExpr)(nil)
_ Expr = (*UnaryExpr)(nil)
_ Expr = (*BinaryExpr)(nil)
_ Expr = (*ParenExpr)(nil)
)
func (n *File) astNode() {}
func (n Body) astNode() {}
func (n CommentGroup) astNode() {}
func (n *Comment) astNode() {}
func (n *AttributeStmt) astNode() {}
func (n *BlockStmt) astNode() {}
func (n *Ident) astNode() {}
func (n *IdentifierExpr) astNode() {}
func (n *LiteralExpr) astNode() {}
func (n *ArrayExpr) astNode() {}
func (n *ObjectExpr) astNode() {}
func (n *AccessExpr) astNode() {}
func (n *IndexExpr) astNode() {}
func (n *CallExpr) astNode() {}
func (n *UnaryExpr) astNode() {}
func (n *BinaryExpr) astNode() {}
func (n *ParenExpr) astNode() {}
func (n *AttributeStmt) astStmt() {}
func (n *BlockStmt) astStmt() {}
func (n *IdentifierExpr) astExpr() {}
func (n *LiteralExpr) astExpr() {}
func (n *ArrayExpr) astExpr() {}
func (n *ObjectExpr) astExpr() {}
func (n *AccessExpr) astExpr() {}
func (n *IndexExpr) astExpr() {}
func (n *CallExpr) astExpr() {}
func (n *UnaryExpr) astExpr() {}
func (n *BinaryExpr) astExpr() {}
func (n *ParenExpr) astExpr() {}
func StartPos(n Node) token.Pos {
if n == nil || reflect.ValueOf(n).IsZero() {
return token.NoPos
}
switch n := n.(type) {
case *File:
return StartPos(n.Body)
case Body:
if len(n) == 0 {
return token.NoPos
}
return StartPos(n[0])
case CommentGroup:
if len(n) == 0 {
return token.NoPos
}
return StartPos(n[0])
case *Comment:
return n.StartPos
case *AttributeStmt:
return StartPos(n.Name)
case *BlockStmt:
return n.NamePos
case *Ident:
return n.NamePos
case *IdentifierExpr:
return StartPos(n.Ident)
case *LiteralExpr:
return n.ValuePos
case *ArrayExpr:
return n.LBrackPos
case *ObjectExpr:
return n.LCurlyPos
case *AccessExpr:
return StartPos(n.Value)
case *IndexExpr:
return StartPos(n.Value)
case *CallExpr:
return StartPos(n.Value)
case *UnaryExpr:
return n.KindPos
case *BinaryExpr:
return StartPos(n.Left)
case *ParenExpr:
return n.LParenPos
default:
panic(fmt.Sprintf("Unhandled Node type %T", n))
}
}
func EndPos(n Node) token.Pos {
if n == nil || reflect.ValueOf(n).IsZero() {
return token.NoPos
}
switch n := n.(type) {
case *File:
return EndPos(n.Body)
case Body:
if len(n) == 0 {
return token.NoPos
}
return EndPos(n[len(n)-1])
case CommentGroup:
if len(n) == 0 {
return token.NoPos
}
return EndPos(n[len(n)-1])
case *Comment:
return n.StartPos.Add(len(n.Text) - 1)
case *AttributeStmt:
return EndPos(n.Value)
case *BlockStmt:
return n.RCurlyPos
case *Ident:
return n.NamePos.Add(len(n.Name) - 1)
case *IdentifierExpr:
return EndPos(n.Ident)
case *LiteralExpr:
return n.ValuePos.Add(len(n.Value) - 1)
case *ArrayExpr:
return n.RBrackPos
case *ObjectExpr:
return n.RCurlyPos
case *AccessExpr:
return EndPos(n.Name)
case *IndexExpr:
return n.RBrackPos
case *CallExpr:
return n.RParenPos
case *UnaryExpr:
return EndPos(n.Value)
case *BinaryExpr:
return EndPos(n.Right)
case *ParenExpr:
return n.RParenPos
default:
panic(fmt.Sprintf("Unhandled Node type %T", n))
}
}
func (block *BlockStmt) GetBlockName() string {
return strings.Join(block.Name, ".")
}