...

Source file src/cuelang.org/go/internal/core/adt/expr.go

Documentation: cuelang.org/go/internal/core/adt

     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  	"bytes"
    19  	"fmt"
    20  	"io"
    21  	"regexp"
    22  
    23  	"github.com/cockroachdb/apd/v3"
    24  
    25  	"cuelang.org/go/cue/ast"
    26  	"cuelang.org/go/cue/errors"
    27  	"cuelang.org/go/cue/token"
    28  )
    29  
    30  var _ Elem = &ConjunctGroup{}
    31  
    32  // A ConjunctGroup is an Elem that is used for internal grouping of Conjuncts
    33  // only.
    34  type ConjunctGroup []Conjunct
    35  
    36  func (g *ConjunctGroup) Source() ast.Node {
    37  	return nil
    38  }
    39  
    40  // A StructLit represents an unevaluated struct literal or file body.
    41  type StructLit struct {
    42  	Src   ast.Node // ast.File or ast.StructLit
    43  	Decls []Decl
    44  
    45  	// TODO: record the merge order somewhere.
    46  
    47  	// The below fields are redundant to Decls and are computed with Init.
    48  
    49  	// field marks the optional conjuncts of all explicit Fields.
    50  	// Required Fields are marked as empty
    51  	Fields []FieldInfo
    52  
    53  	Dynamic []*DynamicField
    54  
    55  	// excluded are all literal fields that already exist.
    56  	Bulk []*BulkOptionalField
    57  
    58  	Additional  []*Ellipsis
    59  	HasEmbed    bool
    60  	IsOpen      bool // has a ...
    61  	initialized bool
    62  
    63  	types OptionalType
    64  
    65  	// administrative fields like hasreferences.
    66  	// hasReferences bool
    67  }
    68  
    69  func (o *StructLit) IsFile() bool {
    70  	_, ok := o.Src.(*ast.File)
    71  	return ok
    72  }
    73  
    74  type FieldInfo struct {
    75  	Label Feature
    76  }
    77  
    78  func (x *StructLit) HasOptional() bool {
    79  	return x.types&(HasPattern|HasAdditional) != 0
    80  }
    81  
    82  func (x *StructLit) Source() ast.Node { return x.Src }
    83  
    84  func (x *StructLit) evaluate(c *OpContext, state combinedFlags) Value {
    85  	e := c.Env(0)
    86  	v := c.newInlineVertex(e.Vertex, nil, Conjunct{e, x, c.ci})
    87  	// evaluate may not finalize a field, as the resulting value may be
    88  	// used in a context where more conjuncts are added. It may also lead
    89  	// to disjuncts being in a partially expanded state, leading to
    90  	// misaligned nodeContexts.
    91  	v.CompleteArcs(c)
    92  	return v
    93  }
    94  
    95  // TODO: remove this method
    96  func (o *StructLit) MarkField(f Feature) {
    97  	o.Fields = append(o.Fields, FieldInfo{Label: f})
    98  }
    99  
   100  func (o *StructLit) Init() {
   101  	if o.initialized {
   102  		return
   103  	}
   104  	o.initialized = true
   105  	for _, d := range o.Decls {
   106  		switch x := d.(type) {
   107  		case *Field:
   108  			if o.fieldIndex(x.Label) < 0 {
   109  				o.Fields = append(o.Fields, FieldInfo{Label: x.Label})
   110  			}
   111  			if x.ArcType > ArcMember {
   112  				o.types |= HasField
   113  			}
   114  
   115  		case *LetField:
   116  			if o.fieldIndex(x.Label) >= 0 {
   117  				panic("duplicate let identifier")
   118  			}
   119  			o.Fields = append(o.Fields, FieldInfo{Label: x.Label})
   120  
   121  		case *DynamicField:
   122  			o.Dynamic = append(o.Dynamic, x)
   123  			o.types |= HasDynamic
   124  
   125  		case Expr:
   126  			o.HasEmbed = true
   127  
   128  		case *Comprehension:
   129  			o.HasEmbed = true
   130  
   131  		case *LetClause:
   132  			o.HasEmbed = true
   133  
   134  		case *BulkOptionalField:
   135  			o.Bulk = append(o.Bulk, x)
   136  			o.types |= HasPattern
   137  			switch x.Filter.(type) {
   138  			case *BasicType, *Top:
   139  			default:
   140  				o.types |= HasComplexPattern
   141  			}
   142  
   143  		case *Ellipsis:
   144  			switch x.Value.(type) {
   145  			case nil, *Top:
   146  				o.IsOpen = true
   147  				o.types |= IsOpen
   148  
   149  			default:
   150  				// TODO: consider only adding for non-top.
   151  				o.types |= HasAdditional
   152  			}
   153  			o.Additional = append(o.Additional, x)
   154  
   155  		default:
   156  			panic("unreachable")
   157  		}
   158  	}
   159  }
   160  
   161  func (o *StructLit) fieldIndex(f Feature) int {
   162  	for i := range o.Fields {
   163  		if o.Fields[i].Label == f {
   164  			return i
   165  		}
   166  	}
   167  	return -1
   168  }
   169  
   170  func (o *StructLit) OptionalTypes() OptionalType {
   171  	return o.types
   172  }
   173  
   174  // FIELDS
   175  //
   176  // Fields can also be used as expressions whereby the value field is the
   177  // expression this allows retaining more context.
   178  
   179  // Field represents a regular field or field constraint with a fixed label.
   180  // The label can be a regular field, definition or hidden field.
   181  //
   182  //	foo: bar
   183  //	#foo: bar
   184  //	_foo: bar
   185  //
   186  // Legacy:
   187  //
   188  //	Foo :: bar
   189  type Field struct {
   190  	Src *ast.Field
   191  
   192  	ArcType ArcType
   193  	Label   Feature
   194  	Value   Expr
   195  }
   196  
   197  func (x *Field) Source() ast.Node {
   198  	if x.Src == nil {
   199  		return nil
   200  	}
   201  	return x.Src
   202  }
   203  
   204  // A LetField represents a field that is only visible in the local scope.
   205  //
   206  //	let X = expr
   207  type LetField struct {
   208  	Src   *ast.LetClause
   209  	Label Feature
   210  	// IsMulti is true when this let field should be replicated for each
   211  	// incarnation. This is the case when its expression refers to the
   212  	// variables of a for comprehension embedded within a struct.
   213  	IsMulti bool
   214  	Value   Expr
   215  }
   216  
   217  func (x *LetField) Source() ast.Node {
   218  	if x.Src == nil {
   219  		return nil
   220  	}
   221  	return x.Src
   222  }
   223  
   224  // A BulkOptionalField represents a set of optional field.
   225  //
   226  //	[expr]: expr
   227  type BulkOptionalField struct {
   228  	Src    *ast.Field // Ellipsis or Field
   229  	Filter Expr
   230  	Value  Expr
   231  	Label  Feature // for reference and formatting
   232  }
   233  
   234  func (x *BulkOptionalField) Source() ast.Node {
   235  	if x.Src == nil {
   236  		return nil
   237  	}
   238  	return x.Src
   239  }
   240  
   241  // A Ellipsis represents a set of optional fields of a given type.
   242  //
   243  //	...T
   244  type Ellipsis struct {
   245  	Src   *ast.Ellipsis
   246  	Value Expr
   247  }
   248  
   249  func (x *Ellipsis) Source() ast.Node {
   250  	if x.Src == nil {
   251  		return nil
   252  	}
   253  	return x.Src
   254  }
   255  
   256  // A DynamicField represents a regular field for which the key is computed.
   257  //
   258  //	"\(expr)": expr
   259  //	(expr): expr
   260  type DynamicField struct {
   261  	Src *ast.Field
   262  
   263  	ArcType ArcType
   264  	Key     Expr
   265  	Value   Expr
   266  }
   267  
   268  func (x *DynamicField) Source() ast.Node {
   269  	if x.Src == nil {
   270  		return nil
   271  	}
   272  	return x.Src
   273  }
   274  
   275  // A ListLit represents an unevaluated list literal.
   276  //
   277  //	[a, for x in src { ... }, b, ...T]
   278  type ListLit struct {
   279  	Src *ast.ListLit
   280  
   281  	// scalars, comprehensions, ...T
   282  	Elems []Elem
   283  
   284  	info *StructLit // Shared closedness info.
   285  }
   286  
   287  func (x *ListLit) Source() ast.Node {
   288  	if x.Src == nil {
   289  		return nil
   290  	}
   291  	return x.Src
   292  }
   293  
   294  func (x *ListLit) evaluate(c *OpContext, state combinedFlags) Value {
   295  	e := c.Env(0)
   296  	v := c.newInlineVertex(e.Vertex, nil, Conjunct{e, x, c.ci})
   297  	v.CompleteArcs(c)
   298  	return v
   299  }
   300  
   301  // Null represents null. It can be used as a Value and Expr.
   302  type Null struct {
   303  	Src ast.Node
   304  }
   305  
   306  func (x *Null) Source() ast.Node { return x.Src }
   307  func (x *Null) Kind() Kind       { return NullKind }
   308  
   309  // Bool is a boolean value. It can be used as a Value and Expr.
   310  type Bool struct {
   311  	Src ast.Node
   312  	B   bool
   313  }
   314  
   315  func (x *Bool) Source() ast.Node { return x.Src }
   316  func (x *Bool) Kind() Kind       { return BoolKind }
   317  
   318  // Num is a numeric value. It can be used as a Value and Expr.
   319  type Num struct {
   320  	Src ast.Node
   321  	K   Kind        // needed?
   322  	X   apd.Decimal // Is integer if the apd.Decimal is an integer.
   323  }
   324  
   325  // TODO: do we need this?
   326  // func NewNumFromString(src ast.Node, s string) Value {
   327  // 	n := &Num{Src: src, K: IntKind}
   328  // 	if strings.ContainsAny(s, "eE.") {
   329  // 		n.K = FloatKind
   330  // 	}
   331  // 	_, _, err := n.X.SetString(s)
   332  // 	if err != nil {
   333  // 		pos := token.NoPos
   334  // 		if src != nil {
   335  // 			pos = src.Pos()
   336  // 		}
   337  // 		return &Bottom{Err: errors.Newf(pos, "invalid number: %v", err)}
   338  // 	}
   339  // 	return n
   340  // }
   341  
   342  func (x *Num) Source() ast.Node { return x.Src }
   343  func (x *Num) Kind() Kind       { return x.K }
   344  
   345  // TODO: do we still need this?
   346  // func (x *Num) Specialize(k Kind) Value {
   347  // 	k = k & x.K
   348  // 	if k == x.K {
   349  // 		return x
   350  // 	}
   351  // 	y := *x
   352  // 	y.K = k
   353  // 	return &y
   354  // }
   355  
   356  // String is a string value. It can be used as a Value and Expr.
   357  type String struct {
   358  	Src ast.Node
   359  	Str string
   360  	RE  *regexp.Regexp // only set if needed
   361  }
   362  
   363  func (x *String) Source() ast.Node { return x.Src }
   364  func (x *String) Kind() Kind       { return StringKind }
   365  
   366  // Bytes is a bytes value. It can be used as a Value and Expr.
   367  type Bytes struct {
   368  	Src ast.Node
   369  	B   []byte
   370  	RE  *regexp.Regexp // only set if needed
   371  }
   372  
   373  func (x *Bytes) Source() ast.Node { return x.Src }
   374  func (x *Bytes) Kind() Kind       { return BytesKind }
   375  
   376  // Composites: the evaluated fields of a composite are recorded in the arc
   377  // vertices.
   378  
   379  type ListMarker struct {
   380  	Src    ast.Expr
   381  	IsOpen bool
   382  }
   383  
   384  func (x *ListMarker) Source() ast.Node { return x.Src }
   385  func (x *ListMarker) Kind() Kind       { return ListKind }
   386  func (x *ListMarker) node()            {}
   387  
   388  type StructMarker struct {
   389  	// NeedClose is used to signal that the evaluator should close this struct.
   390  	// It is only set by the close builtin.
   391  	NeedClose bool
   392  }
   393  
   394  func (x *StructMarker) Source() ast.Node { return nil }
   395  func (x *StructMarker) Kind() Kind       { return StructKind }
   396  func (x *StructMarker) node()            {}
   397  
   398  // Top represents all possible values. It can be used as a Value and Expr.
   399  type Top struct{ Src *ast.Ident }
   400  
   401  func (x *Top) Source() ast.Node {
   402  	if x.Src == nil {
   403  		return nil
   404  	}
   405  	return x.Src
   406  }
   407  func (x *Top) Kind() Kind { return TopKind }
   408  
   409  // BasicType represents all values of a certain Kind. It can be used as a Value
   410  // and Expr.
   411  //
   412  //	string
   413  //	int
   414  //	num
   415  //	bool
   416  type BasicType struct {
   417  	Src ast.Node
   418  	K   Kind
   419  }
   420  
   421  func (x *BasicType) Source() ast.Node {
   422  	if x.Src == nil {
   423  		return nil
   424  	}
   425  	return x.Src
   426  }
   427  func (x *BasicType) Kind() Kind { return x.K }
   428  
   429  // TODO: do we still need this?
   430  // func (x *BasicType) Specialize(k Kind) Value {
   431  // 	k = x.K & k
   432  // 	if k == x.K {
   433  // 		return x
   434  // 	}
   435  // 	y := *x
   436  // 	y.K = k
   437  // 	return &y
   438  // }
   439  
   440  // TODO: should we use UnaryExpr for Bound now we have BoundValue?
   441  
   442  // BoundExpr represents an unresolved unary comparator.
   443  //
   444  //	<a
   445  //	=~MyPattern
   446  type BoundExpr struct {
   447  	Src  *ast.UnaryExpr
   448  	Op   Op
   449  	Expr Expr
   450  }
   451  
   452  func (x *BoundExpr) Source() ast.Node {
   453  	if x.Src == nil {
   454  		return nil
   455  	}
   456  	return x.Src
   457  }
   458  
   459  func (x *BoundExpr) evaluate(ctx *OpContext, state combinedFlags) Value {
   460  	// scalarKnown is used here to ensure we know the value. The result does
   461  	// not have to be concrete, though.
   462  	v := ctx.value(x.Expr, require(partial, scalarKnown))
   463  	if isError(v) {
   464  		return v
   465  	}
   466  
   467  	switch k := v.Kind(); k {
   468  	case IntKind, FloatKind, NumKind, StringKind, BytesKind:
   469  	case NullKind:
   470  		if x.Op != NotEqualOp {
   471  			err := ctx.NewPosf(pos(x.Expr),
   472  				"cannot use null for bound %s", x.Op)
   473  			return &Bottom{Err: err}
   474  		}
   475  	default:
   476  		mask := IntKind | FloatKind | NumKind | StringKind | BytesKind
   477  		if x.Op == NotEqualOp {
   478  			mask |= NullKind
   479  		}
   480  		if k&mask != 0 {
   481  			ctx.addErrf(IncompleteError, token.NoPos, // TODO(errors): use ctx.pos()?
   482  				"non-concrete value %s for bound %s", x.Expr, x.Op)
   483  			return nil
   484  		}
   485  		err := ctx.NewPosf(pos(x.Expr),
   486  			"invalid value %s (type %s) for bound %s", v, k, x.Op)
   487  		return &Bottom{Err: err}
   488  	}
   489  
   490  	if v, ok := x.Expr.(Value); ok {
   491  		if v == nil || v.Concreteness() > Concrete {
   492  			return ctx.NewErrf("bound has fixed non-concrete value")
   493  		}
   494  		return &BoundValue{x.Src, x.Op, v}
   495  	}
   496  
   497  	// This simplifies boundary expressions. It is an alternative to an
   498  	// evaluation strategy that makes nodes increasingly more specific.
   499  	//
   500  	// For instance, a completely different implementation would be to allow
   501  	// the presence of a concrete value to ignore incomplete errors.
   502  	//
   503  	// TODO: consider an alternative approach.
   504  	switch y := v.(type) {
   505  	case *BoundValue:
   506  		switch {
   507  		case y.Op == NotEqualOp:
   508  			switch x.Op {
   509  			case LessEqualOp, LessThanOp, GreaterEqualOp, GreaterThanOp:
   510  				// <(!=3)  =>  number
   511  				// Smaller than an arbitrarily large number is any number.
   512  				return &BasicType{K: y.Kind()}
   513  			case NotEqualOp:
   514  				// !=(!=3) ==> 3
   515  				// Not a value that is anything but a given value is that
   516  				// given value.
   517  				return y.Value
   518  			}
   519  
   520  		case x.Op == NotEqualOp:
   521  			// Invert if applicable.
   522  			switch y.Op {
   523  			case LessEqualOp:
   524  				return &BoundValue{x.Src, GreaterThanOp, y.Value}
   525  			case LessThanOp:
   526  				return &BoundValue{x.Src, GreaterEqualOp, y.Value}
   527  			case GreaterEqualOp:
   528  				return &BoundValue{x.Src, LessThanOp, y.Value}
   529  			case GreaterThanOp:
   530  				return &BoundValue{x.Src, LessEqualOp, y.Value}
   531  			}
   532  
   533  		case (x.Op == LessThanOp || x.Op == LessEqualOp) &&
   534  			(y.Op == GreaterThanOp || y.Op == GreaterEqualOp),
   535  			(x.Op == GreaterThanOp || x.Op == GreaterEqualOp) &&
   536  				(y.Op == LessThanOp || y.Op == LessEqualOp):
   537  			// <(>=3)
   538  			// Something smaller than an arbitrarily large number is any number.
   539  			return &BasicType{K: y.Kind()}
   540  
   541  		case x.Op == LessThanOp &&
   542  			(y.Op == LessEqualOp || y.Op == LessThanOp),
   543  			x.Op == GreaterThanOp &&
   544  				(y.Op == GreaterEqualOp || y.Op == GreaterThanOp):
   545  			// <(<=x)  => <x
   546  			// <(<x)   => <x
   547  			// Less than something that is less or equal to x is less than x.
   548  			return &BoundValue{x.Src, x.Op, y.Value}
   549  
   550  		case x.Op == LessEqualOp &&
   551  			(y.Op == LessEqualOp || y.Op == LessThanOp),
   552  			x.Op == GreaterEqualOp &&
   553  				(y.Op == GreaterEqualOp || y.Op == GreaterThanOp):
   554  			// <=(<x)   => <x
   555  			// <=(<=x)  => <=x
   556  			// Less or equal than something that is less than x is less than x.
   557  			return y
   558  		}
   559  
   560  	case *BasicType:
   561  		switch x.Op {
   562  		case LessEqualOp, LessThanOp, GreaterEqualOp, GreaterThanOp:
   563  			// TODO: this does not seem correct and results in some weird
   564  			// behavior for bounds.
   565  			ctx.addErrf(IncompleteError, token.NoPos,
   566  				"non-concrete value %s for bound %s", x.Expr, x.Op)
   567  			return nil
   568  		}
   569  	}
   570  	if v.Concreteness() > Concrete {
   571  		// TODO(errors): analyze dependencies of x.Expr to get positions.
   572  		ctx.addErrf(IncompleteError, token.NoPos, // TODO(errors): use ctx.pos()?
   573  			"non-concrete value %s for bound %s", x.Expr, x.Op)
   574  		return nil
   575  	}
   576  	return &BoundValue{x.Src, x.Op, v}
   577  }
   578  
   579  // A BoundValue is a fully evaluated unary comparator that can be used to
   580  // validate other values.
   581  //
   582  //	<5
   583  //	=~"Name$"
   584  type BoundValue struct {
   585  	Src   ast.Expr
   586  	Op    Op
   587  	Value Value
   588  }
   589  
   590  func (x *BoundValue) Source() ast.Node { return x.Src }
   591  func (x *BoundValue) Kind() Kind {
   592  	k := x.Value.Kind()
   593  	switch k {
   594  	case IntKind, FloatKind, NumKind:
   595  		return NumKind
   596  
   597  	case NullKind:
   598  		if x.Op == NotEqualOp {
   599  			return TopKind &^ NullKind
   600  		}
   601  	}
   602  	return k
   603  }
   604  
   605  func (x *BoundValue) validate(c *OpContext, y Value) *Bottom {
   606  	a := y // Can be list or struct.
   607  	b := c.scalar(x.Value)
   608  	if c.HasErr() {
   609  		return c.Err()
   610  	}
   611  
   612  	switch v := BinOp(c, x.Op, a, b).(type) {
   613  	case *Bottom:
   614  		return v
   615  
   616  	case *Bool:
   617  		if v.B {
   618  			return nil
   619  		}
   620  		// TODO(errors): use "invalid value %v (not an %s)" if x is a
   621  		// predeclared identifier such as `int`.
   622  		err := c.Newf("invalid value %v (out of bound %s)", y, x)
   623  		err.AddPosition(y)
   624  		return &Bottom{Src: c.src, Err: err, Code: EvalError}
   625  
   626  	default:
   627  		panic(fmt.Sprintf("unsupported type %T", v))
   628  	}
   629  }
   630  
   631  func (x *BoundValue) validateStr(c *OpContext, a string) bool {
   632  	if str, ok := x.Value.(*String); ok {
   633  		b := str.Str
   634  		switch x.Op {
   635  		case LessEqualOp:
   636  			return a <= b
   637  		case LessThanOp:
   638  			return a < b
   639  		case GreaterEqualOp:
   640  			return a >= b
   641  		case GreaterThanOp:
   642  			return a > b
   643  		case EqualOp:
   644  			return a == b
   645  		case NotEqualOp:
   646  			return a != b
   647  		case MatchOp:
   648  			return c.regexp(x.Value).MatchString(a)
   649  		case NotMatchOp:
   650  			return !c.regexp(x.Value).MatchString(a)
   651  		}
   652  	}
   653  	return x.validate(c, &String{Str: a}) == nil
   654  }
   655  
   656  func (x *BoundValue) validateInt(c *OpContext, a int64) bool {
   657  	switch n := x.Value.(type) {
   658  	case *Num:
   659  		b, err := n.X.Int64()
   660  		if err != nil {
   661  			break
   662  		}
   663  		switch x.Op {
   664  		case LessEqualOp:
   665  			return a <= b
   666  		case LessThanOp:
   667  			return a < b
   668  		case GreaterEqualOp:
   669  			return a >= b
   670  		case GreaterThanOp:
   671  			return a > b
   672  		case EqualOp:
   673  			return a == b
   674  		case NotEqualOp:
   675  			return a != b
   676  		}
   677  	}
   678  	return x.validate(c, c.NewInt64(a)) == nil
   679  }
   680  
   681  // A NodeLink is used during computation to refer to an existing Vertex.
   682  // It is used to signal a potential cycle or reference.
   683  // Note that a NodeLink may be used as a value. This should be taken into
   684  // account.
   685  type NodeLink struct {
   686  	Node *Vertex
   687  }
   688  
   689  func (x *NodeLink) Kind() Kind {
   690  	return x.Node.Kind()
   691  }
   692  func (x *NodeLink) Source() ast.Node { return x.Node.Source() }
   693  
   694  func (x *NodeLink) resolve(c *OpContext, state combinedFlags) *Vertex {
   695  	return x.Node
   696  }
   697  
   698  // A FieldReference represents a lexical reference to a field.
   699  //
   700  //	a
   701  type FieldReference struct {
   702  	Src     *ast.Ident
   703  	UpCount int32
   704  	Label   Feature
   705  }
   706  
   707  func (x *FieldReference) Source() ast.Node {
   708  	if x.Src == nil {
   709  		return nil
   710  	}
   711  	return x.Src
   712  }
   713  
   714  func (x *FieldReference) resolve(c *OpContext, state combinedFlags) *Vertex {
   715  	n := c.relNode(x.UpCount)
   716  	pos := pos(x)
   717  	return c.lookup(n, pos, x.Label, state)
   718  }
   719  
   720  // A ValueReference represents a lexical reference to a value.
   721  //
   722  // Example: an X referring to
   723  //
   724  //	a: X=b
   725  type ValueReference struct {
   726  	Src     *ast.Ident
   727  	UpCount int32
   728  	Label   Feature // for informative purposes
   729  }
   730  
   731  func (x *ValueReference) Source() ast.Node {
   732  	if x.Src == nil {
   733  		return nil
   734  	}
   735  	return x.Src
   736  }
   737  
   738  func (x *ValueReference) resolve(c *OpContext, state combinedFlags) *Vertex {
   739  	if x.UpCount == 0 {
   740  		return c.vertex
   741  	}
   742  	n := c.relNode(x.UpCount - 1)
   743  	return n
   744  }
   745  
   746  // A LabelReference refers to the string or integer value of a label.
   747  //
   748  // Example: an X referring to
   749  //
   750  //	[X=Pattern]: b: a
   751  type LabelReference struct {
   752  	Src     *ast.Ident
   753  	UpCount int32
   754  }
   755  
   756  // TODO: should this implement resolver at all?
   757  
   758  func (x *LabelReference) Source() ast.Node {
   759  	if x.Src == nil {
   760  		return nil
   761  	}
   762  	return x.Src
   763  }
   764  
   765  func (x *LabelReference) evaluate(ctx *OpContext, state combinedFlags) Value {
   766  	label := ctx.relLabel(x.UpCount)
   767  	if label == 0 {
   768  		// There is no label. This may happen if a LabelReference is evaluated
   769  		// outside of the context of a parent node, for instance if an
   770  		// "additional" items or properties is evaluated in isolation.
   771  		//
   772  		// TODO: this should return the pattern of the label.
   773  		return &BasicType{K: StringKind}
   774  	}
   775  	return label.ToValue(ctx)
   776  }
   777  
   778  // A DynamicReference is like a FieldReference, but with a computed label.
   779  //
   780  // Example: an X referring to
   781  //
   782  //	X=(x): v
   783  //	X="\(x)": v
   784  //	X=[string]: v
   785  type DynamicReference struct {
   786  	Src     *ast.Ident
   787  	UpCount int32
   788  	Label   Expr
   789  
   790  	// TODO: only use aliases and store the actual expression only in the scope.
   791  	// The feature is unique for every instance. This will also allow dynamic
   792  	// fields to be ordered among normal fields.
   793  	//
   794  	// This could also be used to assign labels to embedded values, if they
   795  	// don't match a label.
   796  	Alias Feature
   797  }
   798  
   799  func (x *DynamicReference) Source() ast.Node {
   800  	if x.Src == nil {
   801  		return nil
   802  	}
   803  	return x.Src
   804  }
   805  
   806  func (x *DynamicReference) EvaluateLabel(ctx *OpContext, env *Environment) Feature {
   807  	env = env.up(ctx, x.UpCount)
   808  	frame := ctx.PushState(env, x.Src)
   809  	v := ctx.value(x.Label, require(partial, scalarKnown))
   810  	ctx.PopState(frame)
   811  	return ctx.Label(x, v)
   812  }
   813  
   814  func (x *DynamicReference) resolve(ctx *OpContext, state combinedFlags) *Vertex {
   815  	e := ctx.Env(x.UpCount)
   816  	frame := ctx.PushState(e, x.Src)
   817  	v := ctx.value(x.Label, require(partial, scalarKnown))
   818  	ctx.PopState(frame)
   819  	f := ctx.Label(x.Label, v)
   820  	return ctx.lookup(e.Vertex, pos(x), f, state)
   821  }
   822  
   823  // An ImportReference refers to an imported package.
   824  //
   825  // Example: strings in
   826  //
   827  //	import "strings"
   828  //
   829  //	strings.ToLower("Upper")
   830  type ImportReference struct {
   831  	Src        *ast.Ident
   832  	ImportPath Feature
   833  	Label      Feature // for informative purposes
   834  }
   835  
   836  func (x *ImportReference) Source() ast.Node {
   837  	if x.Src == nil {
   838  		return nil
   839  	}
   840  	return x.Src
   841  }
   842  
   843  func (x *ImportReference) resolve(ctx *OpContext, state combinedFlags) *Vertex {
   844  	path := x.ImportPath.StringValue(ctx)
   845  	v := ctx.Runtime.LoadImport(path)
   846  	if v == nil {
   847  		ctx.addErrf(EvalError, x.Src.Pos(), "cannot find package %q", path)
   848  	}
   849  	return v
   850  }
   851  
   852  // A LetReference evaluates a let expression in its original environment.
   853  //
   854  // Example: an X referring to
   855  //
   856  //	let X = x
   857  type LetReference struct {
   858  	Src     *ast.Ident
   859  	UpCount int32
   860  	Label   Feature // for informative purposes
   861  	X       Expr
   862  }
   863  
   864  func (x *LetReference) Source() ast.Node {
   865  	if x.Src == nil {
   866  		return nil
   867  	}
   868  	return x.Src
   869  }
   870  
   871  func (x *LetReference) resolve(ctx *OpContext, state combinedFlags) *Vertex {
   872  	e := ctx.Env(x.UpCount)
   873  	n := e.Vertex
   874  
   875  	// No need to Unify n, as Let references can only result from evaluating
   876  	// an expression within n, in which case evaluation must already have
   877  	// started.
   878  	if n.status < evaluating && !ctx.isDevVersion() {
   879  		panic("unexpected node state < Evaluating")
   880  	}
   881  
   882  	arc := ctx.lookup(n, pos(x), x.Label, state)
   883  	if arc == nil {
   884  		return nil
   885  	}
   886  
   887  	// Using a let arc directly saves an allocation, but should not be done
   888  	// in the following circumstances:
   889  	// 1) multiple Environments to be resolved for a single let
   890  	// 2) in case of error: some errors, like structural cycles, may only
   891  	//    occur when an arc is resolved directly, but not when used in an
   892  	//    expression. Consider, for instance:
   893  	//
   894  	//        a: {
   895  	//            b: 1
   896  	//            let X = a  // structural cycle
   897  	//            c: X.b     // not a structural cycle
   898  	//        }
   899  	//
   900  	//     In other words, a Vertex is not necessarily erroneous when a let
   901  	//     field contained in that Vertex is erroneous.
   902  
   903  	// TODO(order): Do not finalize? Although it is safe to finalize a let
   904  	// by itself, it is not necessarily safe, at this point, to finalize any
   905  	// references it makes. Originally, let finalization was requested to
   906  	// detect cases where multi-mode should be enabled. With the recent compiler
   907  	// changes, though, this should be detected statically. Leave this on for
   908  	// now, though, as it is not entirely clear it is fine to remove this.
   909  	// We can reevaluate this once we have redone some of the planned order of
   910  	// evaluation work.
   911  	arc.Finalize(ctx)
   912  	b, ok := arc.BaseValue.(*Bottom)
   913  	if !arc.MultiLet && !ok {
   914  		return arc
   915  	}
   916  
   917  	// Not caching let expressions may lead to exponential behavior.
   918  	// The expr uses the expression of a Let field, which can never be used in
   919  	// any other context.
   920  	c := arc.Conjuncts[0]
   921  	expr := c.Expr()
   922  	key := cacheKey{expr, arc}
   923  	v, ok := e.cache[key]
   924  	if !ok {
   925  		// Link in the right environment to ensure comprehension context is not
   926  		// lost. Use a Vertex to piggyback on cycle processing.
   927  		c.Env = e
   928  		c.x = expr
   929  
   930  		if e.cache == nil {
   931  			e.cache = map[cacheKey]Value{}
   932  		}
   933  		n := &Vertex{
   934  			Parent:    arc.Parent,
   935  			Label:     x.Label,
   936  			IsDynamic: b != nil && b.Code == StructuralCycleError,
   937  			Conjuncts: []Conjunct{c},
   938  		}
   939  		v = n
   940  		e.cache[key] = n
   941  		if ctx.isDevVersion() {
   942  			nc := n.getState(ctx)
   943  			nc.hasNonCycle = true // Allow a first cycle to be skipped.
   944  			nc.free()
   945  		} else {
   946  			nc := n.getNodeContext(ctx, 0)
   947  			nc.hasNonCycle = true // Allow a first cycle to be skipped.
   948  		}
   949  
   950  		// Parents cannot add more conjuncts to a let expression, so set of
   951  		// conjuncts is always complete.
   952  		//
   953  		// NOTE(let finalization): as this let expression is not recorded as
   954  		// a subfield within its parent arc, setParentDone will not be called
   955  		// as part of normal processing. The same is true for finalization.
   956  		// The use of setParentDone has the additional effect that the arc
   957  		// will be finalized where it is needed. See the namesake NOTE for the
   958  		// location where this is triggered.
   959  		n.setParentDone()
   960  	}
   961  	return v.(*Vertex)
   962  }
   963  
   964  // A SelectorExpr looks up a fixed field in an expression.
   965  //
   966  //	a.sel
   967  type SelectorExpr struct {
   968  	Src *ast.SelectorExpr
   969  	X   Expr
   970  	Sel Feature
   971  }
   972  
   973  func (x *SelectorExpr) Source() ast.Node {
   974  	if x.Src == nil {
   975  		return nil
   976  	}
   977  	return x.Src
   978  }
   979  
   980  func (x *SelectorExpr) resolve(c *OpContext, state combinedFlags) *Vertex {
   981  	// TODO: the node should really be evaluated as AllConjunctsDone, but the
   982  	// order of evaluation is slightly off, causing too much to be evaluated.
   983  	// This may especially result in incorrect results when using embedded
   984  	// scalars.
   985  	// In the new evaluator, evaluation of the node is done in lookup.
   986  	n := c.node(x, x.X, x.Sel.IsRegular(), attempt(partial, needFieldSetKnown))
   987  	if n == emptyNode {
   988  		return n
   989  	}
   990  	if n.status == partial && !c.isDevVersion() {
   991  		if b := n.state.incompleteErrors(false); b != nil && b.Code < CycleError {
   992  			c.AddBottom(b)
   993  			return n
   994  		}
   995  	}
   996  	// TODO(eval): dynamic nodes should be fully evaluated here as the result
   997  	// will otherwise be discarded and there will be no other chance to check
   998  	// the struct is valid.
   999  
  1000  	pos := x.Src.Sel.Pos()
  1001  	return c.lookup(n, pos, x.Sel, state)
  1002  }
  1003  
  1004  // IndexExpr is like a selector, but selects an index.
  1005  //
  1006  //	a[index]
  1007  type IndexExpr struct {
  1008  	Src   *ast.IndexExpr
  1009  	X     Expr
  1010  	Index Expr
  1011  }
  1012  
  1013  func (x *IndexExpr) Source() ast.Node {
  1014  	if x.Src == nil {
  1015  		return nil
  1016  	}
  1017  	return x.Src
  1018  }
  1019  
  1020  func (x *IndexExpr) resolve(ctx *OpContext, state combinedFlags) *Vertex {
  1021  	// TODO: support byte index.
  1022  	// TODO: the node should really be evaluated as AllConjunctsDone, but the
  1023  	// order of evaluation is slightly off, causing too much to be evaluated.
  1024  	// This may especially result in incorrect results when using embedded
  1025  	// scalars.
  1026  	n := ctx.node(x, x.X, true, attempt(partial, needFieldSetKnown))
  1027  	i := ctx.value(x.Index, require(partial, scalarKnown))
  1028  	if n == emptyNode {
  1029  		return n
  1030  	}
  1031  	if n.status == partial && !ctx.isDevVersion() {
  1032  		if b := n.state.incompleteErrors(false); b != nil && b.Code < CycleError {
  1033  			ctx.AddBottom(b)
  1034  			return n
  1035  		}
  1036  	}
  1037  	// TODO(eval): dynamic nodes should be fully evaluated here as the result
  1038  	// will otherwise be discarded and there will be no other chance to check
  1039  	// the struct is valid.
  1040  
  1041  	f := ctx.Label(x.Index, i)
  1042  
  1043  	// Within lookup, errors collected in ctx may be associated with n. This is
  1044  	// correct if the error is generated within lookup, but not if it has
  1045  	// already been generated at this point. We therefore bail out early here if
  1046  	// we already have an error.
  1047  	// TODO: this code can probably go once we have cleaned up error generation.
  1048  	if ctx.errs != nil {
  1049  		return nil
  1050  	}
  1051  	pos := x.Src.Index.Pos()
  1052  	return ctx.lookup(n, pos, f, state)
  1053  }
  1054  
  1055  // A SliceExpr represents a slice operation. (Not currently in spec.)
  1056  //
  1057  //	X[Lo:Hi:Stride]
  1058  type SliceExpr struct {
  1059  	Src    *ast.SliceExpr
  1060  	X      Expr
  1061  	Lo     Expr
  1062  	Hi     Expr
  1063  	Stride Expr
  1064  }
  1065  
  1066  func (x *SliceExpr) Source() ast.Node {
  1067  	if x.Src == nil {
  1068  		return nil
  1069  	}
  1070  	return x.Src
  1071  }
  1072  
  1073  func (x *SliceExpr) evaluate(c *OpContext, state combinedFlags) Value {
  1074  	// TODO: strides
  1075  
  1076  	v := c.value(x.X, require(partial, fieldSetKnown))
  1077  	const as = "slice index"
  1078  
  1079  	switch v := v.(type) {
  1080  	case nil:
  1081  		c.addErrf(IncompleteError, c.pos(), "non-concrete slice subject %s", x.X)
  1082  		return nil
  1083  	case *Vertex:
  1084  		if !v.IsList() {
  1085  			break
  1086  		}
  1087  
  1088  		var (
  1089  			lo = uint64(0)
  1090  			hi = uint64(len(v.Arcs))
  1091  		)
  1092  		if x.Lo != nil {
  1093  			lo = c.uint64(c.value(x.Lo, require(partial, scalarKnown)), as)
  1094  		}
  1095  		if x.Hi != nil {
  1096  			hi = c.uint64(c.value(x.Hi, require(partial, scalarKnown)), as)
  1097  			if hi > uint64(len(v.Arcs)) {
  1098  				return c.NewErrf("index %d out of range", hi)
  1099  			}
  1100  		}
  1101  		if lo > hi {
  1102  			return c.NewErrf("invalid slice index: %d > %d", lo, hi)
  1103  		}
  1104  
  1105  		n := c.newList(c.src, v.Parent)
  1106  		for i, a := range v.Arcs[lo:hi] {
  1107  			label, err := MakeLabel(a.Source(), int64(i), IntLabel)
  1108  			if err != nil {
  1109  				c.AddBottom(&Bottom{Src: a.Source(), Err: err})
  1110  				return nil
  1111  			}
  1112  			arc := *a
  1113  			arc.Parent = n
  1114  			arc.Label = label
  1115  			n.Arcs = append(n.Arcs, &arc)
  1116  		}
  1117  		n.status = finalized
  1118  		return n
  1119  
  1120  	case *Bytes:
  1121  		var (
  1122  			lo = uint64(0)
  1123  			hi = uint64(len(v.B))
  1124  		)
  1125  		if x.Lo != nil {
  1126  			lo = c.uint64(c.value(x.Lo, require(partial, scalarKnown)), as)
  1127  		}
  1128  		if x.Hi != nil {
  1129  			hi = c.uint64(c.value(x.Hi, require(partial, scalarKnown)), as)
  1130  			if hi > uint64(len(v.B)) {
  1131  				return c.NewErrf("index %d out of range", hi)
  1132  			}
  1133  		}
  1134  		if lo > hi {
  1135  			return c.NewErrf("invalid slice index: %d > %d", lo, hi)
  1136  		}
  1137  		return c.newBytes(v.B[lo:hi])
  1138  	}
  1139  
  1140  	if isError(v) {
  1141  		return v
  1142  	}
  1143  	return c.NewErrf("cannot slice %v (type %s)", v, v.Kind())
  1144  }
  1145  
  1146  // An Interpolation is a string interpolation.
  1147  //
  1148  //	"a \(b) c"
  1149  type Interpolation struct {
  1150  	Src   *ast.Interpolation
  1151  	K     Kind   // string or bytes
  1152  	Parts []Expr // odd: strings, even sources
  1153  }
  1154  
  1155  func (x *Interpolation) Source() ast.Node {
  1156  	if x.Src == nil {
  1157  		return nil
  1158  	}
  1159  	return x.Src
  1160  }
  1161  
  1162  func (x *Interpolation) evaluate(c *OpContext, state combinedFlags) Value {
  1163  	buf := bytes.Buffer{}
  1164  	for _, e := range x.Parts {
  1165  		v := c.value(e, require(partial, scalarKnown))
  1166  		if x.K == BytesKind {
  1167  			buf.Write(c.ToBytes(v))
  1168  		} else {
  1169  			buf.WriteString(c.ToString(v))
  1170  		}
  1171  	}
  1172  	if err := c.Err(); err != nil {
  1173  		err = &Bottom{
  1174  			Code: err.Code,
  1175  			Err:  errors.Wrapf(err.Err, pos(x), "invalid interpolation"),
  1176  		}
  1177  		// c.AddBottom(err)
  1178  		// return nil
  1179  		return err
  1180  	}
  1181  	if x.K == BytesKind {
  1182  		return &Bytes{x.Src, buf.Bytes(), nil}
  1183  	}
  1184  	return &String{x.Src, buf.String(), nil}
  1185  }
  1186  
  1187  // UnaryExpr is a unary expression.
  1188  //
  1189  //	Op X
  1190  //	-X !X +X
  1191  type UnaryExpr struct {
  1192  	Src *ast.UnaryExpr
  1193  	Op  Op
  1194  	X   Expr
  1195  }
  1196  
  1197  func (x *UnaryExpr) Source() ast.Node {
  1198  	if x.Src == nil {
  1199  		return nil
  1200  	}
  1201  	return x.Src
  1202  }
  1203  
  1204  func (x *UnaryExpr) evaluate(c *OpContext, state combinedFlags) Value {
  1205  	if !c.concreteIsPossible(x.Op, x.X) {
  1206  		return nil
  1207  	}
  1208  	v := c.value(x.X, require(partial, scalarKnown))
  1209  	if isError(v) {
  1210  		return v
  1211  	}
  1212  
  1213  	op := x.Op
  1214  	k := kind(v)
  1215  	expectedKind := k
  1216  	switch op {
  1217  	case SubtractOp:
  1218  		if v, ok := v.(*Num); ok {
  1219  			f := *v
  1220  			f.X.Neg(&v.X)
  1221  			f.Src = x.Src
  1222  			return &f
  1223  		}
  1224  		expectedKind = NumKind
  1225  
  1226  	case AddOp:
  1227  		if v, ok := v.(*Num); ok {
  1228  			// TODO: wrap in thunk to save position of '+'?
  1229  			return v
  1230  		}
  1231  		expectedKind = NumKind
  1232  
  1233  	case NotOp:
  1234  		if v, ok := v.(*Bool); ok {
  1235  			return &Bool{x.Src, !v.B}
  1236  		}
  1237  		expectedKind = BoolKind
  1238  	}
  1239  	if k&expectedKind != BottomKind {
  1240  		c.addErrf(IncompleteError, pos(x.X),
  1241  			"operand %s of '%s' not concrete (was %s)", x.X, op, k)
  1242  		return nil
  1243  	}
  1244  	return c.NewErrf("invalid operation %v (%s %s)", x, op, k)
  1245  }
  1246  
  1247  // BinaryExpr is a binary expression.
  1248  //
  1249  //	X + Y
  1250  //	X & Y
  1251  type BinaryExpr struct {
  1252  	Src *ast.BinaryExpr
  1253  	Op  Op
  1254  	X   Expr
  1255  	Y   Expr
  1256  }
  1257  
  1258  func (x *BinaryExpr) Source() ast.Node {
  1259  	if x.Src == nil {
  1260  		return nil
  1261  	}
  1262  	return x.Src
  1263  }
  1264  
  1265  func (x *BinaryExpr) evaluate(c *OpContext, state combinedFlags) Value {
  1266  	env := c.Env(0)
  1267  	if x.Op == AndOp {
  1268  		v := c.newInlineVertex(nil, nil, makeAnonymousConjunct(env, x, c.ci.Refs))
  1269  
  1270  		// Do not fully evaluate the Vertex: if it is embedded within a
  1271  		// struct with arcs that are referenced from within this expression,
  1272  		// it will end up adding "locked" fields, resulting in an error.
  1273  		// It will be the responsibility of the "caller" to get the result
  1274  		// to the required state. If the struct is already dynamic, we will
  1275  		// evaluate the struct regardless to ensure that cycle reporting
  1276  		// keeps working.
  1277  		if env.Vertex.IsDynamic || c.inValidator > 0 {
  1278  			v.Finalize(c)
  1279  		} else {
  1280  			v.CompleteArcs(c)
  1281  		}
  1282  
  1283  		return v
  1284  	}
  1285  
  1286  	if !c.concreteIsPossible(x.Op, x.X) || !c.concreteIsPossible(x.Op, x.Y) {
  1287  		return nil
  1288  	}
  1289  
  1290  	// TODO: allow comparing to a literal Bottom only. Find something more
  1291  	// principled perhaps. One should especially take care that two values
  1292  	// evaluating to Bottom don't evaluate to true. For now we check for
  1293  	// Bottom here and require that one of the values be a Bottom literal.
  1294  	if x.Op == EqualOp || x.Op == NotEqualOp {
  1295  		if isLiteralBottom(x.X) {
  1296  			return c.validate(env, x.Src, x.Y, x.Op, state)
  1297  		}
  1298  		if isLiteralBottom(x.Y) {
  1299  			return c.validate(env, x.Src, x.X, x.Op, state)
  1300  		}
  1301  	}
  1302  
  1303  	left, _ := c.concrete(env, x.X, x.Op)
  1304  	right, _ := c.concrete(env, x.Y, x.Op)
  1305  
  1306  	if err := CombineErrors(x.Src, left, right); err != nil {
  1307  		return err
  1308  	}
  1309  
  1310  	if err := c.Err(); err != nil {
  1311  		return err
  1312  	}
  1313  
  1314  	return BinOp(c, x.Op, left, right)
  1315  }
  1316  
  1317  func (c *OpContext) validate(env *Environment, src ast.Node, x Expr, op Op, flags combinedFlags) (r Value) {
  1318  	state := flags.vertexStatus()
  1319  
  1320  	s := c.PushState(env, src)
  1321  
  1322  	match := op != EqualOp // non-error case
  1323  
  1324  	// Like value(), but retain the original, unwrapped result.
  1325  	c.inValidator++
  1326  	req := flags
  1327  	req = final(state, needTasksDone)
  1328  	v := c.evalState(x, req)
  1329  	c.inValidator--
  1330  	u, _ := c.getDefault(v)
  1331  	u = Unwrap(u)
  1332  
  1333  	// If our final (unwrapped) value is potentially a recursive structure, we
  1334  	// still need to recursively check for errors. We do so by treating it
  1335  	// as the original value, which if it is a Vertex will be evaluated
  1336  	// recursively below.
  1337  	if u != nil && u.Kind().IsAnyOf(StructKind|ListKind) {
  1338  		u = v
  1339  	}
  1340  
  1341  	switch v := u.(type) {
  1342  	case nil:
  1343  	case *Bottom:
  1344  		switch v.Code {
  1345  		case CycleError:
  1346  			c.PopState(s)
  1347  			c.AddBottom(v)
  1348  			// TODO: add this. This erases some
  1349  			// c.verifyNonMonotonicResult(env, x, true)
  1350  			return nil
  1351  
  1352  		case IncompleteError:
  1353  			c.evalState(x, oldOnly(finalized))
  1354  
  1355  			// We have a nonmonotonic use of a failure. Referenced fields should
  1356  			// not be added anymore.
  1357  			c.verifyNonMonotonicResult(env, x, true)
  1358  		}
  1359  
  1360  		match = op == EqualOp
  1361  
  1362  	case *Vertex:
  1363  		// TODO(cycle): if EqualOp:
  1364  		// - ensure to pass special status to if clause or keep a track of "hot"
  1365  		//   paths.
  1366  		// - evaluate hypothetical struct
  1367  		// - walk over all fields and verify that fields are not contradicting
  1368  		//   previously marked fields.
  1369  		//
  1370  		v.Finalize(c)
  1371  
  1372  		if v.status == evaluatingArcs {
  1373  			// We have a cycle, which may be an error. Cycle errors may occur
  1374  			// in chains that are themselves not a cycle. It suffices to check
  1375  			// for non-monotonic results at the end for this particular path.
  1376  			// TODO(perf): finding the right path through such comprehensions
  1377  			// may be expensive. Finding a path in a directed graph is O(n),
  1378  			// though, so we should ensure that the implementation conforms to
  1379  			// this.
  1380  			c.verifyNonMonotonicResult(env, x, true)
  1381  			match = op == EqualOp
  1382  			break
  1383  		}
  1384  
  1385  		switch {
  1386  		case !v.IsDefined(c):
  1387  			c.verifyNonMonotonicResult(env, x, true) // TODO: remove?
  1388  
  1389  			// TODO: mimic comparison to bottom semantics. If it is a valid
  1390  			// value, check for concreteness that this level only. This
  1391  			// should ultimately be replaced with an exists and valid
  1392  			// builtin.
  1393  			match = op == EqualOp
  1394  
  1395  		case isFinalError(v):
  1396  			// Need to recursively check for errors, so we need to evaluate the
  1397  			// Vertex in case it hadn't been evaluated yet.
  1398  			match = op == EqualOp
  1399  		}
  1400  
  1401  	default:
  1402  		if v.Kind().IsAnyOf(CompositKind) && v.Concreteness() > Concrete && state < conjuncts {
  1403  			c.PopState(s)
  1404  			c.AddBottom(cycle)
  1405  			return nil
  1406  		}
  1407  
  1408  		c.verifyNonMonotonicResult(env, x, false)
  1409  
  1410  		if v.Concreteness() > Concrete {
  1411  			// TODO: mimic comparison to bottom semantics. If it is a valid
  1412  			// value, check for concreteness that this level only. This
  1413  			// should ultimately be replaced with an exists and valid
  1414  			// builtin.
  1415  			match = op == EqualOp
  1416  		}
  1417  
  1418  		c.evalState(x, require(state, needTasksDone))
  1419  	}
  1420  
  1421  	c.PopState(s)
  1422  	return &Bool{src, match}
  1423  }
  1424  
  1425  func isFinalError(n *Vertex) bool {
  1426  	n = n.Indirect()
  1427  	if b, ok := Unwrap(n).(*Bottom); ok && b.Code < IncompleteError {
  1428  		return true
  1429  	}
  1430  	return false
  1431  }
  1432  
  1433  // verifyNonMonotonicResult re-evaluates the given expression at a later point
  1434  // to ensure that the result has not changed. This is relevant when a function
  1435  // uses reflection, as in `if a != _|_`, where the result of an evaluation may
  1436  // change after the fact.
  1437  // expectError indicates whether the value should evaluate to an error or not.
  1438  func (c *OpContext) verifyNonMonotonicResult(env *Environment, x Expr, expectError bool) {
  1439  	if n := env.Vertex.state; n != nil {
  1440  		n.postChecks = append(n.postChecks, envCheck{
  1441  			env:         env,
  1442  			expr:        x,
  1443  			expectError: expectError,
  1444  		})
  1445  	}
  1446  }
  1447  
  1448  // A CallExpr represents a call to a builtin.
  1449  //
  1450  //	len(x)
  1451  //	strings.ToLower(x)
  1452  type CallExpr struct {
  1453  	Src  *ast.CallExpr
  1454  	Fun  Expr
  1455  	Args []Expr
  1456  }
  1457  
  1458  func (x *CallExpr) Source() ast.Node {
  1459  	if x.Src == nil {
  1460  		return nil
  1461  	}
  1462  	return x.Src
  1463  }
  1464  
  1465  func (x *CallExpr) evaluate(c *OpContext, state combinedFlags) Value {
  1466  	fun := c.value(x.Fun, require(partial, concreteKnown))
  1467  	var b *Builtin
  1468  	switch f := fun.(type) {
  1469  	case *Builtin:
  1470  		b = f
  1471  
  1472  	case *BuiltinValidator:
  1473  		// We allow a validator that takes no arguments accept the validated
  1474  		// value to be called with zero arguments.
  1475  		switch {
  1476  		case f.Src != nil:
  1477  			c.AddErrf("cannot call previously called validator %s", x.Fun)
  1478  
  1479  		case f.Builtin.IsValidator(len(x.Args)):
  1480  			v := *f
  1481  			v.Src = x
  1482  			return &v
  1483  
  1484  		default:
  1485  			b = f.Builtin
  1486  		}
  1487  
  1488  	default:
  1489  		c.AddErrf("cannot call non-function %s (type %s)", x.Fun, kind(fun))
  1490  		return nil
  1491  	}
  1492  	args := []Value{}
  1493  	for i, a := range x.Args {
  1494  		saved := c.errs
  1495  		c.errs = nil
  1496  		// XXX: XXX: clear id.closeContext per argument and remove from runTask?
  1497  
  1498  		runMode := state.runMode()
  1499  		cond := state.conditions() | allAncestorsProcessed | concreteKnown
  1500  		state = combineMode(cond, runMode).withVertexStatus(state.vertexStatus())
  1501  
  1502  		expr := c.value(a, state)
  1503  
  1504  		switch v := expr.(type) {
  1505  		case nil:
  1506  			if c.errs == nil {
  1507  				// There SHOULD be an error in the context. If not, we generate
  1508  				// one.
  1509  				c.Assertf(pos(x.Fun), c.HasErr(),
  1510  					"argument %d to function %s is incomplete", i, x.Fun)
  1511  			}
  1512  
  1513  		case *Bottom:
  1514  			// TODO(errors): consider adding an argument index for this errors.
  1515  			c.errs = CombineErrors(a.Source(), c.errs, v)
  1516  
  1517  		default:
  1518  			args = append(args, expr)
  1519  		}
  1520  		c.errs = CombineErrors(a.Source(), saved, c.errs)
  1521  	}
  1522  	if c.HasErr() {
  1523  		return nil
  1524  	}
  1525  	if b.IsValidator(len(args)) {
  1526  		return &BuiltinValidator{x, b, args}
  1527  	}
  1528  	result := b.call(c, pos(x), false, args)
  1529  	if result == nil {
  1530  		return nil
  1531  	}
  1532  	return c.evalState(result, state.withVertexStatus(partial))
  1533  }
  1534  
  1535  // A Builtin is a value representing a native function call.
  1536  type Builtin struct {
  1537  	// TODO:  make these values for better type checking.
  1538  	Params []Param
  1539  	Result Kind
  1540  	Func   func(c *OpContext, args []Value) Expr
  1541  
  1542  	Package Feature
  1543  	Name    string
  1544  }
  1545  
  1546  type Param struct {
  1547  	Name  Feature // name of the argument; mostly for documentation
  1548  	Value Value   // Could become Value later, using disjunctions for defaults.
  1549  }
  1550  
  1551  // Kind returns the kind mask of this parameter.
  1552  func (p Param) Kind() Kind {
  1553  	return p.Value.Kind()
  1554  }
  1555  
  1556  // Default reports the default value for this Param or nil if there is none.
  1557  func (p Param) Default() Value {
  1558  	d, ok := p.Value.(*Disjunction)
  1559  	if !ok || d.NumDefaults != 1 {
  1560  		return nil
  1561  	}
  1562  	return d.Values[0]
  1563  }
  1564  
  1565  func (x *Builtin) WriteName(w io.Writer, c *OpContext) {
  1566  	_, _ = fmt.Fprintf(w, "%s.%s", x.Package.StringValue(c), x.Name)
  1567  }
  1568  
  1569  // Kind here represents the case where Builtin is used as a Validator.
  1570  func (x *Builtin) Kind() Kind {
  1571  	return FuncKind
  1572  }
  1573  
  1574  func (x *Builtin) BareValidator() *BuiltinValidator {
  1575  	if len(x.Params) != 1 ||
  1576  		(x.Result != BoolKind && x.Result != BottomKind) {
  1577  		return nil
  1578  	}
  1579  	return &BuiltinValidator{Builtin: x}
  1580  }
  1581  
  1582  // IsValidator reports whether b should be interpreted as a Validator for the
  1583  // given number of arguments.
  1584  func (b *Builtin) IsValidator(numArgs int) bool {
  1585  	return numArgs == len(b.Params)-1 &&
  1586  		b.Result&^BoolKind == 0 &&
  1587  		b.Params[numArgs].Default() == nil
  1588  }
  1589  
  1590  func bottom(v Value) *Bottom {
  1591  	if x, ok := v.(*Vertex); ok {
  1592  		v = x.Value()
  1593  	}
  1594  	b, _ := v.(*Bottom)
  1595  	return b
  1596  }
  1597  
  1598  func (x *Builtin) call(c *OpContext, p token.Pos, validate bool, args []Value) Expr {
  1599  	fun := x // right now always x.
  1600  	if len(args) > len(x.Params) {
  1601  		c.addErrf(0, p,
  1602  			"too many arguments in call to %v (have %d, want %d)",
  1603  			fun, len(args), len(x.Params))
  1604  		return nil
  1605  	}
  1606  	for i := len(args); i < len(x.Params); i++ {
  1607  		v := x.Params[i].Default()
  1608  		if v == nil {
  1609  			c.addErrf(0, p,
  1610  				"not enough arguments in call to %v (have %d, want %d)",
  1611  				fun, len(args), len(x.Params))
  1612  			return nil
  1613  		}
  1614  		args = append(args, v)
  1615  	}
  1616  	for i, a := range args {
  1617  		if x.Params[i].Kind() == BottomKind {
  1618  			continue
  1619  		}
  1620  		if b := bottom(a); b != nil {
  1621  			return b
  1622  		}
  1623  		if k := kind(a); x.Params[i].Kind()&k == BottomKind {
  1624  			code := EvalError
  1625  			b, _ := args[i].(*Bottom)
  1626  			if b != nil {
  1627  				code = b.Code
  1628  			}
  1629  			c.addErrf(code, pos(a),
  1630  				"cannot use %s (type %s) as %s in argument %d to %v",
  1631  				a, k, x.Params[i].Kind(), i+1, fun)
  1632  			return nil
  1633  		}
  1634  		v := x.Params[i].Value
  1635  		if _, ok := v.(*BasicType); !ok {
  1636  			env := c.Env(0)
  1637  			x := &BinaryExpr{Op: AndOp, X: v, Y: a}
  1638  			n := c.newInlineVertex(nil, nil, Conjunct{env, x, c.ci})
  1639  			n.Finalize(c)
  1640  			if _, ok := n.BaseValue.(*Bottom); ok {
  1641  				c.addErrf(0, pos(a),
  1642  					"cannot use %s as %s in argument %d to %v",
  1643  					a, v, i+1, fun)
  1644  				return nil
  1645  			}
  1646  			args[i] = n
  1647  		}
  1648  	}
  1649  	saved := c.IsValidator
  1650  	c.IsValidator = validate
  1651  	ret := x.Func(c, args)
  1652  	c.IsValidator = saved
  1653  
  1654  	return ret
  1655  }
  1656  
  1657  func (x *Builtin) Source() ast.Node { return nil }
  1658  
  1659  // A BuiltinValidator is a Value that results from evaluation a partial call
  1660  // to a builtin (using CallExpr).
  1661  //
  1662  //	strings.MinRunes(4)
  1663  type BuiltinValidator struct {
  1664  	Src     *CallExpr
  1665  	Builtin *Builtin
  1666  	Args    []Value // any but the first value
  1667  }
  1668  
  1669  func (x *BuiltinValidator) Source() ast.Node {
  1670  	if x.Src == nil {
  1671  		return x.Builtin.Source()
  1672  	}
  1673  	return x.Src.Source()
  1674  }
  1675  
  1676  func (x *BuiltinValidator) Pos() token.Pos {
  1677  	if src := x.Source(); src != nil {
  1678  		return src.Pos()
  1679  	}
  1680  	return token.NoPos
  1681  }
  1682  
  1683  func (x *BuiltinValidator) Kind() Kind {
  1684  	return x.Builtin.Params[0].Kind()
  1685  }
  1686  
  1687  func (x *BuiltinValidator) validate(c *OpContext, v Value) *Bottom {
  1688  	args := make([]Value, len(x.Args)+1)
  1689  	args[0] = v
  1690  	copy(args[1:], x.Args)
  1691  
  1692  	return validateWithBuiltin(c, x.Pos(), x.Builtin, args)
  1693  }
  1694  
  1695  func validateWithBuiltin(c *OpContext, src token.Pos, b *Builtin, args []Value) *Bottom {
  1696  	var severeness ErrorCode
  1697  	var err errors.Error
  1698  
  1699  	res := b.call(c, src, true, args)
  1700  	switch v := res.(type) {
  1701  	case nil:
  1702  		return nil
  1703  
  1704  	case *Bottom:
  1705  		if v == nil {
  1706  			return nil // caught elsewhere, but be defensive.
  1707  		}
  1708  		severeness = v.Code
  1709  		err = v.Err
  1710  
  1711  	case *Bool:
  1712  		if v.B {
  1713  			return nil
  1714  		}
  1715  
  1716  	default:
  1717  		return c.NewErrf("invalid validator %s.%s", b.Package.StringValue(c), b.Name)
  1718  	}
  1719  
  1720  	// failed:
  1721  	var buf bytes.Buffer
  1722  	b.WriteName(&buf, c)
  1723  	if len(args) > 1 {
  1724  		buf.WriteString("(")
  1725  		for i, a := range args[1:] {
  1726  			if i > 0 {
  1727  				_, _ = buf.WriteString(", ")
  1728  			}
  1729  			buf.WriteString(c.Str(a))
  1730  		}
  1731  		buf.WriteString(")")
  1732  	}
  1733  
  1734  	// If the validator returns an error and we already had an error, just
  1735  	// return the original error.
  1736  	if b, ok := Unwrap(args[0]).(*Bottom); ok {
  1737  		return b
  1738  	}
  1739  
  1740  	vErr := c.NewPosf(src, "invalid value %s (does not satisfy %s)", args[0], buf.String())
  1741  
  1742  	for _, v := range args {
  1743  		vErr.AddPosition(v)
  1744  	}
  1745  
  1746  	return &Bottom{Code: severeness, Err: errors.Wrap(vErr, err)}
  1747  }
  1748  
  1749  // A Disjunction represents a disjunction, where each disjunct may or may not
  1750  // be marked as a default.
  1751  type DisjunctionExpr struct {
  1752  	Src    *ast.BinaryExpr
  1753  	Values []Disjunct
  1754  
  1755  	HasDefaults bool
  1756  }
  1757  
  1758  // A Disjunct is used in Disjunction.
  1759  type Disjunct struct {
  1760  	Val     Expr
  1761  	Default bool
  1762  }
  1763  
  1764  func (x *DisjunctionExpr) Source() ast.Node {
  1765  	if x.Src == nil {
  1766  		return nil
  1767  	}
  1768  	return x.Src
  1769  }
  1770  
  1771  func (x *DisjunctionExpr) evaluate(c *OpContext, state combinedFlags) Value {
  1772  	e := c.Env(0)
  1773  	v := c.newInlineVertex(nil, nil, Conjunct{e, x, c.ci})
  1774  	v.Finalize(c) // TODO: also partial okay?
  1775  	// TODO: if the disjunction result originated from a literal value, we may
  1776  	// consider the result closed to create more permanent errors.
  1777  	return v
  1778  }
  1779  
  1780  // A Conjunction is a conjunction of values that cannot be represented as a
  1781  // single value. It is the result of unification.
  1782  type Conjunction struct {
  1783  	Src    ast.Expr
  1784  	Values []Value
  1785  }
  1786  
  1787  func (x *Conjunction) Source() ast.Node { return x.Src }
  1788  func (x *Conjunction) Kind() Kind {
  1789  	k := TopKind
  1790  	for _, v := range x.Values {
  1791  		k &= v.Kind()
  1792  	}
  1793  	return k
  1794  }
  1795  
  1796  // A disjunction is a disjunction of values. It is the result of expanding
  1797  // a DisjunctionExpr if the expression cannot be represented as a single value.
  1798  type Disjunction struct {
  1799  	Src ast.Expr
  1800  
  1801  	// Values are the non-error disjuncts of this expression. The first
  1802  	// NumDefaults values are default values.
  1803  	Values []Value
  1804  
  1805  	Errors *Bottom // []bottom
  1806  
  1807  	// NumDefaults indicates the number of default values.
  1808  	NumDefaults int
  1809  	HasDefaults bool
  1810  }
  1811  
  1812  func (x *Disjunction) Source() ast.Node { return x.Src }
  1813  func (x *Disjunction) Kind() Kind {
  1814  	k := BottomKind
  1815  	for _, v := range x.Values {
  1816  		k |= v.Kind()
  1817  	}
  1818  	return k
  1819  }
  1820  
  1821  type Comprehension struct {
  1822  	Syntax ast.Node
  1823  
  1824  	// Clauses is the list of for, if, and other clauses of a comprehension,
  1825  	// not including the yielded value (in curly braces).
  1826  	Clauses []Yielder
  1827  
  1828  	// Value can be either a StructLit if this is a compiled expression or
  1829  	// a Field if this is a computed Comprehension. Value holds a Field,
  1830  	// rather than an Expr, in the latter case to preserve as much position
  1831  	// information as possible.
  1832  	Value Node
  1833  
  1834  	// The type of field as which the comprehension is added.
  1835  	arcType ArcType
  1836  
  1837  	// Only used for partial comprehensions.
  1838  	comp   *envComprehension
  1839  	parent *Comprehension // comprehension from which this one was derived, if any
  1840  	arc    *Vertex        // arc to which this comprehension was added.
  1841  }
  1842  
  1843  // Nest returns the nesting level of void arcs of this comprehension.
  1844  func (c *Comprehension) Nest() int {
  1845  	count := 0
  1846  	for ; c.parent != nil; c = c.parent {
  1847  		count++
  1848  	}
  1849  	return count
  1850  }
  1851  
  1852  // Envs returns all Environments yielded from an evaluated comprehension.
  1853  // Together with the Comprehension value, each Environment represents a
  1854  // result value of the comprehension.
  1855  func (c *Comprehension) Envs() []*Environment {
  1856  	if c.comp == nil {
  1857  		return nil
  1858  	}
  1859  	return c.comp.envs
  1860  }
  1861  
  1862  // DidResolve reports whether a comprehension was processed and resulted in at
  1863  // least one yielded value.
  1864  func (x *Comprehension) DidResolve() bool {
  1865  	return x.comp.done && len(x.comp.envs) > 0
  1866  }
  1867  
  1868  func (x *Comprehension) Source() ast.Node {
  1869  	if x.Syntax == nil {
  1870  		return nil
  1871  	}
  1872  	return x.Syntax
  1873  }
  1874  
  1875  // A ForClause represents a for clause of a comprehension. It can be used
  1876  // as a struct or list element.
  1877  //
  1878  //	for k, v in src {}
  1879  type ForClause struct {
  1880  	Syntax *ast.ForClause
  1881  	Key    Feature
  1882  	Value  Feature
  1883  	Src    Expr
  1884  }
  1885  
  1886  func (x *ForClause) Source() ast.Node {
  1887  	if x.Syntax == nil {
  1888  		return nil
  1889  	}
  1890  	return x.Syntax
  1891  }
  1892  
  1893  func (c *OpContext) forSource(x Expr) *Vertex {
  1894  	state := require(conjuncts, needFieldSetKnown)
  1895  
  1896  	// TODO: always get the vertex. This allows a whole bunch of trickery
  1897  	// down the line.
  1898  	v := c.unifyNode(x, state)
  1899  
  1900  	node, ok := v.(*Vertex)
  1901  	if ok && c.isDevVersion() {
  1902  		node.unify(c, state.conditions(), yield)
  1903  	}
  1904  
  1905  	v, ok = c.getDefault(v)
  1906  
  1907  	if !ok {
  1908  		// Error already generated by getDefault.
  1909  		return emptyNode
  1910  	}
  1911  
  1912  	// TODO: skip in new evaluator? Check once we introduce disjunctions.
  1913  	if w := Unwrap(v); !isCyclePlaceholder(w) {
  1914  		v = w
  1915  	}
  1916  	node, ok = v.(*Vertex)
  1917  	if ok && !isCyclePlaceholder(node.BaseValue) {
  1918  		v = node.Value()
  1919  	}
  1920  
  1921  	switch nv := v.(type) {
  1922  	case nil:
  1923  		c.addErrf(IncompleteError, pos(x),
  1924  			"cannot range over %s (incomplete)", x)
  1925  		return emptyNode
  1926  
  1927  	case *Bottom:
  1928  		// TODO: this is a bit messy. In some cases errors are already added
  1929  		// and in some cases not. Not a huge deal, as errors will be uniqued
  1930  		// down the line, but could be better.
  1931  		c.AddBottom(nv)
  1932  		return emptyNode
  1933  
  1934  	case *Vertex:
  1935  		if node == nil {
  1936  			panic("unexpected markers with nil node")
  1937  		}
  1938  
  1939  	default:
  1940  		if kind := v.Kind(); kind&StructKind != 0 {
  1941  			c.addErrf(IncompleteError, pos(x),
  1942  				"cannot range over %s (incomplete type %s)", x, kind)
  1943  			return emptyNode
  1944  
  1945  		} else if !ok {
  1946  			c.addErrf(0, pos(x), // TODO(error): better message.
  1947  				"cannot range over %s (found %s, want list or struct)",
  1948  				x.Source(), v.Kind())
  1949  			return emptyNode
  1950  		}
  1951  	}
  1952  
  1953  	return node
  1954  }
  1955  
  1956  func (x *ForClause) yield(s *compState) {
  1957  	c := s.ctx
  1958  	n := c.forSource(x.Src)
  1959  
  1960  	if c.isDevVersion() {
  1961  		if s := n.getState(c); s != nil {
  1962  			s.freeze(fieldSetKnown)
  1963  		}
  1964  	} else {
  1965  		if n.status == evaluating && !n.LockArcs {
  1966  			c.AddBottom(&Bottom{
  1967  				Code:     CycleError,
  1968  				ForCycle: true,
  1969  				Value:    n,
  1970  				Err:      errors.Newf(pos(x.Src), "comprehension source references itself"),
  1971  			})
  1972  			return
  1973  		}
  1974  		if c.HasErr() {
  1975  			return
  1976  		}
  1977  		n.LockArcs = true
  1978  	}
  1979  
  1980  	for _, a := range n.Arcs {
  1981  		if !a.Label.IsRegular() {
  1982  			continue
  1983  		}
  1984  
  1985  		if c.isDevVersion() {
  1986  			c.require(a, arcTypeKnown)
  1987  		} else {
  1988  			if !a.isDefined() {
  1989  				a.Finalize(c)
  1990  			}
  1991  			if !a.definitelyExists() {
  1992  				continue
  1993  			}
  1994  		}
  1995  
  1996  		switch a.ArcType {
  1997  		case ArcMember:
  1998  		case ArcRequired:
  1999  			c.AddBottom(newRequiredFieldInComprehensionError(c, x, a))
  2000  			continue
  2001  		default:
  2002  			continue
  2003  		}
  2004  
  2005  		n := &Vertex{
  2006  			Parent: c.Env(0).Vertex,
  2007  
  2008  			// Using Finalized here ensures that no nodeContext is allocated,
  2009  			// preventing a leak, as this "helper" struct bypasses normal
  2010  			// processing, eluding the deallocation step.
  2011  			status:    finalized,
  2012  			IsDynamic: true,
  2013  			ArcType:   ArcMember,
  2014  		}
  2015  
  2016  		if x.Value != InvalidLabel {
  2017  			b := &Vertex{
  2018  				Label:     x.Value,
  2019  				BaseValue: a,
  2020  				IsDynamic: true,
  2021  				ArcType:   ArcPending,
  2022  			}
  2023  			n.Arcs = append(n.Arcs, b)
  2024  		}
  2025  
  2026  		if x.Key != InvalidLabel {
  2027  			v := &Vertex{
  2028  				Label:     x.Key,
  2029  				IsDynamic: true,
  2030  			}
  2031  			key := a.Label.ToValue(c)
  2032  			v.AddConjunct(MakeRootConjunct(c.Env(0), key))
  2033  			v.SetValue(c, key)
  2034  			n.Arcs = append(n.Arcs, v)
  2035  		}
  2036  
  2037  		sub := c.spawn(n)
  2038  		if !s.yield(sub) {
  2039  			break
  2040  		}
  2041  	}
  2042  }
  2043  
  2044  // An IfClause represents an if clause of a comprehension. It can be used
  2045  // as a struct or list element.
  2046  //
  2047  //	if cond {}
  2048  type IfClause struct {
  2049  	Src       *ast.IfClause
  2050  	Condition Expr
  2051  }
  2052  
  2053  func (x *IfClause) Source() ast.Node {
  2054  	if x.Src == nil {
  2055  		return nil
  2056  	}
  2057  	return x.Src
  2058  }
  2059  
  2060  func (x *IfClause) yield(s *compState) {
  2061  	ctx := s.ctx
  2062  	if ctx.BoolValue(ctx.value(x.Condition, require(s.state, scalarKnown))) {
  2063  		s.yield(ctx.e)
  2064  	}
  2065  }
  2066  
  2067  // A LetClause represents a let clause in a comprehension.
  2068  //
  2069  //	let x = y
  2070  type LetClause struct {
  2071  	Src   *ast.LetClause
  2072  	Label Feature
  2073  	Expr  Expr
  2074  }
  2075  
  2076  func (x *LetClause) Source() ast.Node {
  2077  	if x.Src == nil {
  2078  		return nil
  2079  	}
  2080  	return x.Src
  2081  }
  2082  
  2083  func (x *LetClause) yield(s *compState) {
  2084  	c := s.ctx
  2085  	n := &Vertex{Arcs: []*Vertex{
  2086  		{
  2087  			Label:     x.Label,
  2088  			IsDynamic: true,
  2089  			Conjuncts: []Conjunct{{c.Env(0), x.Expr, c.ci}},
  2090  		},
  2091  	}}
  2092  
  2093  	s.yield(c.spawn(n))
  2094  }
  2095  

View as plain text