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