cuelang.org/go@v0.10.1/internal/core/adt/context.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 "log" 20 "reflect" 21 "regexp" 22 "sort" 23 "strings" 24 25 "github.com/cockroachdb/apd/v3" 26 "golang.org/x/text/encoding/unicode" 27 28 "cuelang.org/go/cue/ast" 29 "cuelang.org/go/cue/errors" 30 "cuelang.org/go/cue/stats" 31 "cuelang.org/go/cue/token" 32 "cuelang.org/go/internal" 33 "cuelang.org/go/internal/cuedebug" 34 ) 35 36 // DebugSort specifies that arcs be sorted consistently between implementations. 37 // 38 // 0: default 39 // 1: sort by Feature: this should be consistent between implementations where 40 // there is no change in the compiler and indexing code. 41 // 2: alphabetical 42 // 43 // TODO: move to DebugFlags 44 var DebugSort int 45 46 func DebugSortArcs(c *OpContext, n *Vertex) { 47 if n.IsList() { 48 return 49 } 50 switch a := n.Arcs; DebugSort { 51 case 1: 52 sort.SliceStable(a, func(i, j int) bool { 53 return a[i].Label < a[j].Label 54 }) 55 case 2: 56 sort.SliceStable(a, func(i, j int) bool { 57 return a[i].Label.SelectorString(c.Runtime) < 58 a[j].Label.SelectorString(c.Runtime) 59 }) 60 } 61 } 62 63 func DebugSortFields(c *OpContext, a []Feature) { 64 switch DebugSort { 65 case 1: 66 sort.SliceStable(a, func(i, j int) bool { 67 return a[i] < a[j] 68 }) 69 case 2: 70 sort.SliceStable(a, func(i, j int) bool { 71 return a[i].SelectorString(c.Runtime) < 72 a[j].SelectorString(c.Runtime) 73 }) 74 } 75 } 76 77 // Assert panics if the condition is false. Assert can be used to check for 78 // conditions that are considers to break an internal variant or unexpected 79 // condition, but that nonetheless probably will be handled correctly down the 80 // line. For instance, a faulty condition could lead to error being caught 81 // down the road, but resulting in an inaccurate error message. In production 82 // code it is better to deal with the bad error message than to panic. 83 // 84 // It is advisable for each use of Assert to document how the error is expected 85 // to be handled down the line. 86 func Assertf(c *OpContext, b bool, format string, args ...interface{}) { 87 if c.Strict && !b { 88 panic(fmt.Sprintf("assertion failed: "+format, args...)) 89 } 90 } 91 92 // Assertf either panics or reports an error to c if the condition is not met. 93 func (c *OpContext) Assertf(pos token.Pos, b bool, format string, args ...interface{}) { 94 if !b { 95 if c.Strict { 96 panic(fmt.Sprintf("assertion failed: "+format, args...)) 97 } 98 c.addErrf(0, pos, format, args...) 99 } 100 } 101 102 func init() { 103 log.SetFlags(log.Lshortfile) 104 } 105 106 var pMap = map[*Vertex]int{} 107 108 func (c *OpContext) Logf(v *Vertex, format string, args ...interface{}) { 109 if c.LogEval == 0 { 110 return 111 } 112 if v == nil { 113 s := fmt.Sprintf(strings.Repeat("..", c.nest)+format, args...) 114 _ = log.Output(2, s) 115 return 116 } 117 p := pMap[v] 118 if p == 0 { 119 p = len(pMap) + 1 120 pMap[v] = p 121 } 122 a := append([]interface{}{ 123 strings.Repeat("..", c.nest), 124 p, 125 v.Label.SelectorString(c), 126 v.Path(), 127 }, args...) 128 for i := 2; i < len(a); i++ { 129 switch x := a[i].(type) { 130 case Node: 131 a[i] = c.Str(x) 132 case Feature: 133 a[i] = x.SelectorString(c) 134 } 135 } 136 s := fmt.Sprintf("%s [%d] %s/%v"+format, a...) 137 _ = log.Output(2, s) 138 } 139 140 // PathToString creates a pretty-printed path of the given list of features. 141 func (c *OpContext) PathToString(path []Feature) string { 142 var b strings.Builder 143 for i, f := range path { 144 if i > 0 { 145 b.WriteByte('.') 146 } 147 b.WriteString(f.SelectorString(c)) 148 } 149 return b.String() 150 } 151 152 // Runtime defines an interface for low-level representation conversion and 153 // lookup. 154 type Runtime interface { 155 // StringIndexer allows for converting string labels to and from a 156 // canonical numeric representation. 157 StringIndexer 158 159 // LoadImport loads a unique Vertex associated with a given import path. It 160 // returns nil if no import for this package could be found. 161 LoadImport(importPath string) *Vertex 162 163 // StoreType associates a CUE expression with a Go type. 164 StoreType(t reflect.Type, src ast.Expr, expr Expr) 165 166 // LoadType retrieves a previously stored CUE expression for a given Go 167 // type if available. 168 LoadType(t reflect.Type) (src ast.Expr, expr Expr, ok bool) 169 170 Settings() (internal.EvaluatorVersion, cuedebug.Config) 171 } 172 173 type Config struct { 174 Runtime 175 Format func(Runtime, Node) string 176 } 177 178 // New creates an operation context. 179 func New(v *Vertex, cfg *Config) *OpContext { 180 if cfg.Runtime == nil { 181 panic("nil Runtime") 182 } 183 version, flags := cfg.Runtime.Settings() 184 ctx := &OpContext{ 185 Runtime: cfg.Runtime, 186 Format: cfg.Format, 187 vertex: v, 188 Version: version, 189 Config: flags, 190 taskContext: schedConfig, 191 } 192 if v != nil { 193 ctx.e = &Environment{Up: nil, Vertex: v} 194 } 195 return ctx 196 } 197 198 func (c *OpContext) isDevVersion() bool { 199 return c.Version == internal.DevVersion 200 } 201 202 // An OpContext implements CUE's unification operation. It only 203 // operates on values that are created with the Runtime with which an OpContext 204 // is associated. An OpContext is not goroutine safe and only one goroutine may 205 // use an OpContext at a time. 206 type OpContext struct { 207 Runtime 208 Format func(Runtime, Node) string 209 210 cuedebug.Config 211 Version internal.EvaluatorVersion // Copied from Runtime 212 213 taskContext 214 215 nest int 216 217 stats stats.Counts 218 freeListNode *nodeContext 219 220 e *Environment 221 ci CloseInfo 222 src ast.Node 223 errs *Bottom 224 positions []Node // keep track of error positions 225 226 // vertex is used to determine the path location in case of error. Turning 227 // this into a stack could also allow determining the cyclic path for 228 // structural cycle errors. 229 vertex *Vertex 230 231 // These fields are used associate scratch fields for computing closedness 232 // of a Vertex. These fields could have been included in StructInfo (like 233 // Tomabechi's unification algorithm), but we opted for an indirection to 234 // allow concurrent unification. 235 // 236 // TODO(perf): have two generations: one for each pass of the closedness 237 // algorithm, so that the results of the first pass can be reused for all 238 // features of a node. 239 generation int 240 closed map[*closeInfo]*closeStats 241 todo *closeStats 242 243 // evalDepth indicates the current depth of evaluation. It is used to 244 // detect structural cycles and their severity.s 245 evalDepth int 246 247 // optionalMark indicates the evalDepth at which the last optional field, 248 // pattern constraint or other construct that may contain errors was 249 // encountered. A value of 0 indicates we are not within such field. 250 optionalMark int 251 252 // inDisjunct indicates that non-monotonic checks should be skipped. 253 // This is used if we want to do some extra work to eliminate disjunctions 254 // early. The result of unification should be thrown away if this check is 255 // used. 256 // 257 // TODO: replace this with a mechanism to determine the correct set (per 258 // conjunct) of StructInfos to include in closedness checking. 259 inDisjunct int 260 261 // inConstaint overrides inDisjunct as field matching should always be 262 // enabled. 263 inConstraint int 264 265 // inValidator defines whether full evaluation need to be enforced, for 266 // instance when comparing against bottom. 267 inValidator int 268 269 // The current call is a validator. A builtin may return a boolean false 270 // along with an error message describing a validation error. If the latter 271 // is wrapped in an internal.ValidationError, it will only be interpreted 272 // as an error if this is true. 273 // TODO: strictly separate validators and functions. 274 IsValidator bool 275 276 // ErrorGraphs contains an analysis, represented as a Mermaid graph, for 277 // each node that has an error. 278 ErrorGraphs map[string]string 279 } 280 281 func (c *OpContext) CloseInfo() CloseInfo { return c.ci } 282 283 func (n *nodeContext) skipNonMonotonicChecks() bool { 284 if n.ctx.inConstraint > 0 { 285 return false 286 } 287 return n.ctx.inDisjunct > 0 288 } 289 290 // Impl is for internal use only. This will go. 291 func (c *OpContext) Impl() Runtime { 292 return c.Runtime 293 } 294 295 func (c *OpContext) Pos() token.Pos { 296 if c.src == nil { 297 return token.NoPos 298 } 299 return c.src.Pos() 300 } 301 302 func (c *OpContext) Source() ast.Node { 303 return c.src 304 } 305 306 // NewContext creates an operation context. 307 func NewContext(r Runtime, v *Vertex) *OpContext { 308 return New(v, &Config{Runtime: r}) 309 } 310 311 func (c *OpContext) pos() token.Pos { 312 if c.src == nil { 313 return token.NoPos 314 } 315 return c.src.Pos() 316 } 317 318 func (c *OpContext) spawn(node *Vertex) *Environment { 319 return spawn(c.e, node) 320 } 321 322 func spawn(env *Environment, node *Vertex) *Environment { 323 return &Environment{ 324 Up: env, 325 Vertex: node, 326 } 327 } 328 329 func (c *OpContext) Env(upCount int32) *Environment { 330 return c.e.up(c, upCount) 331 } 332 333 func (c *OpContext) relNode(upCount int32) *Vertex { 334 e := c.e.up(c, upCount) 335 c.unify(e.Vertex, oldOnly(partial)) 336 return e.Vertex 337 } 338 339 func (c *OpContext) relLabel(upCount int32) Feature { 340 // locate current label. 341 e := c.e.up(c, upCount) 342 return e.DynamicLabel 343 } 344 345 func (c *OpContext) concreteIsPossible(op Op, x Expr) bool { 346 if !AssertConcreteIsPossible(op, x) { 347 // No need to take position of expression. 348 c.AddErr(c.NewPosf(token.NoPos, 349 "invalid operand %s ('%s' requires concrete value)", x, op)) 350 return false 351 } 352 return true 353 } 354 355 // Assert that the given expression can evaluate to a concrete value. 356 func AssertConcreteIsPossible(op Op, x Expr) bool { 357 switch v := x.(type) { 358 case *Bottom: 359 case *BoundExpr: 360 return false 361 case Value: 362 return v.Concreteness() == Concrete 363 } 364 return true 365 } 366 367 // HasErr reports whether any error was reported, including whether value 368 // was incomplete. 369 func (c *OpContext) HasErr() bool { 370 return c.errs != nil 371 } 372 373 func (c *OpContext) Err() *Bottom { 374 b := c.errs 375 c.errs = nil 376 return b 377 } 378 379 func (c *OpContext) addErrf(code ErrorCode, pos token.Pos, msg string, args ...interface{}) { 380 err := c.NewPosf(pos, msg, args...) 381 c.addErr(code, err) 382 } 383 384 func (c *OpContext) addErr(code ErrorCode, err errors.Error) { 385 c.AddBottom(&Bottom{Code: code, Err: err}) 386 } 387 388 // AddBottom records an error in OpContext. 389 func (c *OpContext) AddBottom(b *Bottom) { 390 c.errs = CombineErrors(c.src, c.errs, b) 391 } 392 393 // AddErr records an error in OpContext. It returns errors collected so far. 394 func (c *OpContext) AddErr(err errors.Error) *Bottom { 395 if err != nil { 396 c.AddBottom(&Bottom{Err: err}) 397 } 398 return c.errs 399 } 400 401 // NewErrf creates a *Bottom value and returns it. The returned uses the 402 // current source as the point of origin of the error. 403 func (c *OpContext) NewErrf(format string, args ...interface{}) *Bottom { 404 // TODO: consider renaming ot NewBottomf: this is now confusing as we also 405 // have Newf. 406 err := c.Newf(format, args...) 407 return &Bottom{Src: c.src, Err: err, Code: EvalError} 408 } 409 410 // AddErrf records an error in OpContext. It returns errors collected so far. 411 func (c *OpContext) AddErrf(format string, args ...interface{}) *Bottom { 412 return c.AddErr(c.Newf(format, args...)) 413 } 414 415 type frame struct { 416 env *Environment 417 err *Bottom 418 src ast.Node 419 ci CloseInfo 420 } 421 422 func (c *OpContext) PushState(env *Environment, src ast.Node) (saved frame) { 423 saved.env = c.e 424 saved.err = c.errs 425 saved.src = c.src 426 saved.ci = c.ci 427 428 c.errs = nil 429 if src != nil { 430 c.src = src 431 } 432 c.e = env 433 434 return saved 435 } 436 437 func (c *OpContext) PushConjunct(x Conjunct) (saved frame) { 438 src := x.Expr().Source() 439 440 saved.env = c.e 441 saved.err = c.errs 442 saved.src = c.src 443 saved.ci = c.ci 444 445 c.errs = nil 446 if src != nil { 447 c.src = src 448 } 449 c.e = x.Env 450 c.ci = x.CloseInfo 451 452 return saved 453 } 454 455 func (c *OpContext) PopState(s frame) *Bottom { 456 err := c.errs 457 c.e = s.env 458 c.errs = s.err 459 c.src = s.src 460 c.ci = s.ci 461 return err 462 } 463 464 // PushArc signals c that arc v is currently being processed for the purpose 465 // of error reporting. PopArc should be called with the returned value once 466 // processing of v is completed. 467 func (c *OpContext) PushArc(v *Vertex) (saved *Vertex) { 468 c.vertex, saved = v, c.vertex 469 return saved 470 } 471 472 // PopArc signals completion of processing the current arc. 473 func (c *OpContext) PopArc(saved *Vertex) { 474 c.vertex = saved 475 } 476 477 // Resolve finds a node in the tree. 478 // 479 // Should only be used to insert Conjuncts. TODO: perhaps only return Conjuncts 480 // and error. 481 func (c *OpContext) Resolve(x Conjunct, r Resolver) (*Vertex, *Bottom) { 482 return c.resolveState(x, r, final(finalized, allKnown)) 483 } 484 485 func (c *OpContext) resolveState(x Conjunct, r Resolver, state combinedFlags) (*Vertex, *Bottom) { 486 s := c.PushConjunct(x) 487 488 arc := r.resolve(c, state) 489 490 err := c.PopState(s) 491 if err != nil { 492 return nil, err 493 } 494 495 if arc.ChildErrors != nil && arc.ChildErrors.Code == StructuralCycleError { 496 return nil, arc.ChildErrors 497 } 498 499 // Dereference any vertices that do not contribute to more knownledge about 500 // the node. 501 arc = arc.DerefNonRooted() 502 503 return arc, err 504 } 505 506 // Lookup looks up r in env without further resolving the value. 507 func (c *OpContext) Lookup(env *Environment, r Resolver) (*Vertex, *Bottom) { 508 s := c.PushState(env, r.Source()) 509 510 arc := r.resolve(c, oldOnly(partial)) 511 512 err := c.PopState(s) 513 514 if arc != nil && !c.isDevVersion() { 515 // TODO(deref): lookup should probably not use DerefValue, but 516 // rather only dereference disjunctions. 517 arc = arc.DerefValue() 518 } 519 520 return arc, err 521 } 522 523 // Validate calls validates value for the given validator. 524 // 525 // TODO(errors): return boolean instead: only the caller has enough information 526 // to generate a proper error message. 527 func (c *OpContext) Validate(check Validator, value Value) *Bottom { 528 // TODO: use a position stack to push both values. 529 saved := c.src 530 c.src = check.Source() 531 532 err := check.validate(c, value) 533 534 c.src = saved 535 536 return err 537 } 538 539 // concrete returns the concrete value of x after evaluating it. 540 // msg is used to mention the context in which an error occurred, if any. 541 func (c *OpContext) concrete(env *Environment, x Expr, msg interface{}) (result Value, complete bool) { 542 s := c.PushState(env, x.Source()) 543 544 state := require(partial, concreteKnown) 545 w := c.evalState(x, state) 546 _ = c.PopState(s) 547 548 w, ok := c.getDefault(w) 549 if !ok { 550 return w, false 551 } 552 v := Unwrap(w) 553 554 complete = w != nil 555 if !IsConcrete(v) { 556 complete = false 557 b := c.NewErrf("non-concrete value %v in operand to %s", w, msg) 558 b.Code = IncompleteError 559 v = b 560 } 561 562 return v, complete 563 } 564 565 // getDefault resolves a disjunction to a single value. If there is no default 566 // value, or if there is more than one default value, it reports an "incomplete" 567 // error and return false. In all other cases it will return true, even if 568 // v is already an error. v may be nil, in which case it will also return nil. 569 func (c *OpContext) getDefault(v Value) (result Value, ok bool) { 570 var d *Disjunction 571 switch x := v.(type) { 572 default: 573 return v, true 574 575 case *Vertex: 576 // TODO: return vertex if not disjunction. 577 switch t := x.BaseValue.(type) { 578 case *Disjunction: 579 d = t 580 581 case *Vertex: 582 return c.getDefault(t) 583 584 default: 585 return x, true 586 } 587 588 case *Disjunction: 589 d = x 590 } 591 592 if d.NumDefaults != 1 { 593 c.addErrf(IncompleteError, c.pos(), 594 "unresolved disjunction %v (type %s)", d, d.Kind()) 595 return nil, false 596 } 597 return c.getDefault(d.Values[0]) 598 } 599 600 // Evaluate evaluates an expression within the given environment and indicates 601 // whether the result is complete. It will always return a non-nil result. 602 func (c *OpContext) Evaluate(env *Environment, x Expr) (result Value, complete bool) { 603 s := c.PushState(env, x.Source()) 604 605 val := c.evalState(x, final(partial, concreteKnown)) 606 607 complete = true 608 609 if err, _ := val.(*Bottom); err != nil && err.IsIncomplete() { 610 complete = false 611 } 612 if val == nil { 613 complete = false 614 // TODO ENSURE THIS DOESN"T HAPPEN> 615 val = &Bottom{ 616 Code: IncompleteError, 617 Err: c.Newf("UNANTICIPATED ERROR"), 618 } 619 620 } 621 622 _ = c.PopState(s) 623 624 if !complete || val == nil { 625 return val, false 626 } 627 628 return val, true 629 } 630 631 func (c *OpContext) evaluateRec(v Conjunct, state combinedFlags) Value { 632 x := v.Expr() 633 s := c.PushConjunct(v) 634 635 val := c.evalState(x, state) 636 if val == nil { 637 // Be defensive: this never happens, but just in case. 638 Assertf(c, false, "nil return value: unspecified error") 639 val = &Bottom{ 640 Code: IncompleteError, 641 Err: c.Newf("UNANTICIPATED ERROR"), 642 } 643 } 644 _ = c.PopState(s) 645 646 return val 647 } 648 649 // value evaluates expression v within the current environment. The result may 650 // be nil if the result is incomplete. value leaves errors untouched to that 651 // they can be collected by the caller. 652 func (c *OpContext) value(x Expr, state combinedFlags) (result Value) { 653 v := c.evalState(x, state) 654 655 v, _ = c.getDefault(v) 656 v = Unwrap(v) 657 return v 658 } 659 660 func (c *OpContext) evalState(v Expr, state combinedFlags) (result Value) { 661 savedSrc := c.src 662 c.src = v.Source() 663 err := c.errs 664 c.errs = nil 665 666 defer func() { 667 c.errs = CombineErrors(c.src, c.errs, err) 668 669 if v, ok := result.(*Vertex); ok { 670 if b := v.Bottom(); b != nil { 671 switch b.Code { 672 case IncompleteError: 673 case CycleError: 674 if state.vertexStatus() == partial || c.isDevVersion() { 675 break 676 } 677 fallthrough 678 default: 679 result = b 680 } 681 } 682 } 683 684 // TODO: remove this when we handle errors more principally. 685 if b, ok := result.(*Bottom); ok { 686 result = c.wrapCycleError(c.src, b) 687 if c.errs != result { 688 c.errs = CombineErrors(c.src, c.errs, result) 689 } 690 } 691 if c.errs != nil { 692 result = c.errs 693 } 694 c.src = savedSrc 695 }() 696 697 switch x := v.(type) { 698 case Value: 699 return x 700 701 case Evaluator: 702 v := x.evaluate(c, state) 703 return v 704 705 case Resolver: 706 arc := x.resolve(c, state) 707 if c.HasErr() { 708 return nil 709 } 710 if arc == nil { 711 return nil 712 } 713 // TODO(deref): what is the right level of dereferencing here? 714 // DerefValue seems to work too. 715 arc = arc.DerefNonShared() 716 717 // TODO: consider moving this after markCycle, depending on how we 718 // implement markCycle, or whether we need it at all. 719 // TODO: is this indirect necessary? 720 // arc = arc.Indirect() 721 722 // Save the old CloseInfo and restore after evaluate to avoid detecting 723 // spurious cycles. 724 saved := c.ci 725 n := arc.state 726 if c.isDevVersion() { 727 n = arc.getState(c) 728 } 729 if n != nil { 730 c.ci, _ = n.markCycle(arc, nil, x, c.ci) 731 } 732 c.ci.Inline = true 733 734 if c.isDevVersion() { 735 if s := arc.getState(c); s != nil { 736 needs := state.conditions() 737 runMode := state.runMode() 738 739 arc.unify(c, needs|arcTypeKnown, attemptOnly) // to set scalar 740 741 if runMode == finalize { 742 // arc.unify(c, needs, attemptOnly) // to set scalar 743 // Freeze node. 744 arc.state.freeze(needs) 745 } else { 746 arc.unify(c, needs, runMode) 747 } 748 749 v := arc 750 if v.ArcType == ArcPending { 751 if v.status == evaluating { 752 for ; v.Parent != nil && v.ArcType == ArcPending; v = v.Parent { 753 } 754 err := c.Newf("cycle with field %v", x) 755 b := &Bottom{Code: CycleError, Err: err} 756 v.setValue(c, v.status, b) 757 return b 758 // TODO: use this instead, as is usual for incomplete errors, 759 // and also move this block one scope up to also apply to 760 // defined arcs. In both cases, though, doing so results in 761 // some errors to be misclassified as evaluation error. 762 // c.AddBottom(b) 763 // return nil 764 } 765 c.undefinedFieldError(v, IncompleteError) 766 return nil 767 } 768 } 769 } 770 v := c.evaluate(arc, x, state) 771 c.ci = saved 772 return v 773 774 default: 775 // This can only happen, really, if v == nil, which is not allowed. 776 panic(fmt.Sprintf("unexpected Expr type %T", v)) 777 } 778 } 779 780 // wrapCycleError converts the sentinel cycleError in a concrete one with 781 // position information. 782 func (c *OpContext) wrapCycleError(src ast.Node, b *Bottom) *Bottom { 783 if src != nil && 784 b.Code == CycleError && 785 len(errors.Positions(b.Err)) == 0 { 786 bb := *b 787 bb.Err = errors.Wrapf(b.Err, src.Pos(), "") 788 b = &bb 789 } 790 return b 791 } 792 793 // unifyNode returns a possibly partially evaluated node value. 794 // 795 // TODO: maybe return *Vertex, *Bottom 796 func (c *OpContext) unifyNode(v Expr, state combinedFlags) (result Value) { 797 savedSrc := c.src 798 c.src = v.Source() 799 err := c.errs 800 c.errs = nil 801 802 defer func() { 803 c.errs = CombineErrors(c.src, c.errs, err) 804 805 if v, ok := result.(*Vertex); ok { 806 if b := v.Bottom(); b != nil && !b.IsIncomplete() { 807 result = b 808 } 809 } 810 811 // TODO: remove this when we handle errors more principally. 812 if b, ok := result.(*Bottom); ok { 813 if c.src != nil && 814 b.Code == CycleError && 815 b.Err.Position() == token.NoPos && 816 len(b.Err.InputPositions()) == 0 { 817 bb := *b 818 bb.Err = errors.Wrapf(b.Err, c.src.Pos(), "") 819 result = &bb 820 } 821 c.errs = CombineErrors(c.src, c.errs, result) 822 } 823 if c.errs != nil { 824 result = c.errs 825 } 826 c.src = savedSrc 827 }() 828 829 switch x := v.(type) { 830 case Value: 831 return x 832 833 case Evaluator: 834 v := x.evaluate(c, state) 835 return v 836 837 case Resolver: 838 v := x.resolve(c, state) 839 if c.HasErr() { 840 return nil 841 } 842 if v == nil { 843 return nil 844 } 845 v = v.DerefValue() 846 847 // TODO: consider moving this after markCycle, depending on how we 848 // implement markCycle, or whether we need it at all. 849 // TODO: is this indirect necessary? 850 // v = v.Indirect() 851 852 if c.isDevVersion() { 853 if n := v.getState(c); n != nil { 854 // Always yield to not get spurious errors. 855 n.process(arcTypeKnown, yield) 856 } 857 } else { 858 if v.isUndefined() || state.vertexStatus() > v.status { 859 c.unify(v, state) 860 } 861 } 862 863 return v 864 865 default: 866 // This can only happen, really, if v == nil, which is not allowed. 867 panic(fmt.Sprintf("unexpected Expr type %T", v)) 868 } 869 } 870 871 func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, flags combinedFlags) *Vertex { 872 if c.isDevVersion() { 873 return x.lookup(c, pos, l, flags) 874 } 875 876 state := flags.vertexStatus() 877 878 if l == InvalidLabel || x == nil { 879 // TODO: is it possible to have an invalid label here? Maybe through the 880 // API? 881 return &Vertex{} 882 } 883 884 // var kind Kind 885 // if x.BaseValue != nil { 886 // kind = x.BaseValue.Kind() 887 // } 888 889 switch x.BaseValue.(type) { 890 case *StructMarker: 891 if l.Typ() == IntLabel { 892 c.addErrf(0, pos, "invalid struct selector %v (type int)", l) 893 return nil 894 } 895 896 case *ListMarker: 897 switch { 898 case l.Typ() == IntLabel: 899 switch { 900 case l.Index() < 0: 901 c.addErrf(0, pos, "invalid list index %v (index must be non-negative)", l) 902 return nil 903 case l.Index() > len(x.Arcs): 904 c.addErrf(0, pos, "invalid list index %v (out of bounds)", l) 905 return nil 906 } 907 908 case l.IsDef(), l.IsHidden(), l.IsLet(): 909 910 default: 911 c.addErrf(0, pos, "invalid list index %v (type string)", l) 912 return nil 913 } 914 915 case nil: 916 // c.addErrf(IncompleteError, pos, "incomplete value %s", x) 917 // return nil 918 919 case *Bottom: 920 921 default: 922 kind := x.BaseValue.Kind() 923 if kind&(ListKind|StructKind) != 0 { 924 // c.addErrf(IncompleteError, pos, 925 // "cannot look up %s in incomplete type %s (type %s)", 926 // l, x.Source(), kind) 927 // return nil 928 } else if !l.IsDef() && !l.IsHidden() && !l.IsLet() { 929 c.addErrf(0, pos, 930 "invalid selector %v for value of type %s", l, kind) 931 return nil 932 } 933 } 934 935 a := x.Lookup(l) 936 937 var hasCycle bool 938 939 if a != nil { 940 // Ensure that a's status is at least of the required level. Otherwise, 941 // ensure that any remaining unprocessed conjuncts are processed by 942 // calling c.Unify(a, Partial). The ensures that need to rely on 943 // hasAllConjuncts, but that are finalized too early, get conjuncts 944 // processed beforehand. 945 if state > a.status { 946 c.unify(a, deprecated(c, state)) 947 } else if a.state != nil { 948 c.unify(a, deprecated(c, partial)) 949 } 950 951 if a.IsConstraint() { 952 code := IncompleteError 953 if hasCycle { 954 code = CycleError 955 } 956 label := l.SelectorString(c.Runtime) 957 c.AddBottom(&Bottom{ 958 Code: code, 959 Permanent: x.status >= conjuncts, 960 Err: c.NewPosf(pos, 961 "cannot reference optional field: %s", label), 962 }) 963 } 964 } else { 965 if x.state != nil { 966 x.state.assertInitialized() 967 968 for _, e := range x.state.exprs { 969 if isCyclePlaceholder(e.err) { 970 hasCycle = true 971 } 972 } 973 } 974 code := IncompleteError 975 // As long as we have incomplete information, we cannot mark the 976 // inability to look up a field as "final", as it may resolve down the 977 // line. 978 permanent := x.status >= conjuncts 979 if m, _ := x.BaseValue.(*ListMarker); m != nil && !m.IsOpen { 980 permanent = true 981 } 982 if (state > partial || permanent) && !x.Accept(c, l) { 983 code = 0 984 } else if hasCycle { 985 code = CycleError 986 } 987 // TODO: if the struct was a literal struct, we can also treat it as 988 // closed and make this a permanent error. 989 label := l.SelectorString(c.Runtime) 990 991 // TODO(errors): add path reference and make message 992 // "undefined field %s in %s" 993 var err *ValueError 994 switch { 995 case isCyclePlaceholder(x.BaseValue): 996 err = c.NewPosf(pos, "cycle error referencing %s", label) 997 permanent = false 998 case l.IsInt(): 999 err = c.NewPosf(pos, "index out of range [%d] with length %d", 1000 l.Index(), len(x.Elems())) 1001 default: 1002 err = c.NewPosf(pos, "undefined field: %s", label) 1003 } 1004 c.AddBottom(&Bottom{ 1005 Code: code, 1006 Permanent: permanent, 1007 Err: err, 1008 }) 1009 } 1010 return a 1011 } 1012 1013 func (c *OpContext) undefinedFieldError(v *Vertex, code ErrorCode) { 1014 label := v.Label.SelectorString(c) 1015 c.addErrf(code, c.pos(), "undefined field: %s", label) 1016 } 1017 1018 func (c *OpContext) Label(src Expr, x Value) Feature { 1019 return LabelFromValue(c, src, x) 1020 } 1021 1022 func (c *OpContext) typeError(v Value, k Kind) { 1023 if isError(v) { 1024 return 1025 } 1026 if !IsConcrete(v) && v.Kind()&k != 0 { 1027 c.addErrf(IncompleteError, pos(v), "incomplete %s: %s", k, v) 1028 } else { 1029 c.AddErrf("cannot use %s (type %s) as type %s", v, v.Kind(), k) 1030 } 1031 } 1032 1033 func (c *OpContext) typeErrorAs(v Value, k Kind, as interface{}) { 1034 if as == nil { 1035 c.typeError(v, k) 1036 return 1037 } 1038 if isError(v) { 1039 return 1040 } 1041 if !IsConcrete(v) && v.Kind()&k != 0 { 1042 c.addErrf(IncompleteError, pos(v), 1043 "incomplete %s in %v: %s", k, as, v) 1044 } else { 1045 c.AddErrf("cannot use %s (type %s) as type %s in %v", v, v.Kind(), k, as) 1046 } 1047 } 1048 1049 var emptyNode = &Vertex{} 1050 1051 func pos(x Node) token.Pos { 1052 if x.Source() == nil { 1053 return token.NoPos 1054 } 1055 return x.Source().Pos() 1056 } 1057 1058 func (c *OpContext) node(orig Node, x Expr, scalar bool, state combinedFlags) *Vertex { 1059 // TODO: always get the vertex. This allows a whole bunch of trickery 1060 // down the line. 1061 v := c.unifyNode(x, state) 1062 1063 v, ok := c.getDefault(v) 1064 if !ok { 1065 // Error already generated by getDefault. 1066 return emptyNode 1067 } 1068 1069 // The two if blocks below are rather subtle. If we have an error of 1070 // the sentinel value cycle, we have earlier determined that the cycle is 1071 // allowed and that it can be ignored here. Any other CycleError is an 1072 // annotated cycle error that could be taken as is. 1073 // TODO: do something simpler. 1074 if scalar { 1075 if w := Unwrap(v); !isCyclePlaceholder(w) { 1076 v = w 1077 } 1078 } 1079 1080 node, ok := v.(*Vertex) 1081 if ok && !isCyclePlaceholder(node.BaseValue) { 1082 v = node.Value() 1083 } 1084 1085 switch nv := v.(type) { 1086 case nil: 1087 c.addErrf(IncompleteError, pos(x), 1088 "%s undefined (%s is incomplete)", orig, x) 1089 return emptyNode 1090 1091 case *Bottom: 1092 // TODO: this is a bit messy. In some cases errors are already added 1093 // and in some cases not. Not a huge deal, as errors will be uniqued 1094 // down the line, but could be better. 1095 c.AddBottom(nv) 1096 return emptyNode 1097 1098 case *Vertex: 1099 if node == nil { 1100 panic("unexpected markers with nil node") 1101 } 1102 1103 default: 1104 if kind := v.Kind(); kind&StructKind != 0 { 1105 c.addErrf(IncompleteError, pos(x), 1106 "%s undefined as %s is incomplete (type %s)", orig, x, kind) 1107 return emptyNode 1108 1109 } else if !ok { 1110 c.addErrf(0, pos(x), // TODO(error): better message. 1111 "invalid operand %s (found %s, want list or struct)", 1112 x.Source(), v.Kind()) 1113 return emptyNode 1114 } 1115 } 1116 1117 return node 1118 } 1119 1120 // Elems returns the evaluated elements of a list. 1121 func (c *OpContext) Elems(v Value) []*Vertex { 1122 list := c.list(v) 1123 list.Finalize(c) 1124 return list.Elems() 1125 } 1126 1127 // RawElems returns the elements of the list without evaluating them. 1128 func (c *OpContext) RawElems(v Value) []*Vertex { 1129 list := c.list(v) 1130 return list.Elems() 1131 } 1132 1133 func (c *OpContext) list(v Value) *Vertex { 1134 x, ok := v.(*Vertex) 1135 if !ok || !x.IsList() { 1136 c.typeError(v, ListKind) 1137 return emptyNode 1138 } 1139 return x 1140 } 1141 1142 func (c *OpContext) scalar(v Value) Value { 1143 v = Unwrap(v) 1144 switch v.(type) { 1145 case *Null, *Bool, *Num, *String, *Bytes: 1146 default: 1147 c.typeError(v, ScalarKinds) 1148 } 1149 return v 1150 } 1151 1152 var zero = &Num{K: NumberKind} 1153 1154 func (c *OpContext) Num(v Value, as interface{}) *Num { 1155 v = Unwrap(v) 1156 if isError(v) { 1157 return zero 1158 } 1159 x, ok := v.(*Num) 1160 if !ok { 1161 c.typeErrorAs(v, NumberKind, as) 1162 return zero 1163 } 1164 return x 1165 } 1166 1167 func (c *OpContext) Int64(v Value) int64 { 1168 v = Unwrap(v) 1169 if isError(v) { 1170 return 0 1171 } 1172 x, ok := v.(*Num) 1173 if !ok { 1174 c.typeError(v, IntKind) 1175 return 0 1176 } 1177 i, err := x.X.Int64() 1178 if err != nil { 1179 c.AddErrf("number is not an int64: %v", err) 1180 return 0 1181 } 1182 return i 1183 } 1184 1185 func (c *OpContext) uint64(v Value, as string) uint64 { 1186 v = Unwrap(v) 1187 if isError(v) { 1188 return 0 1189 } 1190 x, ok := v.(*Num) 1191 if !ok { 1192 c.typeErrorAs(v, IntKind, as) 1193 return 0 1194 } 1195 if x.X.Negative { 1196 // TODO: improve message 1197 c.AddErrf("cannot convert negative number to uint64") 1198 return 0 1199 } 1200 if !x.X.Coeff.IsUint64() { 1201 // TODO: improve message 1202 c.AddErrf("cannot convert number %s to uint64", &x.X) 1203 return 0 1204 } 1205 return x.X.Coeff.Uint64() 1206 } 1207 1208 func (c *OpContext) BoolValue(v Value) bool { 1209 return c.boolValue(v, nil) 1210 } 1211 1212 func (c *OpContext) boolValue(v Value, as interface{}) bool { 1213 v = Unwrap(v) 1214 if isError(v) { 1215 return false 1216 } 1217 x, ok := v.(*Bool) 1218 if !ok { 1219 c.typeErrorAs(v, BoolKind, as) 1220 return false 1221 } 1222 return x.B 1223 } 1224 1225 func (c *OpContext) StringValue(v Value) string { 1226 return c.stringValue(v, nil) 1227 } 1228 1229 // ToBytes returns the bytes value of a scalar value. 1230 func (c *OpContext) ToBytes(v Value) []byte { 1231 if x, ok := v.(*Bytes); ok { 1232 return x.B 1233 } 1234 return []byte(c.ToString(v)) 1235 } 1236 1237 // ToString returns the string value of a scalar value. 1238 func (c *OpContext) ToString(v Value) string { 1239 return c.toStringValue(v, StringKind|NumberKind|BytesKind|BoolKind, nil) 1240 1241 } 1242 1243 func (c *OpContext) stringValue(v Value, as interface{}) string { 1244 return c.toStringValue(v, StringKind, as) 1245 } 1246 1247 func (c *OpContext) toStringValue(v Value, k Kind, as interface{}) string { 1248 v = Unwrap(v) 1249 if isError(v) { 1250 return "" 1251 } 1252 if v.Kind()&k == 0 { 1253 if as == nil { 1254 c.typeError(v, k) 1255 } else { 1256 c.typeErrorAs(v, k, as) 1257 } 1258 return "" 1259 } 1260 switch x := v.(type) { 1261 case *String: 1262 return x.Str 1263 1264 case *Bytes: 1265 return bytesToString(x.B) 1266 1267 case *Num: 1268 return x.X.String() 1269 1270 case *Bool: 1271 if x.B { 1272 return "true" 1273 } 1274 return "false" 1275 1276 default: 1277 c.addErrf(IncompleteError, c.pos(), 1278 "non-concrete value %s (type %s)", v, v.Kind()) 1279 } 1280 return "" 1281 } 1282 1283 func bytesToString(b []byte) string { 1284 b, _ = unicode.UTF8.NewDecoder().Bytes(b) 1285 return string(b) 1286 } 1287 1288 func (c *OpContext) bytesValue(v Value, as interface{}) []byte { 1289 v = Unwrap(v) 1290 if isError(v) { 1291 return nil 1292 } 1293 x, ok := v.(*Bytes) 1294 if !ok { 1295 c.typeErrorAs(v, BytesKind, as) 1296 return nil 1297 } 1298 return x.B 1299 } 1300 1301 var matchNone = regexp.MustCompile("^$") 1302 1303 func (c *OpContext) regexp(v Value) *regexp.Regexp { 1304 v = Unwrap(v) 1305 if isError(v) { 1306 return matchNone 1307 } 1308 switch x := v.(type) { 1309 case *String: 1310 if x.RE != nil { 1311 return x.RE 1312 } 1313 // TODO: synchronization 1314 p, err := regexp.Compile(x.Str) 1315 if err != nil { 1316 // FatalError? How to cache error 1317 c.AddErrf("invalid regexp: %s", err) 1318 x.RE = matchNone 1319 } else { 1320 x.RE = p 1321 } 1322 return x.RE 1323 1324 case *Bytes: 1325 if x.RE != nil { 1326 return x.RE 1327 } 1328 // TODO: synchronization 1329 p, err := regexp.Compile(string(x.B)) 1330 if err != nil { 1331 c.AddErrf("invalid regexp: %s", err) 1332 x.RE = matchNone 1333 } else { 1334 x.RE = p 1335 } 1336 return x.RE 1337 1338 default: 1339 c.typeError(v, StringKind|BytesKind) 1340 return matchNone 1341 } 1342 } 1343 1344 // newNum creates a new number of the given kind. It reports an error value 1345 // instead if any error occurred. 1346 func (c *OpContext) newNum(d *apd.Decimal, k Kind, sources ...Node) Value { 1347 if c.HasErr() { 1348 return c.Err() 1349 } 1350 return &Num{Src: c.src, X: *d, K: k} 1351 } 1352 1353 func (c *OpContext) NewInt64(n int64, sources ...Node) Value { 1354 if c.HasErr() { 1355 return c.Err() 1356 } 1357 d := apd.New(n, 0) 1358 return &Num{Src: c.src, X: *d, K: IntKind} 1359 } 1360 1361 func (c *OpContext) NewString(s string) Value { 1362 if c.HasErr() { 1363 return c.Err() 1364 } 1365 return &String{Src: c.src, Str: s} 1366 } 1367 1368 func (c *OpContext) newBytes(b []byte) Value { 1369 if c.HasErr() { 1370 return c.Err() 1371 } 1372 return &Bytes{Src: c.src, B: b} 1373 } 1374 1375 func (c *OpContext) newBool(b bool) Value { 1376 if c.HasErr() { 1377 return c.Err() 1378 } 1379 return &Bool{Src: c.src, B: b} 1380 } 1381 1382 func (c *OpContext) newList(src ast.Node, parent *Vertex) *Vertex { 1383 return c.newInlineVertex(parent, &ListMarker{}) 1384 } 1385 1386 // Str reports a debug string of x. 1387 func (c *OpContext) Str(x Node) string { 1388 if c.Format == nil { 1389 return fmt.Sprintf("%T", x) 1390 } 1391 return c.Format(c.Runtime, x) 1392 } 1393 1394 // NewList returns a new list for the given values. 1395 func (c *OpContext) NewList(values ...Value) *Vertex { 1396 // TODO: consider making this a literal list instead. 1397 list := &ListLit{} 1398 v := c.newInlineVertex(nil, nil, Conjunct{Env: nil, x: list}) 1399 1400 for _, x := range values { 1401 list.Elems = append(list.Elems, x) 1402 } 1403 v.Finalize(c) 1404 return v 1405 }