-
Notifications
You must be signed in to change notification settings - Fork 316
/
resolver.go
69 lines (56 loc) · 1.62 KB
/
resolver.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
package usage
import (
"go/ast"
"go/token"
"encr.dev/pkg/option"
"encr.dev/v2/internals/perr"
"encr.dev/v2/internals/pkginfo"
"encr.dev/v2/parser/resource"
)
// Usage describes an infrastructure usage being used.
type Usage interface {
ast.Node
usage() // marker method
ResourceBind() resource.Bind
ASTExpr() ast.Expr
DeclaredIn() *pkginfo.File
}
type Base struct {
File *pkginfo.File
Bind resource.Bind
Expr Expr
}
func (b *Base) DeclaredIn() *pkginfo.File { return b.File }
func (b *Base) ASTExpr() ast.Expr { return b.Expr.ASTExpr() }
func (b *Base) ResourceBind() resource.Bind { return b.Bind }
func (b *Base) Pos() token.Pos { return b.Expr.Pos() }
func (b *Base) End() token.Pos { return b.Expr.End() }
func (b *Base) usage() {}
type Resolver struct {
resolvers map[resource.Kind]func(ResolveData, resource.Resource) Usage
}
func (r *Resolver) Resolve(errs *perr.List, expr Expr, res resource.Resource) option.Option[Usage] {
fn, ok := r.resolvers[res.Kind()]
if !ok {
return option.None[Usage]()
}
data := ResolveData{
Errs: errs,
Expr: expr,
}
return option.AsOptional(fn(data, res))
}
func NewResolver() *Resolver {
return &Resolver{
resolvers: make(map[resource.Kind]func(ResolveData, resource.Resource) Usage),
}
}
func RegisterUsageResolver[Res resource.Resource](r *Resolver, fn func(ResolveData, Res) Usage) {
var zero Res
if r.resolvers[zero.Kind()] != nil {
panic("usage resolver already registered for type " + zero.Kind().String())
}
r.resolvers[zero.Kind()] = func(data ResolveData, res resource.Resource) Usage {
return fn(data, res.(Res))
}
}