cuelang.org/go@v0.10.1/internal/core/adt/composite.go (about)

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