...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package runtime
16
17 import (
18 "path"
19 "sync"
20
21 "cuelang.org/go/cue/build"
22 "cuelang.org/go/cue/errors"
23 "cuelang.org/go/internal/core/adt"
24 )
25
26 type PackageFunc func(ctx adt.Runtime) (*adt.Vertex, errors.Error)
27
28 func RegisterBuiltin(importPath string, f PackageFunc) {
29 sharedIndex.RegisterBuiltin(importPath, f)
30 }
31
32 func (x *index) RegisterBuiltin(importPath string, f PackageFunc) {
33 if x.builtinPaths == nil {
34 x.builtinPaths = map[string]PackageFunc{}
35 x.builtinShort = map[string]string{}
36 }
37 x.builtinPaths[importPath] = f
38 base := path.Base(importPath)
39 if _, ok := x.builtinShort[base]; ok {
40 importPath = ""
41 }
42 x.builtinShort[base] = importPath
43 }
44
45 var SharedRuntime = &Runtime{index: sharedIndex}
46
47
48
49 func (x *Runtime) BuiltinPackagePath(path string) string {
50 return x.index.shortBuiltinToPath(path)
51 }
52
53
54
55 var sharedIndex = newIndex()
56
57
58
59
60 type index struct {
61
62
63 lock sync.RWMutex
64 imports map[*adt.Vertex]*build.Instance
65 importsByPath map[string]*adt.Vertex
66 importsByBuild map[*build.Instance]*adt.Vertex
67
68 nextUniqueID uint64
69
70
71
72 builtinPaths map[string]PackageFunc
73 builtinShort map[string]string
74
75 typeCache sync.Map
76 }
77
78 func (i *index) getNextUniqueID() uint64 {
79
80 i.lock.Lock()
81 i.nextUniqueID++
82 x := i.nextUniqueID
83 i.lock.Unlock()
84 return x
85 }
86
87 func newIndex() *index {
88 i := &index{
89 imports: map[*adt.Vertex]*build.Instance{},
90 importsByPath: map[string]*adt.Vertex{},
91 importsByBuild: map[*build.Instance]*adt.Vertex{},
92 }
93 return i
94 }
95
96 func (x *index) shortBuiltinToPath(id string) string {
97 if x == nil || x.builtinPaths == nil {
98 return ""
99 }
100 return x.builtinShort[id]
101 }
102
103 func (r *Runtime) AddInst(path string, key *adt.Vertex, p *build.Instance) {
104 r.index.lock.Lock()
105 defer r.index.lock.Unlock()
106
107 x := r.index
108 if key == nil {
109 panic("key must not be nil")
110 }
111 x.imports[key] = p
112 x.importsByBuild[p] = key
113 if path != "" {
114 x.importsByPath[path] = key
115 }
116 }
117
118 func (r *Runtime) GetInstanceFromNode(key *adt.Vertex) *build.Instance {
119 r.index.lock.RLock()
120 defer r.index.lock.RUnlock()
121
122 return r.index.imports[key]
123 }
124
125 func (r *Runtime) getNodeFromInstance(key *build.Instance) *adt.Vertex {
126 r.index.lock.RLock()
127 defer r.index.lock.RUnlock()
128
129 return r.index.importsByBuild[key]
130 }
131
132 func (r *Runtime) LoadImport(importPath string) *adt.Vertex {
133 r.index.lock.Lock()
134 defer r.index.lock.Unlock()
135
136 x := r.index
137
138 key := x.importsByPath[importPath]
139 if key != nil {
140 return key
141 }
142
143 if x.builtinPaths != nil {
144 if f := x.builtinPaths[importPath]; f != nil {
145 p, err := f(r)
146 if err != nil {
147 return adt.ToVertex(&adt.Bottom{Err: err})
148 }
149 inst := &build.Instance{
150 ImportPath: importPath,
151 PkgName: path.Base(importPath),
152 }
153 x.imports[p] = inst
154 x.importsByPath[importPath] = p
155 x.importsByBuild[inst] = p
156 return p
157 }
158 }
159
160 return key
161 }
162
View as plain text