1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package adt
16
17 import (
18 "fmt"
19
20 "cuelang.org/go/cue/token"
21 )
22
23 func (v *Vertex) getState(c *OpContext) *nodeContext {
24 if v.status == finalized {
25 return nil
26 }
27 if v.state == nil {
28 v.state = c.newNodeContext(v)
29 v.state.initNode()
30 v.state.refCount = 1
31 }
32
33
34 v.state.refCount += 1
35
36
37
38
39 return v.state
40 }
41
42
43 func (n *nodeContext) initNode() {
44 v := n.node
45 if v.Parent != nil && v.Parent.state != nil {
46 v.state.depth = v.Parent.state.depth + 1
47 n.blockOn(allAncestorsProcessed)
48 }
49
50 n.blockOn(scalarKnown | listTypeKnown | arcTypeKnown)
51
52 if v.Label.IsDef() {
53 v.Closed = true
54 }
55
56 if v.Parent != nil {
57 if v.Parent.Closed {
58 v.Closed = true
59 }
60 }
61
62 ctx := n.ctx
63
64 ctx.stats.Unifications++
65
66
67
68
69
70
71
72
73
74 v.BaseValue = cycle
75
76 defer ctx.PopArc(ctx.PushArc(v))
77
78 root := n.node.rootCloseContext()
79 root.incDependent(INIT, nil)
80
81 for _, c := range v.Conjuncts {
82 ci := c.CloseInfo
83 ci.cc = root
84 n.scheduleConjunct(c, ci)
85 }
86
87 root.decDependent(ctx, INIT, nil)
88 }
89
90 func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool {
91 if Debug {
92 c.nest++
93 c.Logf(v, "Unify %v", fmt.Sprintf("%p", v))
94 defer func() {
95 c.Logf(v, "END Unify")
96 c.nest--
97 }()
98 }
99
100 if mode == ignore {
101 return false
102 }
103
104 n := v.getState(c)
105 if n == nil {
106 return true
107 }
108 defer n.free()
109
110
111
112
113
114
115
116
117 if v.Label.IsLet() || v.IsDynamic || v.Parent.allChildConjunctsKnown() {
118 n.signal(allAncestorsProcessed)
119 }
120
121 defer c.PopArc(c.PushArc(v))
122
123 nodeOnlyNeeds := needs &^ (subFieldsProcessed)
124 n.process(nodeOnlyNeeds, mode)
125 n.updateScalar()
126
127
128 switch {
129 case n.meets(nodeOnlyNeeds):
130
131 case mode != finalize:
132 return false
133 }
134
135 if isCyclePlaceholder(n.node.BaseValue) {
136 n.node.BaseValue = nil
137 }
138 if n.aStruct != nil {
139 n.updateNodeType(StructKind, n.aStruct, n.aStructID)
140 }
141
142 n.validateValue(finalized)
143
144 if err, ok := n.node.BaseValue.(*Bottom); ok {
145 for _, arc := range n.node.Arcs {
146 if arc.Label.IsLet() {
147 continue
148 }
149 c := MakeConjunct(nil, err, c.CloseInfo())
150 if arc.state != nil {
151 arc.state.scheduleConjunct(c, c.CloseInfo)
152 }
153 }
154 }
155
156 if n.node.Label.IsLet() || n.meets(allAncestorsProcessed) {
157 if cc := v.rootCloseContext(); !cc.isDecremented {
158 cc.decDependent(c, ROOT, nil)
159 cc.isDecremented = true
160 }
161 }
162
163
164
165
166 switch {
167 case n.completed&subFieldsProcessed != 0:
168
169
170 case needs&subFieldsProcessed != 0:
171 if DebugSort > 0 {
172 DebugSortArcs(n.ctx, n.node)
173 }
174
175 switch {
176 case assertStructuralCycle(n):
177 case n.completeAllArcs(needs, mode):
178 }
179
180 n.signal(subFieldsProcessed)
181
182 if v.BaseValue == nil {
183 v.BaseValue = n.getValidators(finalized)
184 }
185 if v := n.node.Value(); v != nil && IsConcrete(v) {
186
187
188 checks := n.checks
189 n.checks = n.checks[:0]
190 for _, v := range checks {
191
192
193
194 if b := c.Validate(v, n.node); b != nil {
195 n.addBottom(b)
196 }
197 }
198 }
199
200 case needs&fieldSetKnown != 0:
201 n.evalArcTypes()
202 }
203
204 if err := n.getErr(); err != nil {
205 n.errs = nil
206 if b, _ := n.node.BaseValue.(*Bottom); b != nil {
207 err = CombineErrors(nil, b, err)
208 }
209 n.node.BaseValue = err
210 }
211
212 if mask := n.completed & needs; mask != 0 {
213
214 n.signal(mask)
215 }
216
217
218 if n.completed&(subFieldsProcessed) != 0 {
219 n.node.updateStatus(finalized)
220
221 for _, r := range n.node.cc.externalDeps {
222 src := r.src
223 a := &src.arcs[r.index]
224 if a.decremented {
225 continue
226 }
227 a.decremented = true
228 if n := src.src.getState(n.ctx); n != nil {
229 n.completeNodeConjuncts()
230 }
231 src.src.unify(n.ctx, needTasksDone, attemptOnly)
232 a.cc.decDependent(c, a.kind, src)
233 }
234
235 if DebugDeps {
236 RecordDebugGraph(n.ctx, n.node, "Finalize")
237 }
238 }
239
240 return n.meets(needs)
241 }
242
243
244
245
246
247
248
249
250
251
252
253
254
255 func (n *nodeContext) completeNodeConjuncts() {
256 const conjunctsKnown = fieldConjunctsKnown | valueKnown
257
258 if n.meets(conjunctsKnown) {
259 return
260 }
261
262 if p := n.node.Parent; p != nil && p.state != nil {
263 p.state.completeNodeConjuncts()
264 }
265
266
267 n.process(conjunctsKnown, attemptOnly)
268 }
269
270
271
272
273
274
275 func (n *nodeContext) completeNodeTasks() (ok bool) {
276 v := n.node
277 c := n.ctx
278
279 if Debug {
280 c.nest++
281 defer func() {
282 c.nest--
283 }()
284 }
285
286 if p := v.Parent; p != nil && p.state != nil {
287 if !v.IsDynamic && n.completed&allAncestorsProcessed == 0 {
288 p.state.completeNodeTasks()
289 }
290 }
291
292 if v.IsDynamic || v.Parent.allChildConjunctsKnown() {
293 n.signal(allAncestorsProcessed)
294 }
295
296 if len(n.scheduler.tasks) != n.scheduler.taskPos {
297
298 const needs = valueKnown | fieldConjunctsKnown
299
300 n.process(needs, attemptOnly)
301 n.updateScalar()
302 }
303
304
305
306
307
308
309 if !n.meets(allAncestorsProcessed) && !n.node.Label.IsLet() {
310 return false
311 }
312
313
314
315
316 if cc := v.rootCloseContext(); !cc.isDecremented {
317 cc.isDecremented = true
318
319 cc.decDependent(n.ctx, ROOT, nil)
320 }
321
322 return true
323 }
324
325 func (n *nodeContext) updateScalar() {
326
327
328 _, isErr := n.node.BaseValue.(*Bottom)
329 if n.scalar != nil && (!isErr || isCyclePlaceholder(n.node.BaseValue)) {
330 n.node.BaseValue = n.scalar
331 n.signal(scalarKnown)
332 }
333 }
334
335 func (n *nodeContext) completeAllArcs(needs condition, mode runMode) bool {
336 if n.node.status == evaluatingArcs {
337
338
339
340
341
342
343 n.ctx.addErrf(CycleError, pos(n.node), "mutual dependency")
344 }
345
346 n.node.updateStatus(evaluatingArcs)
347
348
349 success := true
350
351 for n.arcPos < len(n.node.Arcs) {
352 a := n.node.Arcs[n.arcPos]
353 n.arcPos++
354
355 if !a.unify(n.ctx, needs, finalize) {
356 success = false
357 }
358
359
360
361
362 if a.ArcType == ArcPending {
363
364 a.ArcType = ArcNotPresent
365 continue
366 }
367
368
369
370 if !a.Label.IsLet() && a.ArcType <= ArcRequired {
371 if err, _ := a.BaseValue.(*Bottom); err != nil {
372 n.node.AddChildError(err)
373 }
374 success = true
375 }
376
377
378 switch {
379 case a.ArcType > ArcRequired, !a.Label.IsString():
380 case n.kind&StructKind == 0:
381 if !n.node.IsErr() {
382 n.reportFieldMismatch(pos(a.Value()), nil, a.Label, n.node.Value())
383 }
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400 }
401 }
402
403 k := 0
404 for _, a := range n.node.Arcs {
405 if a.ArcType != ArcNotPresent {
406 n.node.Arcs[k] = a
407 k++
408 }
409 }
410 n.node.Arcs = n.node.Arcs[:k]
411
412 return success
413 }
414
415 func (n *nodeContext) evalArcTypes() {
416 for _, a := range n.node.Arcs {
417 if a.ArcType != ArcPending {
418 continue
419 }
420 a.unify(n.ctx, arcTypeKnown, yield)
421
422 if a.ArcType == ArcPending {
423
424 a.ArcType = ArcNotPresent
425 }
426 }
427 }
428
429 func (v *Vertex) lookup(c *OpContext, pos token.Pos, f Feature, flags combinedFlags) *Vertex {
430 task := c.current()
431 needs := flags.conditions()
432 runMode := flags.runMode()
433
434 c.Logf(c.vertex, "LOOKUP %v", f)
435
436 state := v.getState(c)
437 if state != nil {
438
439
440
441
442
443
444 if state.hasErr() {
445 c.AddBottom(state.getErr())
446 }
447 state.completeNodeTasks()
448 }
449
450
451 if task.state != taskRUNNING {
452 return nil
453 }
454
455
456
457 arc := v.Lookup(f)
458
459
460
461
462
463 var arcState *nodeContext
464 switch {
465 case arc != nil:
466 if arc.ArcType == ArcMember {
467 return arc
468 }
469 arcState = arc.getState(c)
470
471 case state == nil || state.meets(needTasksDone):
472
473 v.reportFieldIndexError(c, pos, f)
474 return nil
475
476 default:
477 arc = &Vertex{Parent: state.node, Label: f, ArcType: ArcPending}
478 v.Arcs = append(v.Arcs, arc)
479 arcState = arc.getState(c)
480 }
481
482 if arcState != nil && (!arcState.meets(needTasksDone) || !arcState.meets(arcTypeKnown)) {
483 needs |= arcTypeKnown
484
485
486 for _, a := range arc.Arcs {
487 if a.ArcType == ArcPending {
488 needs |= fieldSetKnown
489 break
490 }
491 }
492 arcState.completeNodeTasks()
493
494
495
496 if arc.ArcType != ArcMember {
497 for _, a := range arcState.node.Arcs {
498 if a.ArcType == ArcPending {
499 a.unify(c, arcTypeKnown, runMode)
500 }
501 }
502 }
503
504 switch runMode {
505 case ignore, attemptOnly:
506
507 arcState.addNotify2(task.node.node, task.id)
508 return arc
509
510 case yield:
511 arcState.process(needs, yield)
512
513
514
515 case finalize:
516
517 arcState.process(needs, yield)
518 }
519 }
520
521 switch arc.ArcType {
522 case ArcMember:
523 return arc
524
525 case ArcOptional, ArcRequired:
526 label := f.SelectorString(c.Runtime)
527 b := &Bottom{
528 Code: IncompleteError,
529 Err: c.NewPosf(pos,
530 "cannot reference optional field: %s", label),
531 }
532 c.AddBottom(b)
533
534 return nil
535
536 case ArcNotPresent:
537 v.reportFieldCycleError(c, pos, f)
538 return nil
539
540 case ArcPending:
541
542 panic("unreachable")
543 }
544
545 v.reportFieldIndexError(c, pos, f)
546 return nil
547 }
548
View as plain text