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