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