cuelang.org/go@v0.10.1/internal/core/adt/composite.go (about) 1 // Copyright 2020 CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package adt 16 17 import ( 18 "fmt" 19 "slices" 20 21 "cuelang.org/go/cue/ast" 22 "cuelang.org/go/cue/errors" 23 "cuelang.org/go/cue/token" 24 ) 25 26 // TODO: unanswered questions about structural cycles: 27 // 28 // 1. When detecting a structural cycle, should we consider this as: 29 // a) an unevaluated value, 30 // b) an incomplete error (which does not affect parent validity), or 31 // c) a special value. 32 // 33 // Making it an error is the simplest way to ensure reentrancy is disallowed: 34 // without an error it would require an additional mechanism to stop reentrancy 35 // from continuing to process. Even worse, in some cases it may only partially 36 // evaluate, resulting in unexpected results. For this reason, we are taking 37 // approach `b` for now. 38 // 39 // This has some consequences of how disjunctions are treated though. Consider 40 // 41 // list: { 42 // head: _ 43 // tail: list | null 44 // } 45 // 46 // When making it an error, evaluating the above will result in 47 // 48 // list: { 49 // head: _ 50 // tail: null 51 // } 52 // 53 // because list will result in a structural cycle, and thus an error, it will be 54 // stripped from the disjunction. This may or may not be a desirable property. A 55 // nice thing is that it is not required to write `list | *null`. A disadvantage 56 // is that this is perhaps somewhat inexplicit. 57 // 58 // When not making it an error (and simply cease evaluating child arcs upon 59 // cycle detection), the result would be: 60 // 61 // list: { 62 // head: _ 63 // tail: list | null 64 // } 65 // 66 // In other words, an evaluation would result in a cycle and thus an error. 67 // Implementations can recognize such cases by having unevaluated arcs. An 68 // explicit structure cycle marker would probably be less error prone. 69 // 70 // Note that in both cases, a reference to list will still use the original 71 // conjuncts, so the result will be the same for either method in this case. 72 // 73 // 74 // 2. Structural cycle allowance. 75 // 76 // Structural cycle detection disallows reentrancy as well. This means one 77 // cannot use structs for recursive computation. This will probably preclude 78 // evaluation of some configuration. Given that there is no real alternative 79 // yet, we could allow structural cycle detection to be optionally disabled. 80 81 // An Environment links the parent scopes for identifier lookup to a composite 82 // node. Each conjunct that make up node in the tree can be associated with 83 // a different environment (although some conjuncts may share an Environment). 84 type Environment struct { 85 Up *Environment 86 Vertex *Vertex 87 88 // DynamicLabel is only set when instantiating a field from a pattern 89 // constraint. It is used to resolve label references. 90 DynamicLabel Feature 91 92 // TODO(perf): make the following public fields a shareable struct as it 93 // mostly is going to be the same for child nodes. 94 95 // TODO: This can probably move into the nodeContext, making it a map from 96 // conjunct to Value. 97 cache map[cacheKey]Value 98 } 99 100 type cacheKey struct { 101 Expr Expr 102 Arc *Vertex 103 } 104 105 func (e *Environment) up(ctx *OpContext, count int32) *Environment { 106 for i := int32(0); i < count; i++ { 107 e = e.Up 108 ctx.Assertf(ctx.Pos(), e.Vertex != nil, "Environment.up encountered a nil vertex") 109 } 110 return e 111 } 112 113 type ID int32 114 115 // evalCached is used to look up dynamic field pattern constraint expressions. 116 func (e *Environment) evalCached(c *OpContext, x Expr) Value { 117 if v, ok := x.(Value); ok { 118 return v 119 } 120 key := cacheKey{x, nil} 121 v, ok := e.cache[key] 122 if !ok { 123 if e.cache == nil { 124 e.cache = map[cacheKey]Value{} 125 } 126 env, src := c.e, c.src 127 c.e, c.src = e, x.Source() 128 // Save and restore errors to ensure that only relevant errors are 129 // associated with the cash. 130 err := c.errs 131 v = c.evalState(x, require(partial, allKnown)) // TODO: should this be finalized? 132 c.e, c.src = env, src 133 c.errs = err 134 if b, ok := v.(*Bottom); !ok || !b.IsIncomplete() { 135 e.cache[key] = v 136 } 137 } 138 return v 139 } 140 141 // A Vertex is a node in the value tree. It may be a leaf or internal node. 142 // It may have arcs to represent elements of a fully evaluated struct or list. 143 // 144 // For structs, it only contains definitions and concrete fields. 145 // optional fields are dropped. 146 // 147 // It maintains source information such as a list of conjuncts that contributed 148 // to the value. 149 type Vertex struct { 150 // Parent links to a parent Vertex. This parent should only be used to 151 // access the parent's Label field to find the relative location within a 152 // tree. 153 Parent *Vertex 154 155 // State: 156 // eval: nil, BaseValue: nil -- unevaluated 157 // eval: *, BaseValue: nil -- evaluating 158 // eval: *, BaseValue: * -- finalized 159 // 160 state *nodeContext 161 162 // cc manages the closedness logic for this Vertex. It is created 163 // by rootCloseContext. 164 // TODO: move back to nodeContext, but be sure not to clone it. 165 cc *closeContext 166 167 // Label is the feature leading to this vertex. 168 Label Feature 169 170 // TODO: move the following fields to nodeContext. 171 172 // status indicates the evaluation progress of this vertex. 173 status vertexStatus 174 175 // hasAllConjuncts indicates that the set of conjuncts is complete. 176 // This is the case if the conjuncts of all its ancestors have been 177 // processed. 178 hasAllConjuncts bool 179 180 // isData indicates that this Vertex is to be interpreted as data: pattern 181 // and additional constraints, as well as optional fields, should be 182 // ignored. 183 isData bool 184 185 // Closed indicates whether this Vertex is recursively closed. This is the 186 // case, for instance, if it is a node in a definition or if one of the 187 // conjuncts, or ancestor conjuncts, is a definition. 188 Closed bool 189 190 // HasEllipsis indicates that this Vertex is open by means of an ellipsis. 191 // TODO: combine this field with Closed once we removed the old evaluator. 192 HasEllipsis bool 193 194 // MultiLet indicates whether multiple let fields were added from 195 // different sources. If true, a LetReference must be resolved using 196 // the per-Environment value cache. 197 MultiLet bool 198 199 // After this is set, no more arcs may be added during evaluation. This is 200 // set, for instance, after a Vertex is used as a source for comprehensions, 201 // or any other operation that relies on the set of arcs being constant. 202 LockArcs bool 203 204 // IsDynamic signifies whether this struct is computed as part of an 205 // expression and not part of the static evaluation tree. 206 // Used for cycle detection. 207 IsDynamic bool 208 209 nonRooted bool // indicates that there is no path from the root of the tree. 210 211 // hasPendingArc is set if this Vertex has a void arc (e.g. for comprehensions) 212 hasPendingArc bool 213 214 // IsDisjunct indicates this Vertex is a disjunct resulting from a 215 // disjunction evaluation. 216 IsDisjunct bool 217 218 // IsShared is true if BaseValue holds a Vertex of a node of another path. 219 // If a node is shared, the user should be careful with traversal. 220 // The debug printer, for instance, takes extra care not to print in a loop. 221 IsShared bool 222 223 // IsCyclic is true if a node is cyclic, for instance if its value is 224 // a cyclic reference to a shared node or if the value is a conjunction 225 // of which at least one value is cyclic (not yet supported). 226 IsCyclic bool 227 228 // ArcType indicates the level of optionality of this arc. 229 ArcType ArcType 230 231 // cyclicReferences is a linked list of internal references pointing to this 232 // Vertex. This is used to shorten the path of some structural cycles. 233 cyclicReferences *RefNode 234 235 // BaseValue is the value associated with this vertex. For lists and structs 236 // this is a sentinel value indicating its kind. 237 BaseValue BaseValue 238 239 // ChildErrors is the collection of all errors of children. 240 ChildErrors *Bottom 241 242 // The parent of nodes can be followed to determine the path within the 243 // configuration of this node. 244 // Value Value 245 Arcs []*Vertex // arcs are sorted in display order. 246 247 // PatternConstraints are additional constraints that match more nodes. 248 // Constraints that match existing Arcs already have their conjuncts 249 // mixed in. 250 // TODO: either put in StructMarker/ListMarker or integrate with Arcs 251 // so that this pointer is unnecessary. 252 PatternConstraints *Constraints 253 254 // Conjuncts lists the structs that ultimately formed this Composite value. 255 // This includes all selected disjuncts. 256 // 257 // This value may be nil, in which case the Arcs are considered to define 258 // the final value of this Vertex. 259 // 260 // TODO: all access to Conjuncts should go through functions like 261 // VisitLeafConjuncts and VisitAllConjuncts. We should probably make this 262 // an unexported field. 263 Conjuncts []Conjunct 264 265 // Structs is a slice of struct literals that contributed to this value. 266 // This information is used to compute the topological sort of arcs. 267 Structs []*StructInfo 268 } 269 270 func deref(v *Vertex) *Vertex { 271 v = v.DerefValue() 272 n := v.state 273 if n != nil { 274 v = n.underlying 275 } 276 if v == nil { 277 panic("unexpected nil underlying with non-nil state") 278 } 279 return v 280 } 281 282 func equalDeref(a, b *Vertex) bool { 283 return deref(a) == deref(b) 284 } 285 286 // rootCloseContext creates a closeContext for this Vertex or returns the 287 // existing one. 288 func (v *Vertex) rootCloseContext(ctx *OpContext) *closeContext { 289 if v.cc == nil { 290 v.cc = &closeContext{ 291 group: (*ConjunctGroup)(&v.Conjuncts), 292 parent: nil, 293 src: v, 294 parentConjuncts: v, 295 } 296 v.cc.incDependent(ctx, ROOT, nil) // matched in REF(decrement:nodeDone) 297 } 298 v.cc.origin = v.cc 299 if p := v.Parent; p != nil { 300 pcc := p.rootCloseContext(ctx) 301 v.cc.origin = pcc.origin 302 } 303 304 return v.cc 305 } 306 307 // newInlineVertex creates a Vertex that is needed for computation, but for 308 // which there is no CUE path defined from the root Vertex. 309 func (ctx *OpContext) newInlineVertex(parent *Vertex, v BaseValue, a ...Conjunct) *Vertex { 310 return &Vertex{ 311 Parent: parent, 312 BaseValue: v, 313 IsDynamic: true, 314 ArcType: ArcMember, 315 Conjuncts: a, 316 } 317 } 318 319 // updateArcType updates v.ArcType if t is more restrictive. 320 func (v *Vertex) updateArcType(t ArcType) { 321 if t >= v.ArcType { 322 return 323 } 324 if v.ArcType == ArcNotPresent { 325 return 326 } 327 s := v.state 328 if (s != nil || v.isFinal()) && s.ctx.isDevVersion() { 329 c := s.ctx 330 if s.scheduler.frozen.meets(arcTypeKnown) { 331 parent := v.Parent 332 parent.reportFieldCycleError(c, c.Source().Pos(), v.Label) 333 return 334 } 335 } 336 if v.Parent != nil && v.Parent.ArcType == ArcPending && v.Parent.state != nil && v.Parent.state.ctx.isDevVersion() { 337 // TODO: check that state is always non-nil. 338 v.Parent.state.unshare() 339 } 340 v.ArcType = t 341 } 342 343 // isDefined indicates whether this arc is a "value" field, and not a constraint 344 // or void arc. 345 func (v *Vertex) isDefined() bool { 346 return v.ArcType == ArcMember 347 } 348 349 // IsConstraint reports whether the Vertex is an optional or required field. 350 func (v *Vertex) IsConstraint() bool { 351 return v.ArcType == ArcOptional || v.ArcType == ArcRequired 352 } 353 354 // IsDefined indicates whether this arc is defined meaning it is not a 355 // required or optional constraint and not a "void" arc. 356 // It will evaluate the arc, and thus evaluate any comprehension, to make this 357 // determination. 358 func (v *Vertex) IsDefined(c *OpContext) bool { 359 if v.isDefined() { 360 return true 361 } 362 v.Finalize(c) 363 return v.isDefined() 364 } 365 366 // Rooted reports whether there is a path from the root of the tree to this 367 // Vertex. 368 func (v *Vertex) Rooted() bool { 369 return !v.nonRooted && !v.Label.IsLet() && !v.IsDynamic 370 } 371 372 type ArcType uint8 373 374 const ( 375 // ArcMember means that this arc is a normal non-optional field 376 // (including regular, hidden, and definition fields). 377 ArcMember ArcType = iota 378 379 // ArcRequired is like optional, but requires that a field be specified. 380 // Fields are of the form foo!. 381 ArcRequired 382 383 // ArcOptional represents fields of the form foo? and defines constraints 384 // for foo in case it is defined. 385 ArcOptional 386 387 // ArcPending means that it is not known yet whether an arc exists and that 388 // its conjuncts need to be processed to find out. This happens when an arc 389 // is provisionally added as part of a comprehension, but when this 390 // comprehension has not yet yielded any results. 391 ArcPending 392 393 // ArcNotPresent indicates that this arc is not present and, unlike 394 // ArcPending, needs no further processing. 395 ArcNotPresent 396 397 // TODO: define a type for optional arcs. This will be needed for pulling 398 // in optional fields into the Vertex, which, in turn, is needed for 399 // structure sharing, among other things. 400 // We could also define types for required fields and potentially lets. 401 ) 402 403 func (a ArcType) String() string { 404 switch a { 405 case ArcMember: 406 return "Member" 407 case ArcOptional: 408 return "Optional" 409 case ArcRequired: 410 return "Required" 411 case ArcPending: 412 return "Pending" 413 case ArcNotPresent: 414 return "NotPresent" 415 } 416 return fmt.Sprintf("ArcType(%d)", a) 417 } 418 419 // definitelyExists reports whether an arc is a constraint or member arc. 420 // TODO: we should check that users of this call ensure there are no 421 // ArcPendings. 422 func (v *Vertex) definitelyExists() bool { 423 return v.ArcType < ArcPending 424 } 425 426 // ConstraintFromToken converts a given AST constraint token to the 427 // corresponding ArcType. 428 func ConstraintFromToken(t token.Token) ArcType { 429 switch t { 430 case token.OPTION: 431 return ArcOptional 432 case token.NOT: 433 return ArcRequired 434 } 435 return ArcMember 436 } 437 438 // Token reports the token corresponding to the constraint represented by a, 439 // or token.ILLEGAL otherwise. 440 func (a ArcType) Token() (t token.Token) { 441 switch a { 442 case ArcOptional: 443 t = token.OPTION 444 case ArcRequired: 445 t = token.NOT 446 } 447 return t 448 } 449 450 // Suffix reports the field suffix for the given ArcType if it is a 451 // constraint or the empty string otherwise. 452 func (a ArcType) Suffix() string { 453 switch a { 454 case ArcOptional: 455 return "?" 456 case ArcRequired: 457 return "!" 458 459 // For debugging internal state. This is not CUE syntax. 460 case ArcPending: 461 return "*" 462 case ArcNotPresent: 463 return "-" 464 } 465 return "" 466 } 467 468 func (v *Vertex) Clone() *Vertex { 469 c := *v 470 c.state = nil 471 return &c 472 } 473 474 type StructInfo struct { 475 *StructLit 476 477 Env *Environment 478 479 CloseInfo 480 481 // Embed indicates the struct in which this struct is embedded (originally), 482 // or nil if this is a root structure. 483 // Embed *StructInfo 484 // Context *RefInfo // the location from which this struct originates. 485 Disable bool 486 487 Embedding bool 488 } 489 490 // TODO(perf): this could be much more aggressive for eliminating structs that 491 // are immaterial for closing. 492 func (s *StructInfo) useForAccept() bool { 493 if c := s.closeInfo; c != nil { 494 return !c.noCheck 495 } 496 return true 497 } 498 499 // vertexStatus indicates the evaluation progress of a Vertex. 500 type vertexStatus int8 501 502 const ( 503 // unprocessed indicates a Vertex has not been processed before. 504 // Value must be nil. 505 unprocessed vertexStatus = iota 506 507 // evaluating means that the current Vertex is being evaluated. If this is 508 // encountered it indicates a reference cycle. Value must be nil. 509 evaluating 510 511 // partial indicates that the result was only partially evaluated. It will 512 // need to be fully evaluated to get a complete results. 513 // 514 // TODO: this currently requires a renewed computation. Cache the 515 // nodeContext to allow reusing the computations done so far. 516 partial 517 518 // conjuncts is the state reached when all conjuncts have been evaluated, 519 // but without recursively processing arcs. 520 conjuncts 521 522 // evaluatingArcs indicates that the arcs of the Vertex are currently being 523 // evaluated. If this is encountered it indicates a structural cycle. 524 // Value does not have to be nil 525 evaluatingArcs 526 527 // finalized means that this node is fully evaluated and that the results 528 // are save to use without further consideration. 529 finalized 530 ) 531 532 func (s vertexStatus) String() string { 533 switch s { 534 case unprocessed: 535 return "unprocessed" 536 case evaluating: 537 return "evaluating" 538 case partial: 539 return "partial" 540 case conjuncts: 541 return "conjuncts" 542 case evaluatingArcs: 543 return "evaluatingArcs" 544 case finalized: 545 return "finalized" 546 default: 547 return "unknown" 548 } 549 } 550 551 func (v *Vertex) Status() vertexStatus { 552 return v.status 553 } 554 555 // ForceDone prevents v from being evaluated. 556 func (v *Vertex) ForceDone() { 557 v.updateStatus(finalized) 558 } 559 560 // IsUnprocessed reports whether v is unprocessed. 561 func (v *Vertex) IsUnprocessed() bool { 562 return v.status == unprocessed 563 } 564 565 func (v *Vertex) updateStatus(s vertexStatus) { 566 if !isCyclePlaceholder(v.BaseValue) { 567 if !v.IsErr() && v.state != nil { 568 Assertf(v.state.ctx, v.status <= s+1, "attempt to regress status from %d to %d", v.Status(), s) 569 } 570 } 571 572 if s == finalized && v.BaseValue == nil { 573 // TODO: for debugging. 574 // panic("not finalized") 575 } 576 v.status = s 577 } 578 579 // setParentDone signals v that the conjuncts of all ancestors have been 580 // processed. 581 // If all conjuncts of this node have been set, all arcs will be notified 582 // of this parent being done. 583 // 584 // Note: once a vertex has started evaluation (state != nil), insertField will 585 // cause all conjuncts to be immediately processed. This means that if all 586 // ancestors of this node processed their conjuncts, and if this node has 587 // processed all its conjuncts as well, all nodes that it embedded will have 588 // received all their conjuncts as well, after which this node will have been 589 // notified of these conjuncts. 590 func (v *Vertex) setParentDone() { 591 v.hasAllConjuncts = true 592 // Could set "Conjuncts" flag of arc at this point. 593 if n := v.state; n != nil && len(n.conjuncts) == n.conjunctsPos { 594 for _, a := range v.Arcs { 595 a.setParentDone() 596 } 597 } 598 } 599 600 // VisitLeafConjuncts visits all conjuncts that are leafs of the ConjunctGroup tree. 601 func (v *Vertex) VisitLeafConjuncts(f func(Conjunct) bool) { 602 visitConjuncts(v.Conjuncts, f) 603 } 604 605 func visitConjuncts(a []Conjunct, f func(Conjunct) bool) bool { 606 for _, c := range a { 607 switch x := c.x.(type) { 608 case *ConjunctGroup: 609 if !visitConjuncts(*x, f) { 610 return false 611 } 612 default: 613 if !f(c) { 614 return false 615 } 616 } 617 } 618 return true 619 } 620 621 // VisitAllConjuncts visits all conjuncts of v, including ConjunctGroups. 622 // Note that ConjunctGroups do not have an Environment associated with them. 623 func (v *Vertex) VisitAllConjuncts(f func(c Conjunct, isLeaf bool)) { 624 visitAllConjuncts(v.Conjuncts, f) 625 } 626 627 func visitAllConjuncts(a []Conjunct, f func(c Conjunct, isLeaf bool)) { 628 for _, c := range a { 629 switch x := c.x.(type) { 630 case *ConjunctGroup: 631 f(c, false) 632 visitAllConjuncts(*x, f) 633 default: 634 f(c, true) 635 } 636 } 637 } 638 639 // SingleConjunct reports whether there is a single leaf conjunct and returns 1 640 // if so. It will return 0 if there are no conjuncts or 2 if there are more than 641 // 1. 642 // 643 // This is an often-used operation. 644 func (v *Vertex) SingleConjunct() (c Conjunct, count int) { 645 if v == nil { 646 return c, 0 647 } 648 v.VisitLeafConjuncts(func(x Conjunct) bool { 649 c = x 650 if count++; count > 1 { 651 return false 652 } 653 return true 654 }) 655 656 return c, count 657 } 658 659 // Value returns the Value of v without definitions if it is a scalar 660 // or itself otherwise. 661 func (v *Vertex) Value() Value { 662 switch x := v.BaseValue.(type) { 663 case nil: 664 return nil 665 case *StructMarker, *ListMarker: 666 return v 667 case Value: 668 // TODO: recursively descend into Vertex? 669 return x 670 default: 671 panic(fmt.Sprintf("unexpected type %T", v.BaseValue)) 672 } 673 } 674 675 // isUndefined reports whether a vertex does not have a useable BaseValue yet. 676 func (v *Vertex) isUndefined() bool { 677 if !v.isDefined() { 678 return true 679 } 680 switch v.BaseValue { 681 case nil, cycle: 682 return true 683 } 684 return false 685 } 686 687 // isFinal reports whether this node may no longer be modified. 688 func (v *Vertex) isFinal() bool { 689 // TODO(deref): the accounting of what is final should be recorded 690 // in the original node. Remove this dereference once the old 691 // evaluator has been removed. 692 v = v.DerefValue() 693 return v.status == finalized 694 } 695 696 func (x *Vertex) IsConcrete() bool { 697 return x.Concreteness() <= Concrete 698 } 699 700 // IsData reports whether v should be interpreted in data mode. In other words, 701 // it tells whether optional field matching and non-regular fields, like 702 // definitions and hidden fields, should be ignored. 703 func (v *Vertex) IsData() bool { 704 return v.isData || len(v.Conjuncts) == 0 705 } 706 707 // ToDataSingle creates a new Vertex that represents just the regular fields 708 // of this vertex. Arcs are left untouched. 709 // It is used by cue.Eval to convert nodes to data on per-node basis. 710 func (v *Vertex) ToDataSingle() *Vertex { 711 w := *v 712 w.isData = true 713 w.state = nil 714 w.status = finalized 715 return &w 716 } 717 718 // ToDataAll returns a new v where v and all its descendents contain only 719 // the regular fields. 720 func (v *Vertex) ToDataAll(ctx *OpContext) *Vertex { 721 arcs := make([]*Vertex, 0, len(v.Arcs)) 722 for _, a := range v.Arcs { 723 if !a.IsDefined(ctx) { 724 continue 725 } 726 if a.Label.IsRegular() { 727 arcs = append(arcs, a.ToDataAll(ctx)) 728 } 729 } 730 w := *v 731 w.state = nil 732 w.status = finalized 733 734 w.BaseValue = toDataAll(ctx, w.BaseValue) 735 w.Arcs = arcs 736 w.isData = true 737 w.Conjuncts = slices.Clone(v.Conjuncts) 738 // TODO(perf): this is not strictly necessary for evaluation, but it can 739 // hurt performance greatly. Drawback is that it may disable ordering. 740 for _, s := range w.Structs { 741 s.Disable = true 742 } 743 for i, c := range w.Conjuncts { 744 if v, _ := c.x.(Value); v != nil { 745 w.Conjuncts[i].x = toDataAll(ctx, v).(Value) 746 } 747 } 748 return &w 749 } 750 751 func toDataAll(ctx *OpContext, v BaseValue) BaseValue { 752 switch x := v.(type) { 753 default: 754 return x 755 756 case *Vertex: 757 return x.ToDataAll(ctx) 758 759 // The following cases are always erroneous, but we handle them anyway 760 // to avoid issues with the closedness algorithm down the line. 761 case *Disjunction: 762 d := *x 763 d.Values = make([]Value, len(x.Values)) 764 for i, v := range x.Values { 765 switch x := v.(type) { 766 case *Vertex: 767 d.Values[i] = x.ToDataAll(ctx) 768 default: 769 d.Values[i] = x 770 } 771 } 772 return &d 773 774 case *Conjunction: 775 c := *x 776 c.Values = make([]Value, len(x.Values)) 777 for i, v := range x.Values { 778 // This case is okay because the source is of type Value. 779 c.Values[i] = toDataAll(ctx, v).(Value) 780 } 781 return &c 782 } 783 } 784 785 // func (v *Vertex) IsEvaluating() bool { 786 // return v.Value == cycle 787 // } 788 789 // IsErr is a convenience function to check whether a Vertex represents an 790 // error currently. It does not finalize the value, so it is possible that 791 // v may become erroneous after this call. 792 func (v *Vertex) IsErr() bool { 793 // if v.Status() > Evaluating { 794 return v.Bottom() != nil 795 } 796 797 // Err finalizes v, if it isn't yet, and returns an error if v evaluates to an 798 // error or nil otherwise. 799 func (v *Vertex) Err(c *OpContext) *Bottom { 800 v.Finalize(c) 801 return v.Bottom() 802 } 803 804 // Bottom reports whether v is currently erroneous It does not finalize the 805 // value, so it is possible that v may become erroneous after this call. 806 func (v *Vertex) Bottom() *Bottom { 807 // TODO: should we consider errors recorded in the state? 808 v = v.DerefValue() 809 if b, ok := v.BaseValue.(*Bottom); ok { 810 return b 811 } 812 return nil 813 } 814 815 // func (v *Vertex) Evaluate() 816 817 func (v *Vertex) Finalize(c *OpContext) { 818 // Saving and restoring the error context prevents v from panicking in 819 // case the caller did not handle existing errors in the context. 820 err := c.errs 821 c.errs = nil 822 c.unify(v, final(finalized, allKnown)) 823 c.errs = err 824 } 825 826 // CompleteArcs ensures the set of arcs has been computed. 827 func (v *Vertex) CompleteArcs(c *OpContext) { 828 c.unify(v, final(conjuncts, allKnown)) 829 } 830 831 func (v *Vertex) CompleteArcsOnly(c *OpContext) { 832 c.unify(v, final(conjuncts, fieldSetKnown)) 833 } 834 835 func (v *Vertex) AddErr(ctx *OpContext, b *Bottom) { 836 v.SetValue(ctx, CombineErrors(nil, v.Value(), b)) 837 } 838 839 // SetValue sets the value of a node. 840 func (v *Vertex) SetValue(ctx *OpContext, value BaseValue) *Bottom { 841 return v.setValue(ctx, finalized, value) 842 } 843 844 func (v *Vertex) setValue(ctx *OpContext, state vertexStatus, value BaseValue) *Bottom { 845 v.BaseValue = value 846 // TODO: should not set status here for new evaluator. 847 v.updateStatus(state) 848 return nil 849 } 850 851 // ToVertex wraps v in a new Vertex, if necessary. 852 func ToVertex(v Value) *Vertex { 853 switch x := v.(type) { 854 case *Vertex: 855 return x 856 default: 857 n := &Vertex{ 858 status: finalized, 859 BaseValue: x, 860 } 861 n.AddConjunct(MakeRootConjunct(nil, v)) 862 return n 863 } 864 } 865 866 // Unwrap returns the possibly non-concrete scalar value of v, v itself for 867 // lists and structs, or nil if v is an undefined type. 868 func Unwrap(v Value) Value { 869 x, ok := v.(*Vertex) 870 if !ok { 871 return v 872 } 873 // TODO(deref): BaseValue is currently overloaded to track cycles as well 874 // as the actual or dereferenced value. Once the old evaluator can be 875 // removed, we should use the new cycle tracking mechanism for cycle 876 // detection and keep BaseValue clean. 877 x = x.DerefValue() 878 if n := x.state; n != nil && isCyclePlaceholder(x.BaseValue) { 879 if n.errs != nil && !n.errs.IsIncomplete() { 880 return n.errs 881 } 882 if n.scalar != nil { 883 return n.scalar 884 } 885 } 886 return x.Value() 887 } 888 889 // OptionalType is a bit field of the type of optional constraints in use by an 890 // Acceptor. 891 type OptionalType int8 892 893 const ( 894 HasField OptionalType = 1 << iota // X: T 895 HasDynamic // (X): T or "\(X)": T 896 HasPattern // [X]: T 897 HasComplexPattern // anything but a basic type 898 HasAdditional // ...T 899 IsOpen // Defined for all fields 900 ) 901 902 func (v *Vertex) Kind() Kind { 903 // This is possible when evaluating comprehensions. It is potentially 904 // not known at this time what the type is. 905 switch { 906 case v.state != nil && v.state.kind == BottomKind: 907 return BottomKind 908 case v.BaseValue != nil && !isCyclePlaceholder(v.BaseValue): 909 return v.BaseValue.Kind() 910 case v.state != nil: 911 return v.state.kind 912 default: 913 return TopKind 914 } 915 } 916 917 func (v *Vertex) OptionalTypes() OptionalType { 918 var mask OptionalType 919 for _, s := range v.Structs { 920 mask |= s.OptionalTypes() 921 } 922 return mask 923 } 924 925 // IsOptional reports whether a field is explicitly defined as optional, 926 // as opposed to whether it is allowed by a pattern constraint. 927 func (v *Vertex) IsOptional(label Feature) bool { 928 for _, a := range v.Arcs { 929 if a.Label == label { 930 return a.IsConstraint() 931 } 932 } 933 return false 934 } 935 936 func (v *Vertex) accepts(ok, required bool) bool { 937 return ok || (!required && !v.Closed) 938 } 939 940 func (v *Vertex) IsClosedStruct() bool { 941 // TODO: uncomment this. This fixes a bunch of closedness bugs 942 // in the old and new evaluator. For compability sake, though, we 943 // keep it as is for now. 944 // if v.Closed { 945 // return true 946 // } 947 // if v.HasEllipsis { 948 // return false 949 // } 950 switch x := v.BaseValue.(type) { 951 default: 952 return false 953 954 case *Vertex: 955 return v.Closed && !v.HasEllipsis 956 957 case *StructMarker: 958 if x.NeedClose { 959 return true 960 } 961 962 case *Disjunction: 963 } 964 return isClosed(v) 965 } 966 967 func (v *Vertex) IsClosedList() bool { 968 if x, ok := v.BaseValue.(*ListMarker); ok { 969 return !x.IsOpen 970 } 971 return false 972 } 973 974 // TODO: return error instead of boolean? (or at least have version that does.) 975 func (v *Vertex) Accept(ctx *OpContext, f Feature) bool { 976 // TODO(#543): remove this check. 977 if f.IsDef() { 978 return true 979 } 980 981 if f.IsHidden() || f.IsLet() { 982 return true 983 } 984 985 // TODO(deref): right now a dereferenced value holds all the necessary 986 // closedness information. In the future we may want to allow sharing nodes 987 // with different closedness information. In that case, we should reconsider 988 // the use of this dereference. Consider, for instance: 989 // 990 // #a: b // this node is currently not shared, but could be. 991 // b: {c: 1} 992 v = v.DerefValue() 993 if x, ok := v.BaseValue.(*Disjunction); ok { 994 for _, v := range x.Values { 995 if x, ok := v.(*Vertex); ok && x.Accept(ctx, f) { 996 return true 997 } 998 } 999 return false 1000 } 1001 1002 if f.IsInt() { 1003 switch v.BaseValue.(type) { 1004 case *ListMarker: 1005 // TODO(perf): use precomputed length. 1006 if f.Index() < len(v.Elems()) { 1007 return true 1008 } 1009 return !v.IsClosedList() 1010 1011 default: 1012 return v.Kind()&ListKind != 0 1013 } 1014 } 1015 1016 if k := v.Kind(); k&StructKind == 0 && f.IsString() { 1017 // If the value is bottom, we may not really know if this used to 1018 // be a struct. 1019 if k != BottomKind || len(v.Structs) == 0 { 1020 return false 1021 } 1022 } 1023 1024 // TODO: move this check to IsClosedStruct. Right now this causes too many 1025 // changes in the debug output, and it also appears to be not entirely 1026 // correct. 1027 if v.HasEllipsis { 1028 return true 1029 1030 } 1031 1032 if !v.IsClosedStruct() || v.Lookup(f) != nil { 1033 return true 1034 } 1035 1036 // TODO(perf): collect positions in error. 1037 defer ctx.ReleasePositions(ctx.MarkPositions()) 1038 1039 return v.accepts(Accept(ctx, v, f)) 1040 } 1041 1042 // MatchAndInsert finds the conjuncts for optional fields, pattern 1043 // constraints, and additional constraints that match f and inserts them in 1044 // arc. Use f is 0 to match all additional constraints only. 1045 func (v *Vertex) MatchAndInsert(ctx *OpContext, arc *Vertex) { 1046 if !v.Accept(ctx, arc.Label) { 1047 return 1048 } 1049 1050 // Go backwards to simulate old implementation. 1051 for i := len(v.Structs) - 1; i >= 0; i-- { 1052 s := v.Structs[i] 1053 if s.Disable { 1054 continue 1055 } 1056 s.MatchAndInsert(ctx, arc) 1057 } 1058 1059 // This is the equivalent for the new implementation. 1060 if pcs := v.PatternConstraints; pcs != nil { 1061 for _, pc := range pcs.Pairs { 1062 if matchPattern(ctx, pc.Pattern, arc.Label) { 1063 for _, c := range pc.Constraint.Conjuncts { 1064 env := *(c.Env) 1065 if arc.Label.Index() < MaxIndex { 1066 env.DynamicLabel = arc.Label 1067 } 1068 c.Env = &env 1069 1070 root := arc.rootCloseContext(ctx) 1071 root.insertConjunct(ctx, root, c, c.CloseInfo, ArcMember, true, false) 1072 } 1073 } 1074 } 1075 } 1076 } 1077 1078 func (v *Vertex) IsList() bool { 1079 _, ok := v.BaseValue.(*ListMarker) 1080 return ok 1081 } 1082 1083 // Lookup returns the Arc with label f if it exists or nil otherwise. 1084 func (v *Vertex) Lookup(f Feature) *Vertex { 1085 for _, a := range v.Arcs { 1086 if a.Label == f { 1087 // TODO(P1)/TODO(deref): this indirection should ultimately be 1088 // eliminated: the original node may have useful information (like 1089 // original conjuncts) that are eliminated after indirection. We 1090 // should leave it up to the user of Lookup at what point an 1091 // indirection is necessary. 1092 a = a.DerefValue() 1093 return a 1094 } 1095 } 1096 return nil 1097 } 1098 1099 // LookupRaw returns the Arc with label f if it exists or nil otherwise. 1100 // 1101 // TODO: with the introduction of structure sharing, it is not always correct 1102 // to indirect the arc. At the very least, this discards potential useful 1103 // information. We introduce LookupRaw to avoid having to delete the 1104 // information. Ultimately, this should become Lookup, or better, we should 1105 // have a higher-level API for accessing values. 1106 func (v *Vertex) LookupRaw(f Feature) *Vertex { 1107 for _, a := range v.Arcs { 1108 if a.Label == f { 1109 return a 1110 } 1111 } 1112 return nil 1113 } 1114 1115 // Elems returns the regular elements of a list. 1116 func (v *Vertex) Elems() []*Vertex { 1117 // TODO: add bookkeeping for where list arcs start and end. 1118 a := make([]*Vertex, 0, len(v.Arcs)) 1119 for _, x := range v.Arcs { 1120 if x.Label.IsInt() { 1121 a = append(a, x) 1122 } 1123 } 1124 return a 1125 } 1126 1127 func (v *Vertex) Init(c *OpContext) { 1128 v.getState(c) 1129 } 1130 1131 // GetArc returns a Vertex for the outgoing arc with label f. It creates and 1132 // ads one if it doesn't yet exist. 1133 func (v *Vertex) GetArc(c *OpContext, f Feature, t ArcType) (arc *Vertex, isNew bool) { 1134 arc = v.Lookup(f) 1135 if arc != nil { 1136 arc.updateArcType(t) 1137 return arc, false 1138 } 1139 1140 if c.isDevVersion() { 1141 return nil, false 1142 } 1143 1144 if v.LockArcs { 1145 // TODO(errors): add positions. 1146 if f.IsInt() { 1147 c.addErrf(EvalError, token.NoPos, 1148 "element at index %v not allowed by earlier comprehension or reference cycle", f) 1149 } else { 1150 c.addErrf(EvalError, token.NoPos, 1151 "field %v not allowed by earlier comprehension or reference cycle", f) 1152 } 1153 } 1154 // TODO: consider setting Dynamic here from parent. 1155 arc = &Vertex{ 1156 Parent: v, 1157 Label: f, 1158 ArcType: t, 1159 nonRooted: v.IsDynamic || v.Label.IsLet() || v.nonRooted, 1160 } 1161 v.Arcs = append(v.Arcs, arc) 1162 if t == ArcPending { 1163 v.hasPendingArc = true 1164 } 1165 return arc, true 1166 } 1167 1168 func (v *Vertex) Source() ast.Node { 1169 if v != nil { 1170 if b, ok := v.BaseValue.(Value); ok { 1171 return b.Source() 1172 } 1173 } 1174 return nil 1175 } 1176 1177 // AddConjunct adds the given Conjuncts to v if it doesn't already exist. 1178 func (v *Vertex) AddConjunct(c Conjunct) *Bottom { 1179 if v.BaseValue != nil && !isCyclePlaceholder(v.BaseValue) { 1180 // TODO: investigate why this happens at all. Removing it seems to 1181 // change the order of fields in some cases. 1182 // 1183 // This is likely a bug in the evaluator and should not happen. 1184 return &Bottom{Err: errors.Newf(token.NoPos, "cannot add conjunct")} 1185 } 1186 if !v.hasConjunct(c) { 1187 v.addConjunctUnchecked(c) 1188 } 1189 return nil 1190 } 1191 1192 func (v *Vertex) hasConjunct(c Conjunct) (added bool) { 1193 switch f := c.x.(type) { 1194 case *BulkOptionalField, *Ellipsis: 1195 case *Field: 1196 v.updateArcType(f.ArcType) 1197 case *DynamicField: 1198 v.updateArcType(f.ArcType) 1199 default: 1200 v.ArcType = ArcMember 1201 } 1202 return hasConjunct(v.Conjuncts, c) 1203 } 1204 1205 func hasConjunct(cs []Conjunct, c Conjunct) bool { 1206 for _, x := range cs { 1207 // TODO: disregard certain fields from comparison (e.g. Refs)? 1208 if x.CloseInfo.closeInfo == c.CloseInfo.closeInfo && 1209 x.x == c.x && 1210 x.Env.Up == c.Env.Up && x.Env.Vertex == c.Env.Vertex { 1211 return true 1212 } 1213 } 1214 return false 1215 } 1216 1217 func (n *nodeContext) addConjunction(c Conjunct, index int) { 1218 unreachableForDev(n.ctx) 1219 1220 // NOTE: This does not split binary expressions for comprehensions. 1221 // TODO: split for comprehensions and rewrap? 1222 if x, ok := c.Elem().(*BinaryExpr); ok && x.Op == AndOp { 1223 c.x = x.X 1224 n.conjuncts = append(n.conjuncts, conjunct{C: c, index: index}) 1225 c.x = x.Y 1226 n.conjuncts = append(n.conjuncts, conjunct{C: c, index: index}) 1227 } else { 1228 n.conjuncts = append(n.conjuncts, conjunct{C: c, index: index}) 1229 } 1230 } 1231 1232 func (v *Vertex) addConjunctUnchecked(c Conjunct) { 1233 index := len(v.Conjuncts) 1234 v.Conjuncts = append(v.Conjuncts, c) 1235 if n := v.state; n != nil && !n.ctx.isDevVersion() { 1236 // TODO(notify): consider this as a central place to send out 1237 // notifications. At the moment this is not necessary, but it may 1238 // be if we move the notification mechanism outside of the path of 1239 // running tasks. 1240 n.addConjunction(c, index) 1241 1242 // TODO: can we remove notifyConjunct here? This method is only 1243 // used if either Unprocessed is 0, in which case there will be no 1244 // notification recipients, or for "pushed down" comprehensions, 1245 // which should also have been added at an earlier point. 1246 n.notifyConjunct(c) 1247 } 1248 } 1249 1250 // addConjunctDynamic adds a conjunct to a vertex and immediately evaluates 1251 // it, whilst doing the same for any vertices on the notify list, recursively. 1252 func (n *nodeContext) addConjunctDynamic(c Conjunct) { 1253 unreachableForDev(n.ctx) 1254 1255 n.node.Conjuncts = append(n.node.Conjuncts, c) 1256 n.addExprConjunct(c, partial) 1257 n.notifyConjunct(c) 1258 1259 } 1260 1261 func (n *nodeContext) notifyConjunct(c Conjunct) { 1262 unreachableForDev(n.ctx) 1263 1264 for _, rec := range n.notify { 1265 arc := rec.v 1266 if !arc.hasConjunct(c) { 1267 if arc.state == nil { 1268 // TODO: continuing here is likely to result in a faulty 1269 // (incomplete) configuration. But this may be okay. The 1270 // CUE_DEBUG=0 flag disables this assertion. 1271 n.ctx.Assertf(n.ctx.pos(), !n.ctx.Strict, "unexpected nil state") 1272 n.ctx.addErrf(0, n.ctx.pos(), "cannot add to field %v", arc.Label) 1273 continue 1274 } 1275 arc.state.addConjunctDynamic(c) 1276 } 1277 } 1278 } 1279 1280 func (v *Vertex) AddStruct(s *StructLit, env *Environment, ci CloseInfo) *StructInfo { 1281 info := StructInfo{ 1282 StructLit: s, 1283 Env: env, 1284 CloseInfo: ci, 1285 } 1286 for _, t := range v.Structs { 1287 if *t == info { // TODO: check for different identity. 1288 return t 1289 } 1290 } 1291 t := &info 1292 v.Structs = append(v.Structs, t) 1293 return t 1294 } 1295 1296 // Path computes the sequence of Features leading from the root to of the 1297 // instance to this Vertex. 1298 // 1299 // NOTE: this is for debugging purposes only. 1300 func (v *Vertex) Path() []Feature { 1301 return appendPath(nil, v) 1302 } 1303 1304 func appendPath(a []Feature, v *Vertex) []Feature { 1305 if v.Parent == nil { 1306 return a 1307 } 1308 a = appendPath(a, v.Parent) 1309 if v.Label != 0 { 1310 // A Label may be 0 for programmatically inserted nodes. 1311 a = append(a, v.Label) 1312 } 1313 return a 1314 } 1315 1316 // A Conjunct is an Environment-Expr pair. The Environment is the starting 1317 // point for reference lookup for any reference contained in X. 1318 type Conjunct struct { 1319 Env *Environment 1320 x Node 1321 1322 // CloseInfo is a unique number that tracks a group of conjuncts that need 1323 // belong to a single originating definition. 1324 CloseInfo CloseInfo 1325 } 1326 1327 // TODO(perf): replace with composite literal if this helps performance. 1328 1329 // MakeRootConjunct creates a conjunct from the given environment and node. 1330 // It panics if x cannot be used as an expression. 1331 func MakeRootConjunct(env *Environment, x Node) Conjunct { 1332 return MakeConjunct(env, x, CloseInfo{}) 1333 } 1334 1335 func MakeConjunct(env *Environment, x Node, id CloseInfo) Conjunct { 1336 if env == nil { 1337 // TODO: better is to pass one. 1338 env = &Environment{} 1339 } 1340 switch x.(type) { 1341 case Elem, interface{ expr() Expr }: 1342 default: 1343 panic(fmt.Sprintf("invalid Node type %T", x)) 1344 } 1345 return Conjunct{env, x, id} 1346 } 1347 1348 func (c *Conjunct) Source() ast.Node { 1349 return c.x.Source() 1350 } 1351 1352 func (c *Conjunct) Field() Node { 1353 switch x := c.x.(type) { 1354 case *Comprehension: 1355 return x.Value 1356 default: 1357 return c.x 1358 } 1359 } 1360 1361 // Elem retrieves the Elem form of the contained conjunct. 1362 // If it is a Field, it will return the field value. 1363 func (c *Conjunct) Elem() Elem { 1364 switch x := c.x.(type) { 1365 case interface{ expr() Expr }: 1366 return x.expr() 1367 case Elem: 1368 return x 1369 default: 1370 panic("unreachable") 1371 } 1372 } 1373 1374 // Expr retrieves the expression form of the contained conjunct. If it is a 1375 // field or comprehension, it will return its associated value. This is only to 1376 // be used for syntactic operations where evaluation of the expression is not 1377 // required. To get an expression paired with the correct environment, use 1378 // EnvExpr. 1379 // 1380 // TODO: rename to RawExpr. 1381 func (c *Conjunct) Expr() Expr { 1382 return ToExpr(c.x) 1383 } 1384 1385 // EnvExpr returns the expression form of the contained conjunct alongside an 1386 // Environment in which this expression should be evaluated. 1387 func (c Conjunct) EnvExpr() (*Environment, Expr) { 1388 return EnvExpr(c.Env, c.Elem()) 1389 } 1390 1391 // EnvExpr returns the expression represented by Elem alongside an Environment 1392 // with the necessary adjustments in which the resulting expression can be 1393 // evaluated. 1394 func EnvExpr(env *Environment, elem Elem) (*Environment, Expr) { 1395 for { 1396 switch x := elem.(type) { 1397 case *ConjunctGroup: 1398 if len(*x) == 1 { 1399 c := (*x)[0] 1400 env = c.Env 1401 elem = c.Elem() 1402 continue 1403 } 1404 case *Comprehension: 1405 env = linkChildren(env, x) 1406 c := MakeConjunct(env, x.Value, CloseInfo{}) 1407 elem = c.Elem() 1408 continue 1409 } 1410 break 1411 } 1412 return env, ToExpr(elem) 1413 } 1414 1415 // ToExpr extracts the underlying expression for a Node. If something is already 1416 // an Expr, it will return it as is, if it is a field, it will return its value, 1417 // and for comprehensions it returns the yielded struct. 1418 func ToExpr(n Node) Expr { 1419 for { 1420 switch x := n.(type) { 1421 case *ConjunctGroup: 1422 if len(*x) != 1 { 1423 return x 1424 } 1425 n = (*x)[0].x 1426 case Expr: 1427 return x 1428 case interface{ expr() Expr }: 1429 n = x.expr() 1430 case *Comprehension: 1431 n = x.Value 1432 default: 1433 panic("unreachable") 1434 } 1435 } 1436 }