-
Notifications
You must be signed in to change notification settings - Fork 231
/
resourceparser.go
105 lines (86 loc) · 2.65 KB
/
resourceparser.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package resourceparser
import (
"go/ast"
"encr.dev/pkg/option"
"encr.dev/pkg/paths"
"encr.dev/v2/internals/parsectx"
"encr.dev/v2/internals/pkginfo"
"encr.dev/v2/internals/schema"
"encr.dev/v2/parser/resource"
)
type Parser struct {
Name string
// InterestingImports are the imports paths that the parser is interested in.
// If a package imports any one of them, the Run method is invoked.
InterestingImports []paths.Pkg
// InterestingSubdirs are the subdirectories of a package that a parser is interested in.
// If a package has any one of these subdirectories, the Run method is invoked.
// Its purpose is to support our current way of defining databases via a "migrations" dir.
InterestingSubdirs []string
Run func(*Pass)
}
// RunAlways is a value for InterestingImports to indicate to always run the parser.
var RunAlways = []paths.Pkg{"*"}
type Pass struct {
*parsectx.Context
SchemaParser *schema.Parser
Pkg *pkginfo.Package
resources []resource.Resource
binds []resource.Bind
}
func (p *Pass) RegisterResource(resource resource.Resource) {
p.resources = append(p.resources, resource)
}
func (p *Pass) Resources() []resource.Resource {
return p.resources
}
func (p *Pass) Binds() []resource.Bind {
return p.binds
}
func (p *Pass) AddBind(file *pkginfo.File, boundName option.Option[*ast.Ident], res resource.Resource) {
if id, ok := boundName.Get(); ok {
p.AddNamedBind(file, id, res)
} else {
p.AddAnonymousBind(file, res)
}
}
func (p *Pass) AddNamedBind(file *pkginfo.File, boundName *ast.Ident, res resource.Resource) {
if boundName.Name == "_" {
p.AddAnonymousBind(file, res)
} else {
p.binds = append(p.binds, &resource.PkgDeclBind{
Resource: resource.ResourceOrPath{Resource: res},
File: file,
BoundName: boundName,
})
}
}
func (p *Pass) AddAnonymousBind(file *pkginfo.File, res resource.Resource) {
p.binds = append(p.binds, &resource.AnonymousBind{
Resource: resource.ResourceOrPath{Resource: res},
File: file,
})
}
func (p *Pass) AddPathBind(file *pkginfo.File, boundName option.Option[*ast.Ident], path resource.Path) {
if len(path) == 0 {
panic("AddPathBind: empty path")
}
if id, ok := boundName.Get(); !ok || id.Name == "_" {
p.binds = append(p.binds, &resource.AnonymousBind{
Resource: resource.ResourceOrPath{Path: path},
File: file,
})
} else {
p.binds = append(p.binds, &resource.PkgDeclBind{
Resource: resource.ResourceOrPath{Path: path},
File: file,
BoundName: id,
})
}
}
func (p *Pass) AddImplicitBind(res resource.Resource) {
p.binds = append(p.binds, &resource.ImplicitBind{
Resource: resource.ResourceOrPath{Resource: res},
Pkg: p.Pkg,
})
}