-
-
Notifications
You must be signed in to change notification settings - Fork 29
/
include.go
88 lines (79 loc) · 2.56 KB
/
include.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package interpreter
import (
"fmt"
"strings"
"github.com/ysugimoto/falco/ast"
"github.com/ysugimoto/falco/interpreter/exception"
ex "github.com/ysugimoto/falco/interpreter/exception"
"github.com/ysugimoto/falco/lexer"
"github.com/ysugimoto/falco/parser"
)
func (i *Interpreter) resolveIncludeStatement(statements []ast.Statement, isRoot bool) ([]ast.Statement, error) {
var resolved []ast.Statement
for _, stmt := range statements {
if include, ok := stmt.(*ast.IncludeStatement); ok {
if strings.HasPrefix(include.Module.Value, "snippet::") {
if included, err := i.includeSnippet(include, isRoot); err != nil {
return nil, ex.Runtime(&stmt.GetMeta().Token, err.Error())
} else {
resolved = append(resolved, included...)
}
continue
}
included, err := i.includeFile(include, isRoot)
if err != nil {
return nil, ex.Runtime(&stmt.GetMeta().Token, err.Error())
}
recursive, err := i.resolveIncludeStatement(included, isRoot)
if err != nil {
return nil, err
}
resolved = append(resolved, recursive...)
continue
}
resolved = append(resolved, stmt)
}
return resolved, nil
}
func (i *Interpreter) includeSnippet(include *ast.IncludeStatement, isRoot bool) ([]ast.Statement, error) {
if i.ctx.FastlySnippets == nil {
return nil, exception.Runtime(
&include.GetMeta().Token, "Remote snippet is not found. Did you run with '-r' option?",
)
}
snippets := i.ctx.FastlySnippets.IncludeSnippets
snip, ok := snippets[strings.TrimPrefix(include.Module.Value, "snippet::")]
if !ok {
return nil, fmt.Errorf("Failed to include VCL snippets '%s'", include.Module.Value)
}
if isRoot {
return loadRootVCL(include.Module.Value, snip.Data)
}
return loadStatementVCL(include.Module.Value, snip.Data)
}
func (i *Interpreter) includeFile(include *ast.IncludeStatement, isRoot bool) ([]ast.Statement, error) {
module, err := i.ctx.Resolver.Resolve(include)
if err != nil {
return nil, fmt.Errorf("Failed to include VCL module '%s'", include.Module.Value)
}
if isRoot {
return loadRootVCL(module.Name, module.Data)
}
return loadStatementVCL(module.Name, module.Data)
}
func loadRootVCL(name, content string) ([]ast.Statement, error) {
lx := lexer.NewFromString(content, lexer.WithFile(name))
vcl, err := parser.New(lx).ParseVCL()
if err != nil {
return nil, err
}
return vcl.Statements, nil
}
func loadStatementVCL(name, content string) ([]ast.Statement, error) {
lx := lexer.NewFromString(content, lexer.WithFile(name))
vcl, err := parser.New(lx).ParseSnippetVCL()
if err != nil {
return nil, err
}
return vcl, nil
}