// Copyright 2018 The CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cue

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"math"
	"math/big"
	"strconv"
	"strings"

	"github.com/cockroachdb/apd/v2"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/ast/astutil"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/literal"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal"
	"cuelang.org/go/internal/core/adt"
	"cuelang.org/go/internal/core/compile"
	"cuelang.org/go/internal/core/convert"
	"cuelang.org/go/internal/core/eval"
	"cuelang.org/go/internal/core/export"
	"cuelang.org/go/internal/core/runtime"
	"cuelang.org/go/internal/core/subsume"
	"cuelang.org/go/internal/core/validate"
	"cuelang.org/go/internal/types"
)

// Kind determines the underlying type of a Value.
type Kind = adt.Kind

const BottomKind Kind = 0

const (
	// NullKind indicates a null value.
	NullKind Kind = adt.NullKind

	// BoolKind indicates a boolean value.
	BoolKind = adt.BoolKind

	// IntKind represents an integral number.
	IntKind = adt.IntKind

	// FloatKind represents a decimal float point number that cannot be
	// converted to an integer. The underlying number may still be integral,
	// but resulting from an operation that enforces the float type.
	FloatKind = adt.FloatKind

	// StringKind indicates any kind of string.
	StringKind = adt.StringKind

	// BytesKind is a blob of data.
	BytesKind = adt.BytesKind

	// StructKind is a kev-value map.
	StructKind = adt.StructKind

	// ListKind indicates a list of values.
	ListKind = adt.ListKind

	// _numberKind is used as a implementation detail inside
	// Kind.String to indicate NumberKind.

	// NumberKind represents any kind of number.
	NumberKind = IntKind | FloatKind

	TopKind = adt.TopKind
)

// An structValue represents a JSON object.
//
// TODO: remove
type structValue struct {
	ctx      *adt.OpContext
	v        Value
	obj      *adt.Vertex
	features []adt.Feature
}

type hiddenStructValue = structValue

// Len reports the number of fields in this struct.
func (o *hiddenStructValue) Len() int {
	if o.obj == nil {
		return 0
	}
	return len(o.features)
}

// At reports the key and value of the ith field, i < o.Len().
func (o *hiddenStructValue) At(i int) (key string, v Value) {
	f := o.features[i]
	return o.v.idx.LabelStr(f), newChildValue(o, i)
}

func (o *hiddenStructValue) at(i int) (v *adt.Vertex, isOpt bool) {
	f := o.features[i]
	arc := o.obj.Lookup(f)
	if arc == nil {
		arc = &adt.Vertex{
			Parent: o.v.v,
			Label:  f,
		}
		o.obj.MatchAndInsert(o.ctx, arc)
		arc.Finalize(o.ctx)
		isOpt = true
	}
	return arc, isOpt
}

// Lookup reports the field for the given key. The returned Value is invalid
// if it does not exist.
func (o *hiddenStructValue) Lookup(key string) Value {
	f := o.v.idx.StrLabel(key)
	i := 0
	len := o.Len()
	for ; i < len; i++ {
		if o.features[i] == f {
			break
		}
	}
	if i == len {
		// TODO: better message.
		x := mkErr(o.v.idx, o.obj, adt.NotExistError, "value %q not found", key)
		return newErrValue(o.v, x)
	}
	return newChildValue(o, i)
}

// MarshalJSON returns a valid JSON encoding or reports an error if any of the
// fields is invalid.
func (o *structValue) marshalJSON() (b []byte, err errors.Error) {
	b = append(b, '{')
	n := o.Len()
	for i := 0; i < n; i++ {
		k, v := o.At(i)
		s, err := json.Marshal(k)
		if err != nil {
			return nil, unwrapJSONError(err)
		}
		b = append(b, s...)
		b = append(b, ':')
		bb, err := json.Marshal(v)
		if err != nil {
			return nil, unwrapJSONError(err)
		}
		b = append(b, bb...)
		if i < n-1 {
			b = append(b, ',')
		}
	}
	b = append(b, '}')
	return b, nil
}

var _ errors.Error = &marshalError{}

type marshalError struct {
	err errors.Error
	b   *adt.Bottom
}

func toMarshalErr(v Value, b *adt.Bottom) error {
	return &marshalError{v.toErr(b), b}
}

func marshalErrf(v Value, src adt.Node, code adt.ErrorCode, msg string, args ...interface{}) error {
	arguments := append([]interface{}{code, msg}, args...)
	b := mkErr(v.idx, src, arguments...)
	return toMarshalErr(v, b)
}

func (e *marshalError) Error() string {
	return fmt.Sprintf("cue: marshal error: %v", e.err)
}

func (e *marshalError) Bottom() *adt.Bottom          { return e.b }
func (e *marshalError) Path() []string               { return e.err.Path() }
func (e *marshalError) Msg() (string, []interface{}) { return e.err.Msg() }
func (e *marshalError) Position() token.Pos          { return e.err.Position() }
func (e *marshalError) InputPositions() []token.Pos {
	return e.err.InputPositions()
}

func unwrapJSONError(err error) errors.Error {
	switch x := err.(type) {
	case *json.MarshalerError:
		return unwrapJSONError(x.Err)
	case *marshalError:
		return x
	case errors.Error:
		return &marshalError{x, nil}
	default:
		return &marshalError{errors.Wrapf(err, token.NoPos, "json error"), nil}
	}
}

// An Iterator iterates over values.
//
type Iterator struct {
	val   Value
	idx   *runtime.Runtime
	ctx   *adt.OpContext
	arcs  []field
	p     int
	cur   Value
	f     adt.Feature
	isOpt bool
}

type hiddenIterator = Iterator

type field struct {
	arc        *adt.Vertex
	isOptional bool
}

// Next advances the iterator to the next value and reports whether there was
// any. It must be called before the first call to Value or Key.
func (i *Iterator) Next() bool {
	if i.p >= len(i.arcs) {
		i.cur = Value{}
		return false
	}
	f := i.arcs[i.p]
	f.arc.Finalize(i.ctx)
	p := linkParent(i.val.parent_, i.val.v, f.arc)
	i.cur = makeValue(i.val.idx, f.arc, p)
	i.f = f.arc.Label
	i.isOpt = f.isOptional
	i.p++
	return true
}

// Value returns the current value in the list. It will panic if Next advanced
// past the last entry.
func (i *Iterator) Value() Value {
	return i.cur
}

// Selector reports the field label of this iteration.
func (i *Iterator) Selector() Selector {
	return featureToSel(i.f, i.idx)
}

// Label reports the label of the value if i iterates over struct fields and ""
// otherwise.
//
//
// Slated to be deprecated: use i.Selector().String(). Note that this will give
// more accurate string representations.
func (i *hiddenIterator) Label() string {
	if i.f == 0 {
		return ""
	}
	return i.idx.LabelStr(i.f)
}

// IsHidden reports if a field is hidden from the data model.
//
// Deprecated: use i.Selector().PkgPath() != ""
func (i *hiddenIterator) IsHidden() bool {
	return i.f.IsHidden()
}

// IsOptional reports if a field is optional.
func (i *Iterator) IsOptional() bool {
	return i.isOpt
}

// IsDefinition reports if a field is a definition.
//
// Deprecated: use i.Selector().IsDefinition()
func (i *hiddenIterator) IsDefinition() bool {
	return i.f.IsDef()
}

// marshalJSON iterates over the list and generates JSON output. HasNext
// will return false after this operation.
func marshalList(l *Iterator) (b []byte, err errors.Error) {
	b = append(b, '[')
	if l.Next() {
		for i := 0; ; i++ {
			x, err := json.Marshal(l.Value())
			if err != nil {
				return nil, unwrapJSONError(err)
			}
			b = append(b, x...)
			if !l.Next() {
				break
			}
			b = append(b, ',')
		}
	}
	b = append(b, ']')
	return b, nil
}

func (v Value) getNum(k adt.Kind) (*adt.Num, errors.Error) {
	v, _ = v.Default()
	ctx := v.ctx()
	if err := v.checkKind(ctx, k); err != nil {
		return nil, v.toErr(err)
	}
	n, _ := v.eval(ctx).(*adt.Num)
	return n, nil
}

// MantExp breaks x into its mantissa and exponent components and returns the
// exponent. If a non-nil mant argument is provided its value is set to the
// mantissa of x. The components satisfy x == mant × 10**exp. It returns an
// error if v is not a number.
//
// The components are not normalized. For instance, 2.00 is represented mant ==
// 200 and exp == -2. Calling MantExp with a nil argument is an efficient way to
// get the exponent of the receiver.
func (v Value) MantExp(mant *big.Int) (exp int, err error) {
	n, err := v.getNum(adt.NumKind)
	if err != nil {
		return 0, err
	}
	if n.X.Form != 0 {
		return 0, ErrInfinite
	}
	if mant != nil {
		mant.Set(&n.X.Coeff)
		if n.X.Negative {
			mant.Neg(mant)
		}
	}
	return int(n.X.Exponent), nil
}

// Decimal is for internal use only. The Decimal type that is returned is
// subject to change.
func (v hiddenValue) Decimal() (d *internal.Decimal, err error) {
	n, err := v.getNum(adt.NumKind)
	if err != nil {
		return nil, err
	}
	return &n.X, nil
}

// AppendInt appends the string representation of x in the given base to buf and
// returns the extended buffer, or an error if the underlying number was not
// an integer.
func (v Value) AppendInt(buf []byte, base int) ([]byte, error) {
	i, err := v.Int(nil)
	if err != nil {
		return nil, err
	}
	return i.Append(buf, base), nil
}

// AppendFloat appends to buf the string form of the floating-point number x.
// It returns an error if v is not a number.
func (v Value) AppendFloat(buf []byte, fmt byte, prec int) ([]byte, error) {
	n, err := v.getNum(adt.NumKind)
	if err != nil {
		return nil, err
	}
	ctx := apd.BaseContext
	nd := int(apd.NumDigits(&n.X.Coeff)) + int(n.X.Exponent)
	if n.X.Form == apd.Infinite {
		if n.X.Negative {
			buf = append(buf, '-')
		}
		return append(buf, string('∞')...), nil
	}
	if fmt == 'f' && nd > 0 {
		ctx.Precision = uint32(nd + prec)
	} else {
		ctx.Precision = uint32(prec)
	}
	var d apd.Decimal
	ctx.Round(&d, &n.X)
	return d.Append(buf, fmt), nil
}

var (
	// ErrBelow indicates that a value was rounded down in a conversion.
	ErrBelow = errors.New("value was rounded down")

	// ErrAbove indicates that a value was rounded up in a conversion.
	ErrAbove = errors.New("value was rounded up")

	// ErrInfinite indicates that a value is infinite.
	ErrInfinite = errors.New("infinite")
)

// Int converts the underlying integral number to an big.Int. It reports an
// error if the underlying value is not an integer type. If a non-nil *Int
// argument z is provided, Int stores the result in z instead of allocating a
// new Int.
func (v Value) Int(z *big.Int) (*big.Int, error) {
	n, err := v.getNum(adt.IntKind)
	if err != nil {
		return nil, err
	}
	if z == nil {
		z = &big.Int{}
	}
	if n.X.Exponent != 0 {
		panic("cue: exponent should always be nil for integer types")
	}
	z.Set(&n.X.Coeff)
	if n.X.Negative {
		z.Neg(z)
	}
	return z, nil
}

// Int64 converts the underlying integral number to int64. It reports an
// error if the underlying value is not an integer type or cannot be represented
// as an int64. The result is (math.MinInt64, ErrAbove) for x < math.MinInt64,
// and (math.MaxInt64, ErrBelow) for x > math.MaxInt64.
func (v Value) Int64() (int64, error) {
	n, err := v.getNum(adt.IntKind)
	if err != nil {
		return 0, err
	}
	if !n.X.Coeff.IsInt64() {
		if n.X.Negative {
			return math.MinInt64, ErrAbove
		}
		return math.MaxInt64, ErrBelow
	}
	i := n.X.Coeff.Int64()
	if n.X.Negative {
		i = -i
	}
	return i, nil
}

// Uint64 converts the underlying integral number to uint64. It reports an
// error if the underlying value is not an integer type or cannot be represented
// as a uint64. The result is (0, ErrAbove) for x < 0, and
// (math.MaxUint64, ErrBelow) for x > math.MaxUint64.
func (v Value) Uint64() (uint64, error) {
	n, err := v.getNum(adt.IntKind)
	if err != nil {
		return 0, err
	}
	if n.X.Negative {
		return 0, ErrAbove
	}
	if !n.X.Coeff.IsUint64() {
		return math.MaxUint64, ErrBelow
	}
	i := n.X.Coeff.Uint64()
	return i, nil
}

// trimZeros trims 0's for better JSON respresentations.
func trimZeros(s string) string {
	n1 := len(s)
	s2 := strings.TrimRight(s, "0")
	n2 := len(s2)
	if p := strings.IndexByte(s2, '.'); p != -1 {
		if p == n2-1 {
			return s[:len(s2)+1]
		}
		return s2
	}
	if n1-n2 <= 4 {
		return s
	}
	return fmt.Sprint(s2, "e+", n1-n2)
}

var (
	smallestPosFloat64 *apd.Decimal
	smallestNegFloat64 *apd.Decimal
	maxPosFloat64      *apd.Decimal
	maxNegFloat64      *apd.Decimal
)

func init() {
	const (
		// math.SmallestNonzeroFloat64: 1 / 2**(1023 - 1 + 52)
		smallest = "4.940656458412465441765687928682213723651e-324"
		// math.MaxFloat64: 2**1023 * (2**53 - 1) / 2**52
		max = "1.797693134862315708145274237317043567981e+308"
	)
	ctx := apd.BaseContext
	ctx.Precision = 40

	var err error
	smallestPosFloat64, _, err = ctx.NewFromString(smallest)
	if err != nil {
		panic(err)
	}
	smallestNegFloat64, _, err = ctx.NewFromString("-" + smallest)
	if err != nil {
		panic(err)
	}
	maxPosFloat64, _, err = ctx.NewFromString(max)
	if err != nil {
		panic(err)
	}
	maxNegFloat64, _, err = ctx.NewFromString("-" + max)
	if err != nil {
		panic(err)
	}
}

// Float64 returns the float64 value nearest to x. It reports an error if v is
// not a number. If x is too small to be represented by a float64 (|x| <
// math.SmallestNonzeroFloat64), the result is (0, ErrBelow) or (-0, ErrAbove),
// respectively, depending on the sign of x. If x is too large to be represented
// by a float64 (|x| > math.MaxFloat64), the result is (+Inf, ErrAbove) or
// (-Inf, ErrBelow), depending on the sign of x.
func (v Value) Float64() (float64, error) {
	n, err := v.getNum(adt.NumKind)
	if err != nil {
		return 0, err
	}
	if n.X.Negative {
		if n.X.Cmp(smallestNegFloat64) == 1 {
			return -0, ErrAbove
		}
		if n.X.Cmp(maxNegFloat64) == -1 {
			return math.Inf(-1), ErrBelow
		}
	} else {
		if n.X.Cmp(smallestPosFloat64) == -1 {
			return 0, ErrBelow
		}
		if n.X.Cmp(maxPosFloat64) == 1 {
			return math.Inf(1), ErrAbove
		}
	}
	f, _ := n.X.Float64()
	return f, nil
}

func (v Value) appendPath(a []string) []string {
	for _, f := range v.v.Path() {
		switch f.Typ() {
		case adt.IntLabel:
			a = append(a, strconv.FormatInt(int64(f.Index()), 10))

		case adt.StringLabel:
			label := v.idx.LabelStr(f)
			if !f.IsDef() && !f.IsHidden() {
				if !ast.IsValidIdent(label) {
					label = literal.String.Quote(label)
				}
			}
			a = append(a, label)
		default:
			a = append(a, f.SelectorString(v.idx))
		}
	}
	return a
}

// Value holds any value, which may be a Boolean, Error, List, Null, Number,
// Struct, or String.
type Value struct {
	idx *runtime.Runtime
	v   *adt.Vertex
	// Parent keeps track of the parent if the value corresponding to v.Parent
	// differs, recursively.
	parent_ *parent
}

// parent is a distinct type from Value to ensure more type safety: Value
// is typically used by value, so taking a pointer to it has a high risk
// or globbering the contents.
type parent struct {
	v *adt.Vertex
	p *parent
}

func (v Value) parent() Value {
	switch {
	case v.v == nil:
		return Value{}
	case v.parent_ != nil:
		return Value{v.idx, v.parent_.v, v.parent_.p}
	default:
		return Value{v.idx, v.v.Parent, nil}
	}
}

type valueScope Value

func (v valueScope) Vertex() *adt.Vertex { return v.v }
func (v valueScope) Parent() compile.Scope {
	p := Value(v).parent()
	if p.v == nil {
		return nil
	}
	return valueScope(p)
}

type hiddenValue = Value

// Core is for internal use only.
func (v hiddenValue) Core(x *types.Value) {
	x.V = v.v
	x.R = v.idx
}

func newErrValue(v Value, b *adt.Bottom) Value {
	node := &adt.Vertex{BaseValue: b}
	if v.v != nil {
		node.Label = v.v.Label
		node.Parent = v.v.Parent
	}
	node.UpdateStatus(adt.Finalized)
	node.AddConjunct(adt.MakeRootConjunct(nil, b))
	return makeChildValue(v.parent(), node)
}

func newVertexRoot(idx *runtime.Runtime, ctx *adt.OpContext, x *adt.Vertex) Value {
	if ctx != nil {
		// This is indicative of an zero Value. In some cases this is called
		// with an error value.
		x.Finalize(ctx)
	} else {
		x.UpdateStatus(adt.Finalized)
	}
	return makeValue(idx, x, nil)
}

func newValueRoot(idx *runtime.Runtime, ctx *adt.OpContext, x adt.Expr) Value {
	if n, ok := x.(*adt.Vertex); ok {
		return newVertexRoot(idx, ctx, n)
	}
	node := &adt.Vertex{}
	node.AddConjunct(adt.MakeRootConjunct(nil, x))
	return newVertexRoot(idx, ctx, node)
}

func newChildValue(o *structValue, i int) Value {
	arc, _ := o.at(i)
	return makeValue(o.v.idx, arc, linkParent(o.v.parent_, o.v.v, arc))
}

// Dereference reports the value v refers to if v is a reference or v itself
// otherwise.
func Dereference(v Value) Value {
	n := v.v
	if n == nil || len(n.Conjuncts) != 1 {
		return v
	}

	c := n.Conjuncts[0]
	r, _ := c.Expr().(adt.Resolver)
	if r == nil {
		return v
	}

	ctx := v.ctx()
	n, b := ctx.Resolve(c.Env, r)
	if b != nil {
		return newErrValue(v, b)
	}
	n.Finalize(ctx)
	// NOTE: due to structure sharing, the path of the referred node may end
	// up different from the one explicitly pointed to. The value will be the
	// same, but the scope may differ.
	// TODO(structureshare): see if we can construct the original path. This
	// only has to be done if structures are being shared.
	return makeValue(v.idx, n, nil)
}

func makeValue(idx *runtime.Runtime, v *adt.Vertex, p *parent) Value {
	if v.Status() == 0 || v.BaseValue == nil {
		panic(fmt.Sprintf("not properly initialized (state: %v, value: %T)",
			v.Status(), v.BaseValue))
	}
	return Value{idx, v, p}
}

// makeChildValue makes a new value, of which p is the parent, and links the
// parent pointer to p if necessary.
func makeChildValue(p Value, arc *adt.Vertex) Value {
	return makeValue(p.idx, arc, linkParent(p.parent_, p.v, arc))
}

// linkParent creates the parent struct for an arc, if necessary.
//
// The parent struct is necessary if the parent struct also has a parent struct,
// or if arc is (structurally) shared and does not have node as a parent.
func linkParent(p *parent, node, arc *adt.Vertex) *parent {
	if p == nil && node == arc.Parent {
		return nil
	}
	return &parent{node, p}
}

func remakeValue(base Value, env *adt.Environment, v adt.Expr) Value {
	// TODO: right now this is necessary because disjunctions do not have
	// populated conjuncts.
	if v, ok := v.(*adt.Vertex); ok && v.Status() >= adt.Partial {
		return Value{base.idx, v, nil}
	}
	n := &adt.Vertex{Label: base.v.Label}
	n.AddConjunct(adt.MakeRootConjunct(env, v))
	n = manifest(base.ctx(), n)
	n.Parent = base.v.Parent
	return makeChildValue(base.parent(), n)
}

func remakeFinal(base Value, env *adt.Environment, v adt.Value) Value {
	n := &adt.Vertex{Parent: base.v.Parent, Label: base.v.Label, BaseValue: v}
	n.UpdateStatus(adt.Finalized)
	return makeChildValue(base.parent(), n)
}

func (v Value) ctx() *adt.OpContext {
	return newContext(v.idx)
}

// Eval resolves the references of a value and returns the result.
// This method is not necessary to obtain concrete values.
func (v Value) Eval() Value {
	if v.v == nil {
		return v
	}
	x := v.v
	// x = eval.FinalizeValue(v.idx.Runtime, v.v)
	// x.Finalize(v.ctx())
	x = x.ToDataSingle()
	return makeValue(v.idx, x, v.parent_)
	// return remakeValue(v, nil, ctx.value(x))
}

// Default reports the default value and whether it existed. It returns the
// normal value if there is no default.
func (v Value) Default() (Value, bool) {
	if v.v == nil {
		return v, false
	}

	d := v.v.Default()
	if d == v.v {
		return v, false
	}
	return makeValue(v.idx, d, v.parent_), true

	// d, ok := v.v.Value.(*adt.Disjunction)
	// if !ok {
	// 	return v, false
	// }

	// var w *adt.Vertex

	// switch d.NumDefaults {
	// case 0:
	// 	return v, false

	// case 1:
	// 	w = d.Values[0]

	// default:
	// 	x := *v.v
	// 	x.Value = &adt.Disjunction{
	// 		Src:         d.Src,
	// 		Values:      d.Values[:d.NumDefaults],
	// 		NumDefaults: 0,
	// 	}
	// 	w = &x
	// }

	// w.Conjuncts = nil
	// for _, c := range v.v.Conjuncts {
	// 	// TODO: preserve field information.
	// 	expr, _ := stripNonDefaults(c.Expr())
	// 	w.AddConjunct(adt.MakeConjunct(c.Env, expr))
	// }

	// return makeValue(v.idx, w), true

	// if !stripped {
	// 	return v, false
	// }

	// n := *v.v
	// n.Conjuncts = conjuncts
	// return Value{v.idx, &n}, true

	// isDefault := false
	// for _, c := range v.v.Conjuncts {
	// 	if hasDisjunction(c.Expr()) {
	// 		isDefault = true
	// 		break
	// 	}
	// }

	// if !isDefault {
	// 	return v, false
	// }

	// TODO: record expanded disjunctions in output.
	// - Rename Disjunction to DisjunctionExpr
	// - Introduce Disjuncts with Values.
	// - In Expr introduce Star
	// - Don't pick default by default?

	// Evaluate the value.
	// 	x := eval.FinalizeValue(v.idx.Runtime, v.v)
	// 	if b, _ := x.Value.(*adt.Bottom); b != nil { // && b.IsIncomplete() {
	// 		return v, false
	// 	}
	// 	// Finalize and return here.
	// 	return Value{v.idx, x}, isDefault
}

// TODO: this should go: record preexpanded disjunctions in Vertex.
func hasDisjunction(expr adt.Expr) bool {
	switch x := expr.(type) {
	case *adt.DisjunctionExpr:
		return true
	case *adt.Conjunction:
		for _, v := range x.Values {
			if hasDisjunction(v) {
				return true
			}
		}
	case *adt.BinaryExpr:
		switch x.Op {
		case adt.OrOp:
			return true
		case adt.AndOp:
			return hasDisjunction(x.X) || hasDisjunction(x.Y)
		}
	}
	return false
}

// TODO: this should go: record preexpanded disjunctions in Vertex.
func stripNonDefaults(expr adt.Expr) (r adt.Expr, stripped bool) {
	switch x := expr.(type) {
	case *adt.DisjunctionExpr:
		if !x.HasDefaults {
			return x, false
		}
		d := *x
		d.Values = []adt.Disjunct{}
		for _, v := range x.Values {
			if v.Default {
				d.Values = append(d.Values, v)
			}
		}
		if len(d.Values) == 1 {
			return d.Values[0].Val, true
		}
		return &d, true

	case *adt.BinaryExpr:
		if x.Op != adt.AndOp {
			return x, false
		}
		a, sa := stripNonDefaults(x.X)
		b, sb := stripNonDefaults(x.Y)
		if sa || sb {
			bin := *x
			bin.X = a
			bin.Y = b
			return &bin, true
		}
		return x, false

	default:
		return x, false
	}
}

// Label reports he label used to obtain this value from the enclosing struct.
//
// TODO: get rid of this somehow. Probably by including a FieldInfo struct
// or the like.
func (v hiddenValue) Label() (string, bool) {
	if v.v == nil || v.v.Label == 0 {
		return "", false
	}
	return v.idx.LabelStr(v.v.Label), true
}

// Kind returns the kind of value. It returns BottomKind for atomic values that
// are not concrete. For instance, it will return BottomKind for the bounds
// >=0.
func (v Value) Kind() Kind {
	if v.v == nil {
		return BottomKind
	}
	c := v.v.BaseValue
	if !v.v.IsConcrete() {
		return BottomKind
	}
	if v.IncompleteKind() == adt.ListKind && !v.v.IsClosedList() {
		return BottomKind
	}
	return c.Kind()
}

// IncompleteKind returns a mask of all kinds that this value may be.
func (v Value) IncompleteKind() Kind {
	if v.v == nil {
		return BottomKind
	}
	return v.v.Kind()
}

// MarshalJSON marshalls this value into valid JSON.
func (v Value) MarshalJSON() (b []byte, err error) {
	b, err = v.marshalJSON()
	if err != nil {
		return nil, unwrapJSONError(err)
	}
	return b, nil
}

func (v Value) marshalJSON() (b []byte, err error) {
	v, _ = v.Default()
	if v.v == nil {
		return json.Marshal(nil)
	}
	ctx := newContext(v.idx)
	x := v.eval(ctx)

	if _, ok := x.(adt.Resolver); ok {
		return nil, marshalErrf(v, x, adt.IncompleteError, "value %q contains unresolved references", str(ctx, x))
	}
	if !adt.IsConcrete(x) {
		return nil, marshalErrf(v, x, adt.IncompleteError, "cannot convert incomplete value %q to JSON", str(ctx, x))
	}

	// TODO: implement marshalles in value.
	switch k := x.Kind(); k {
	case adt.NullKind:
		return json.Marshal(nil)
	case adt.BoolKind:
		return json.Marshal(x.(*adt.Bool).B)
	case adt.IntKind, adt.FloatKind, adt.NumKind:
		b, err := x.(*adt.Num).X.MarshalText()
		b = bytes.TrimLeft(b, "+")
		return b, err
	case adt.StringKind:
		return json.Marshal(x.(*adt.String).Str)
	case adt.BytesKind:
		return json.Marshal(x.(*adt.Bytes).B)
	case adt.ListKind:
		i, _ := v.List()
		return marshalList(&i)
	case adt.StructKind:
		obj, err := v.structValData(ctx)
		if err != nil {
			return nil, toMarshalErr(v, err)
		}
		return obj.marshalJSON()
	case adt.BottomKind:
		return nil, toMarshalErr(v, x.(*adt.Bottom))
	default:
		return nil, marshalErrf(v, x, 0, "cannot convert value %q of type %T to JSON", str(ctx, x), x)
	}
}

// Syntax converts the possibly partially evaluated value into syntax. This
// can use used to print the value with package format.
func (v Value) Syntax(opts ...Option) ast.Node {
	// TODO: the default should ideally be simplified representation that
	// exactly represents the value. The latter can currently only be
	// ensured with Raw().
	if v.v == nil {
		return nil
	}
	var o options = getOptions(opts)
	// var inst *Instance

	p := export.Profile{
		Simplify:        !o.raw,
		TakeDefaults:    o.final,
		ShowOptional:    !o.omitOptional && !o.concrete,
		ShowDefinitions: !o.omitDefinitions && !o.concrete,
		ShowHidden:      !o.omitHidden && !o.concrete,
		ShowAttributes:  !o.omitAttrs,
		ShowDocs:        o.docs,
	}

	pkgID := v.instance().ID()

	bad := func(name string, err error) ast.Node {
		const format = `"%s: internal error
Error: %s

Profile:
%#v

Value:
%v

You could file a bug with the above information at:
    https://github.com/cuelang/cue/issues/new?assignees=&labels=NeedsInvestigation&template=bug_report.md&title=.
`
		cg := &ast.CommentGroup{Doc: true}
		msg := fmt.Sprintf(format, name, err, p, v)
		for _, line := range strings.Split(msg, "\n") {
			cg.List = append(cg.List, &ast.Comment{Text: "// " + line})
		}
		x := &ast.BadExpr{}
		ast.AddComment(x, cg)
		return x
	}

	// var expr ast.Expr
	var err error
	var f *ast.File
	if o.concrete || o.final {
		// inst = v.instance()
		var expr ast.Expr
		expr, err = p.Value(v.idx, pkgID, v.v)
		if err != nil {
			return bad(`"cuelang.org/go/internal/core/export".Value`, err)
		}

		// This introduces gratuitous unshadowing!
		f, err = astutil.ToFile(expr)
		if err != nil {
			return bad(`"cuelang.org/go/ast/astutil".ToFile`, err)
		}
		// return expr
	} else {
		f, err = p.Def(v.idx, pkgID, v.v)
		if err != nil {
			return bad(`"cuelang.org/go/internal/core/export".Def`, err)
		}
	}

outer:
	for _, d := range f.Decls {
		switch d.(type) {
		case *ast.Package, *ast.ImportDecl:
			return f
		case *ast.CommentGroup, *ast.Attribute:
		default:
			break outer
		}
	}

	if len(f.Decls) == 1 {
		if e, ok := f.Decls[0].(*ast.EmbedDecl); ok {
			return e.Expr
		}
	}
	return &ast.StructLit{
		Elts: f.Decls,
	}
}

// Doc returns all documentation comments associated with the field from which
// the current value originates.
func (v Value) Doc() []*ast.CommentGroup {
	if v.v == nil {
		return nil
	}
	return export.ExtractDoc(v.v)
}

// Split returns a list of values from which v originated such that
// the unification of all these values equals v and for all returned values.
// It will also split unchecked unifications (embeddings), so unifying the
// split values may fail if actually unified.
// Source returns a non-nil value.
//
// Deprecated: use Expr.
func (v hiddenValue) Split() []Value {
	if v.v == nil {
		return nil
	}
	a := []Value{}
	for _, x := range v.v.Conjuncts {
		a = append(a, remakeValue(v, x.Env, x.Expr()))
	}
	return a
}

// Source returns the original node for this value. The return value may not
// be a syntax.Expr. For instance, a struct kind may be represented by a
// struct literal, a field comprehension, or a file. It returns nil for
// computed nodes. Use Split to get all source values that apply to a field.
func (v Value) Source() ast.Node {
	if v.v == nil {
		return nil
	}
	if len(v.v.Conjuncts) == 1 {
		return v.v.Conjuncts[0].Source()
	}
	return v.v.Value().Source()
}

// Err returns the error represented by v or nil v is not an error.
func (v Value) Err() error {
	if err := v.checkKind(v.ctx(), adt.BottomKind); err != nil {
		return v.toErr(err)
	}
	return nil
}

// Pos returns position information.
func (v Value) Pos() token.Pos {
	if v.v == nil || v.Source() == nil {
		return token.NoPos
	}
	pos := v.Source().Pos()
	return pos
}

// TODO: IsFinal: this value can never be changed.

// IsClosed reports whether a list of struct is closed. It reports false when
// when the value is not a list or struct.
//
// Deprecated: use Allows and Kind/IncompleteKind.
func (v hiddenValue) IsClosed() bool {
	if v.v == nil {
		return false
	}
	return v.v.IsClosedList() || v.v.IsClosedStruct()
}

// Allows reports whether a field with the given selector could be added to v.
//
// Allows does not take into account validators like list.MaxItems(4). This may
// change in the future.
func (v Value) Allows(sel Selector) bool {
	c := v.ctx()
	f := sel.sel.feature(c)
	return v.v.Accept(c, f)
}

// IsConcrete reports whether the current value is a concrete scalar value
// (not relying on default values), a terminal error, a list, or a struct.
// It does not verify that values of lists or structs are concrete themselves.
// To check whether there is a concrete default, use v.Default().IsConcrete().
func (v Value) IsConcrete() bool {
	if v.v == nil {
		return false // any is neither concrete, not a list or struct.
	}
	if b, ok := v.v.BaseValue.(*adt.Bottom); ok {
		return !b.IsIncomplete()
	}
	if !adt.IsConcrete(v.v) {
		return false
	}
	if v.IncompleteKind() == adt.ListKind && !v.v.IsClosedList() {
		return false
	}
	return true
}

// // Deprecated: IsIncomplete
// //
// // It indicates that the value cannot be fully evaluated due to
// // insufficient information.
// func (v Value) IsIncomplete() bool {
// 	panic("deprecated")
// }

// Exists reports whether this value existed in the configuration.
func (v Value) Exists() bool {
	if v.v == nil {
		return false
	}
	if err, ok := v.v.BaseValue.(*adt.Bottom); ok {
		return err.Code != adt.NotExistError
	}
	return true
}

func (v Value) checkKind(ctx *adt.OpContext, want adt.Kind) *adt.Bottom {
	if v.v == nil {
		return errNotExists
	}
	// TODO: use checkKind
	x := v.eval(ctx)
	if b, ok := x.(*adt.Bottom); ok {
		return b
	}
	k := x.Kind()
	if want != adt.BottomKind {
		if k&want == adt.BottomKind {
			return mkErr(v.idx, x, "cannot use value %v (type %s) as %s",
				ctx.Str(x), k, want)
		}
		if !adt.IsConcrete(x) {
			return mkErr(v.idx, x, adt.IncompleteError, "non-concrete value %v", k)
		}
	}
	return nil
}

func makeInt(v Value, x int64) Value {
	n := &adt.Num{K: adt.IntKind}
	n.X.SetInt64(int64(x))
	return remakeFinal(v, nil, n)
}

// Len returns the number of items of the underlying value.
// For lists it reports the capacity of the list. For structs it indicates the
// number of fields, for bytes the number of bytes.
func (v Value) Len() Value {
	if v.v != nil {
		switch x := v.eval(v.ctx()).(type) {
		case *adt.Vertex:
			if x.IsList() {
				n := &adt.Num{K: adt.IntKind}
				n.X.SetInt64(int64(len(x.Elems())))
				if x.IsClosedList() {
					return remakeFinal(v, nil, n)
				}
				// Note: this HAS to be a Conjunction value and cannot be
				// an adt.BinaryExpr, as the expressions would be considered
				// to be self-contained and unresolvable when evaluated
				// (can never become concrete).
				c := &adt.Conjunction{Values: []adt.Value{
					&adt.BasicType{K: adt.IntKind},
					&adt.BoundValue{Op: adt.GreaterEqualOp, Value: n},
				}}
				return remakeFinal(v, nil, c)

			}
		case *adt.Bytes:
			return makeInt(v, int64(len(x.B)))
		case *adt.String:
			return makeInt(v, int64(len([]rune(x.Str))))
		}
	}
	const msg = "len not supported for type %v"
	return remakeValue(v, nil, mkErr(v.idx, v.v, msg, v.Kind()))

}

// Elem returns the value of undefined element types of lists and structs.
//
// Deprecated: use LookupPath in combination with "AnyString" or "AnyIndex".
func (v hiddenValue) Elem() (Value, bool) {
	sel := AnyString
	if v.v.IsList() {
		sel = AnyIndex
	}
	x := v.LookupPath(MakePath(sel))
	return x, x.Exists()
}

// List creates an iterator over the values of a list or reports an error if
// v is not a list.
func (v Value) List() (Iterator, error) {
	v, _ = v.Default()
	ctx := v.ctx()
	if err := v.checkKind(ctx, adt.ListKind); err != nil {
		return Iterator{idx: v.idx, ctx: ctx}, v.toErr(err)
	}
	arcs := []field{}
	for _, a := range v.v.Elems() {
		if a.Label.IsInt() {
			arcs = append(arcs, field{arc: a})
		}
	}
	return Iterator{idx: v.idx, ctx: ctx, val: v, arcs: arcs}, nil
}

// Null reports an error if v is not null.
func (v Value) Null() error {
	v, _ = v.Default()
	if err := v.checkKind(v.ctx(), adt.NullKind); err != nil {
		return v.toErr(err)
	}
	return nil
}

// // IsNull reports whether v is null.
// func (v Value) IsNull() bool {
// 	return v.Null() == nil
// }

// Bool returns the bool value of v or false and an error if v is not a boolean.
func (v Value) Bool() (bool, error) {
	v, _ = v.Default()
	ctx := v.ctx()
	if err := v.checkKind(ctx, adt.BoolKind); err != nil {
		return false, v.toErr(err)
	}
	return v.eval(ctx).(*adt.Bool).B, nil
}

// String returns the string value if v is a string or an error otherwise.
func (v Value) String() (string, error) {
	v, _ = v.Default()
	ctx := v.ctx()
	if err := v.checkKind(ctx, adt.StringKind); err != nil {
		return "", v.toErr(err)
	}
	return v.eval(ctx).(*adt.String).Str, nil
}

// Bytes returns a byte slice if v represents a list of bytes or an error
// otherwise.
func (v Value) Bytes() ([]byte, error) {
	v, _ = v.Default()
	ctx := v.ctx()
	switch x := v.eval(ctx).(type) {
	case *adt.Bytes:
		return append([]byte(nil), x.B...), nil
	case *adt.String:
		return []byte(x.Str), nil
	}
	return nil, v.toErr(v.checkKind(ctx, adt.BytesKind|adt.StringKind))
}

// Reader returns a new Reader if v is a string or bytes type and an error
// otherwise.
func (v hiddenValue) Reader() (io.Reader, error) {
	v, _ = v.Default()
	ctx := v.ctx()
	switch x := v.eval(ctx).(type) {
	case *adt.Bytes:
		return bytes.NewReader(x.B), nil
	case *adt.String:
		return strings.NewReader(x.Str), nil
	}
	return nil, v.toErr(v.checkKind(ctx, adt.StringKind|adt.BytesKind))
}

// TODO: distinguish between optional, hidden, etc. Probably the best approach
// is to mark options in context and have a single function for creating
// a structVal.

// structVal returns an structVal or an error if v is not a struct.
func (v Value) structValData(ctx *adt.OpContext) (structValue, *adt.Bottom) {
	return v.structValOpts(ctx, options{
		omitHidden:      true,
		omitDefinitions: true,
		omitOptional:    true,
	})
}

func (v Value) structValFull(ctx *adt.OpContext) (structValue, *adt.Bottom) {
	return v.structValOpts(ctx, options{allowScalar: true})
}

// structVal returns an structVal or an error if v is not a struct.
func (v Value) structValOpts(ctx *adt.OpContext, o options) (s structValue, err *adt.Bottom) {
	v, _ = v.Default()

	obj := v.v

	if !o.allowScalar {
		obj, err = v.getStruct()
		if err != nil {
			return structValue{}, err
		}
	}

	features := export.VertexFeatures(obj)

	k := 0
	for _, f := range features {
		if f.IsDef() && (o.omitDefinitions || o.concrete) {
			continue
		}
		if f.IsHidden() && o.omitHidden {
			continue
		}
		if arc := obj.Lookup(f); arc == nil {
			if o.omitOptional {
				continue
			}
			// ensure it really exists.
			v := adt.Vertex{
				Parent: obj,
				Label:  f,
			}
			obj.MatchAndInsert(ctx, &v)
			if len(v.Conjuncts) == 0 {
				continue
			}
		}
		features[k] = f
		k++
	}
	features = features[:k]
	return structValue{ctx, v, obj, features}, nil
}

// Struct returns the underlying struct of a value or an error if the value
// is not a struct.
func (v hiddenValue) Struct() (*Struct, error) {
	// TODO: deprecate
	ctx := v.ctx()
	obj, err := v.structValOpts(ctx, options{})
	if err != nil {
		return nil, v.toErr(err)
	}
	return &Struct{obj}, nil
}

func (v Value) getStruct() (*adt.Vertex, *adt.Bottom) {
	ctx := v.ctx()
	if err := v.checkKind(ctx, adt.StructKind); err != nil {
		if !err.ChildError {
			return nil, err
		}
	}
	return v.v, nil
}

// Struct represents a CUE struct value.
type Struct struct {
	structValue
}

type hiddenStruct = Struct

// FieldInfo contains information about a struct field.
type FieldInfo struct {
	Selector string
	Name     string // Deprecated: use Selector
	Pos      int
	Value    Value

	IsDefinition bool
	IsOptional   bool
	IsHidden     bool
}

func (s *hiddenStruct) Len() int {
	return s.structValue.Len()
}

// field reports information about the ith field, i < o.Len().
func (s *hiddenStruct) Field(i int) FieldInfo {
	a, opt := s.at(i)
	ctx := s.v.ctx()

	v := makeChildValue(s.v, a)
	name := s.v.idx.LabelStr(a.Label)
	str := a.Label.SelectorString(ctx)
	return FieldInfo{str, name, i, v, a.Label.IsDef(), opt, a.Label.IsHidden()}
}

// FieldByName looks up a field for the given name. If isIdent is true, it will
// look up a definition or hidden field (starting with `_` or `_#`). Otherwise
// it interprets name as an arbitrary string for a regular field.
func (s *hiddenStruct) FieldByName(name string, isIdent bool) (FieldInfo, error) {
	f := s.v.idx.Label(name, isIdent)
	for i, a := range s.features {
		if a == f {
			return s.Field(i), nil
		}
	}
	return FieldInfo{}, errNotFound
}

// Fields creates an iterator over the Struct's fields.
func (s *hiddenStruct) Fields(opts ...Option) *Iterator {
	iter, _ := s.v.Fields(opts...)
	return iter
}

// Fields creates an iterator over v's fields if v is a struct or an error
// otherwise.
func (v Value) Fields(opts ...Option) (*Iterator, error) {
	o := options{omitDefinitions: true, omitHidden: true, omitOptional: true}
	o.updateOptions(opts)
	ctx := v.ctx()
	obj, err := v.structValOpts(ctx, o)
	if err != nil {
		return &Iterator{idx: v.idx, ctx: ctx}, v.toErr(err)
	}

	arcs := []field{}
	for i := range obj.features {
		arc, isOpt := obj.at(i)
		arcs = append(arcs, field{arc: arc, isOptional: isOpt})
	}
	return &Iterator{idx: v.idx, ctx: ctx, val: v, arcs: arcs}, nil
}

// Lookup reports the value at a path starting from v. The empty path returns v
// itself.
//
// The Exists() method can be used to verify if the returned value existed.
// Lookup cannot be used to look up hidden or optional fields or definitions.
//
// Deprecated: use LookupPath. At some point before v1.0.0, this method will
// be removed to be reused eventually for looking up a selector.
func (v hiddenValue) Lookup(path ...string) Value {
	ctx := v.ctx()
	for _, k := range path {
		// TODO(eval) TODO(error): always search in full data and change error
		// message if a field is found but is of the incorrect type.
		obj, err := v.structValData(ctx)
		if err != nil {
			// TODO: return a Value at the same location and a new error?
			return newErrValue(v, err)
		}
		v = obj.Lookup(k)
	}
	return v
}

// Path returns the path to this value from the root of an Instance.
//
// This is currently only defined for values that have a fixed path within
// a configuration, and thus not those that are derived from Elem, Template,
// or programmatically generated values such as those returned by Unify.
func (v Value) Path() Path {
	if v.v == nil {
		return Path{}
	}
	return Path{path: appendPath(nil, v)}
}

// Path computes the sequence of Features leading from the root to of the
// instance to this Vertex.
func appendPath(a []Selector, v Value) []Selector {
	if p := v.parent(); p.v != nil {
		a = appendPath(a, p)
	}

	if v.v.Label == 0 {
		// A Label may be 0 for programmatically inserted nodes.
		return a
	}

	var sel selector
	switch f := v.v.Label; f.Typ() {
	case adt.IntLabel:
		sel = indexSelector(f)

	case adt.DefinitionLabel:
		sel = definitionSelector(f.SelectorString(v.idx))

	case adt.HiddenDefinitionLabel, adt.HiddenLabel:
		sel = scopedSelector{
			name: f.IdentString(v.idx),
			pkg:  f.PkgID(v.idx),
		}

	case adt.StringLabel:
		sel = stringSelector(f.StringValue(v.idx))
	}
	return append(a, Selector{sel})
}

// LookupDef is equal to LookupPath(MakePath(Def(name))).
//
// Deprecated: use LookupPath.
func (v hiddenValue) LookupDef(name string) Value {
	return v.LookupPath(MakePath(Def(name)))
}

var errNotFound = errors.Newf(token.NoPos, "field not found")

// FieldByName looks up a field for the given name. If isIdent is true, it will
// look up a definition or hidden field (starting with `_` or `_#`). Otherwise
// it interprets name as an arbitrary string for a regular field.
//
// Deprecated: use LookupPath.
func (v hiddenValue) FieldByName(name string, isIdent bool) (f FieldInfo, err error) {
	s, err := v.Struct()
	if err != nil {
		return f, err
	}
	return s.FieldByName(name, isIdent)
}

// LookupField reports information about a field of v.
//
// Deprecated: use LookupPath
func (v hiddenValue) LookupField(name string) (FieldInfo, error) {
	s, err := v.Struct()
	if err != nil {
		// TODO: return a Value at the same location and a new error?
		return FieldInfo{}, err
	}
	f, err := s.FieldByName(name, true)
	if err != nil {
		return f, err
	}
	if f.IsHidden {
		return f, errNotFound
	}
	return f, err
}

// TODO: expose this API?
//
// // EvalExpr evaluates an expression within the scope of v, which must be
// // a struct.
// //
// // Expressions may refer to builtin packages if they can be uniquely identified.
// func (v Value) EvalExpr(expr ast.Expr) Value {
// 	ctx := v.ctx()
// 	result := evalExpr(ctx, v.eval(ctx), expr)
// 	return newValueRoot(ctx, result)
// }

// Fill creates a new value by unifying v with the value of x at the given path.
//
// Values may be any Go value that can be converted to CUE, an ast.Expr or
// a Value. In the latter case, it will panic if the Value is not from the same
// Runtime.
//
// Any reference in v referring to the value at the given path will resolve
// to x in the newly created value. The resulting value is not validated.
//
// Deprecated: use FillPath.
func (v hiddenValue) Fill(x interface{}, path ...string) Value {
	if v.v == nil {
		return v
	}
	selectors := make([]Selector, len(path))
	for i, p := range path {
		selectors[i] = Str(p)
	}
	return v.FillPath(MakePath(selectors...), x)
}

// FillPath creates a new value by unifying v with the value of x at the given
// path.
//
// If x is an cue/ast.Expr, it will be evaluated within the context of the
// given path: identifiers that are not resolved within the expression are
// resolved as if they were defined at the path position.
//
// If x is a Value, it will be used as is. It panics if x is not created
// from the same Runtime as v.
//
// Otherwise, the given Go value will be converted to CUE using the same rules
// as Context.Encode.
//
// Any reference in v referring to the value at the given path will resolve to x
// in the newly created value. The resulting value is not validated.
//
func (v Value) FillPath(p Path, x interface{}) Value {
	if v.v == nil {
		// TODO: panic here?
		return v
	}
	ctx := v.ctx()
	if err := p.Err(); err != nil {
		return newErrValue(v, mkErr(v.idx, nil, 0, "invalid path: %v", err))
	}
	var expr adt.Expr
	switch x := x.(type) {
	case Value:
		if v.idx != x.idx {
			panic("values are not from the same runtime")
		}
		expr = x.v
	case ast.Expr:
		n := getScopePrefix(v, p)
		expr = resolveExpr(ctx, n, x)
	default:
		expr = convert.GoValueToValue(ctx, x, true)
	}
	for i := len(p.path) - 1; i >= 0; i-- {
		switch sel := p.path[i].sel; {
		case sel == AnyString.sel:
			expr = &adt.StructLit{Decls: []adt.Decl{
				&adt.BulkOptionalField{
					Filter: &adt.BasicType{K: adt.StringKind},
					Value:  expr,
				},
			}}

		case sel == anyIndex.sel:
			expr = &adt.ListLit{Elems: []adt.Elem{
				&adt.Ellipsis{Value: expr},
			}}

		case sel == anyDefinition.sel:
			expr = &adt.Bottom{Err: errors.Newf(token.NoPos,
				"AnyDefinition not supported")}

		case sel.kind() == adt.IntLabel:
			i := sel.feature(ctx.Runtime).Index()
			list := &adt.ListLit{}
			any := &adt.Top{}
			// TODO(perf): make this a constant thing. This will be possible with the query extension.
			for k := 0; k < i; k++ {
				list.Elems = append(list.Elems, any)
			}
			list.Elems = append(list.Elems, expr, &adt.Ellipsis{})
			expr = list

		default:
			var d adt.Decl
			if sel.optional() {
				d = &adt.OptionalField{
					Label: sel.feature(v.idx),
					Value: expr,
				}
			} else {
				d = &adt.Field{
					Label: sel.feature(v.idx),
					Value: expr,
				}
			}
			expr = &adt.StructLit{Decls: []adt.Decl{d}}
		}
	}
	n := &adt.Vertex{}
	n.AddConjunct(adt.MakeRootConjunct(nil, expr))
	n.Finalize(ctx)
	w := makeValue(v.idx, n, v.parent_)
	return v.Unify(w)
}

// Template returns a function that represents the template definition for a
// struct in a configuration file. It returns nil if v is not a struct kind or
// if there is no template associated with the struct.
//
// The returned function returns the value that would be unified with field
// given its name.
//
// Deprecated: use LookupPath in combination with using optional selectors.
func (v hiddenValue) Template() func(label string) Value {
	if v.v == nil {
		return nil
	}

	types := v.v.OptionalTypes()
	if types&(adt.HasAdditional|adt.HasPattern) == 0 {
		return nil
	}

	return func(label string) Value {
		return v.LookupPath(MakePath(Str(label).Optional()))
	}
}

// Subsume reports nil when w is an instance of v or an error otherwise.
//
// Without options, the entire value is considered for assumption, which means
// Subsume tests whether  v is a backwards compatible (newer) API version of w.
//
// Use the Final option to check subsumption if a w is known to be final, and
// should assumed to be closed.
//
// Use the Raw option to do a low-level subsumption, taking defaults into
// account.
//
// Value v and w must be obtained from the same build. TODO: remove this
// requirement.
func (v Value) Subsume(w Value, opts ...Option) error {
	o := getOptions(opts)
	p := subsume.CUE
	switch {
	case o.final && o.ignoreClosedness:
		p = subsume.FinalOpen
	case o.final:
		p = subsume.Final
	case o.ignoreClosedness:
		p = subsume.API
	}
	if !o.raw {
		p.Defaults = true
	}
	ctx := v.ctx()
	return p.Value(ctx, v.v, w.v)
}

// Deprecated: use Subsume.
//
// Subsumes reports whether w is an instance of v.
//
// Without options, Subsumes checks whether v is a backwards compatbile schema
// of w.
//
// By default, Subsumes tests whether two values are compatible
// Value v and w must be obtained from the same build.
// TODO: remove this requirement.
func (v hiddenValue) Subsumes(w Value) bool {
	ctx := v.ctx()
	p := subsume.Profile{Defaults: true}
	return p.Check(ctx, v.v, w.v)
}

func isDef(v *adt.Vertex) bool {
	for ; v != nil; v = v.Parent {
		if v.Label.IsDef() {
			return true
		}
	}
	return false
}

func allowed(ctx *adt.OpContext, parent, n *adt.Vertex) *adt.Bottom {
	if !parent.IsClosedList() && !parent.IsClosedStruct() && !isDef(parent) {
		return nil
	}

	for _, a := range n.Arcs {
		if !parent.Accept(ctx, a.Label) {
			defer ctx.PopArc(ctx.PushArc(parent))
			label := a.Label.SelectorString(ctx)
			parent.Accept(ctx, a.Label)
			return ctx.NewErrf("field %s not allowed", label)
		}
	}
	return nil
}

func addConjuncts(dst, src *adt.Vertex) {
	c := adt.MakeRootConjunct(nil, src)
	if src.Closed {
		var root adt.CloseInfo
		c.CloseInfo = root.SpawnRef(src, src.Closed, nil)
	}
	dst.AddConjunct(c)
}

// Unify reports the greatest lower bound of v and w.
//
// Value v and w must be obtained from the same build.
// TODO: remove this requirement.
func (v Value) Unify(w Value) Value {
	if v.v == nil {
		return w
	}
	if w.v == nil {
		return v
	}

	n := &adt.Vertex{}
	addConjuncts(n, v.v)
	addConjuncts(n, w.v)

	ctx := newContext(v.idx)
	n.Finalize(ctx)

	n.Parent = v.v.Parent
	n.Label = v.v.Label
	n.Closed = v.v.Closed || w.v.Closed

	if err := n.Err(ctx, adt.Finalized); err != nil {
		return makeValue(v.idx, n, v.parent_)
	}
	if err := allowed(ctx, v.v, n); err != nil {
		return newErrValue(w, err)
	}
	if err := allowed(ctx, w.v, n); err != nil {
		return newErrValue(v, err)
	}

	return makeValue(v.idx, n, v.parent_)
}

// UnifyAccept is as v.Unify(w), but will disregard any field that is allowed
// in the Value accept.
func (v Value) UnifyAccept(w Value, accept Value) Value {
	if v.v == nil {
		return w
	}
	if w.v == nil {
		return v
	}
	if accept.v == nil {
		panic("accept must exist")
	}

	n := &adt.Vertex{}
	n.AddConjunct(adt.MakeRootConjunct(nil, v.v))
	n.AddConjunct(adt.MakeRootConjunct(nil, w.v))

	ctx := newContext(v.idx)
	n.Finalize(ctx)

	n.Parent = v.v.Parent
	n.Label = v.v.Label

	if err := n.Err(ctx, adt.Finalized); err != nil {
		return makeValue(v.idx, n, v.parent_)
	}
	if err := allowed(ctx, accept.v, n); err != nil {
		return newErrValue(accept, err)
	}

	return makeValue(v.idx, n, v.parent_)
}

// Equals reports whether two values are equal, ignoring optional fields.
// The result is undefined for incomplete values.
func (v Value) Equals(other Value) bool {
	if v.v == nil || other.v == nil {
		return false
	}
	return adt.Equal(v.ctx(), v.v, other.v, 0)
}

func (v Value) instance() *Instance {
	if v.v == nil {
		return nil
	}
	return getImportFromNode(v.idx, v.v)
}

// Reference returns the instance and path referred to by this value such that
// inst.Lookup(path) resolves to the same value, or no path if this value is not
// a reference. If a reference contains index selection (foo[bar]), it will
// only return a reference if the index resolves to a concrete value.
//
// Deprecated: use ReferencePath
func (v hiddenValue) Reference() (inst *Instance, path []string) {
	root, p := v.ReferencePath()
	if !root.Exists() {
		return nil, nil
	}

	inst = getImportFromNode(v.idx, root.v)
	for _, sel := range p.Selectors() {
		switch x := sel.sel.(type) {
		case stringSelector:
			path = append(path, string(x))
		default:
			path = append(path, sel.String())
		}
	}

	return inst, path
}

// ReferencePath returns the value and path referred to by this value such that
// value.LookupPath(path) resolves to the same value, or no path if this value
// is not a reference.
func (v Value) ReferencePath() (root Value, p Path) {
	// TODO: don't include references to hidden fields.
	if v.v == nil || len(v.v.Conjuncts) != 1 {
		return Value{}, Path{}
	}
	ctx := v.ctx()
	c := v.v.Conjuncts[0]

	x, path := reference(v.idx, ctx, c.Env, c.Expr())
	if x == nil {
		return Value{}, Path{}
	}
	// NOTE: due to structure sharing, the path of the referred node may end
	// up different from the one explicitly pointed to. The value will be the
	// same, but the scope may differ.
	// TODO(structureshare): see if we can construct the original path. This
	// only has to be done if structures are being shared.
	return makeValue(v.idx, x, nil), Path{path: path}
}

func reference(rt *runtime.Runtime, c *adt.OpContext, env *adt.Environment, r adt.Expr) (inst *adt.Vertex, path []Selector) {
	ctx := c
	defer ctx.PopState(ctx.PushState(env, r.Source()))

	switch x := r.(type) {
	// TODO: do we need to handle Vertex as well, in case this is hard-wired?
	// Probably not, as this results from dynamic content.

	case *adt.NodeLink:
		// TODO: consider getting rid of NodeLink.
		inst, path = mkPath(rt, nil, x.Node)

	case *adt.FieldReference:
		env := ctx.Env(x.UpCount)
		inst, path = mkPath(rt, nil, env.Vertex)
		path = appendSelector(path, featureToSel(x.Label, rt))

	case *adt.LabelReference:
		env := ctx.Env(x.UpCount)
		return mkPath(rt, nil, env.Vertex)

	case *adt.DynamicReference:
		env := ctx.Env(x.UpCount)
		inst, path = mkPath(rt, nil, env.Vertex)
		v, _ := ctx.Evaluate(env, x.Label)
		path = appendSelector(path, valueToSel(v))

	case *adt.ImportReference:
		inst, _ = rt.LoadImport(rt.LabelStr(x.ImportPath))

	case *adt.SelectorExpr:
		inst, path = reference(rt, c, env, x.X)
		path = appendSelector(path, featureToSel(x.Sel, rt))

	case *adt.IndexExpr:
		inst, path = reference(rt, c, env, x.X)
		v, _ := ctx.Evaluate(env, x.Index)
		path = appendSelector(path, valueToSel(v))
	}
	if inst == nil {
		return nil, nil
	}
	return inst, path
}

func mkPath(r *runtime.Runtime, a []Selector, v *adt.Vertex) (root *adt.Vertex, path []Selector) {
	if v.Parent == nil {
		return v, a
	}
	root, path = mkPath(r, a, v.Parent)
	path = appendSelector(path, featureToSel(v.Label, r))
	return root, path
}

type options struct {
	concrete          bool // enforce that values are concrete
	raw               bool // show original values
	hasHidden         bool
	omitHidden        bool
	omitDefinitions   bool
	omitOptional      bool
	omitAttrs         bool
	resolveReferences bool
	final             bool
	ignoreClosedness  bool // used for comparing APIs
	docs              bool
	disallowCycles    bool // implied by concrete
	allowScalar       bool
}

// An Option defines modes of evaluation.
type Option option

type option func(p *options)

// Final indicates a value is final. It implicitly closes all structs and lists
// in a value and selects defaults.
func Final() Option {
	return func(o *options) {
		o.final = true
		o.omitDefinitions = true
		o.omitOptional = true
		o.omitHidden = true
	}
}

// Schema specifies the input is a Schema. Used by Subsume.
func Schema() Option {
	return func(o *options) {
		o.ignoreClosedness = true
	}
}

// Concrete ensures that all values are concrete.
//
// For Validate this means it returns an error if this is not the case.
// In other cases a non-concrete value will be replaced with an error.
func Concrete(concrete bool) Option {
	return func(p *options) {
		if concrete {
			p.concrete = true
			p.final = true
			if !p.hasHidden {
				p.omitHidden = true
				p.omitDefinitions = true
			}
		}
	}
}

// DisallowCycles forces validation in the precense of cycles, even if
// non-concrete values are allowed. This is implied by Concrete(true).
func DisallowCycles(disallow bool) Option {
	return func(p *options) { p.disallowCycles = disallow }
}

// ResolveReferences forces the evaluation of references when outputting.
// This implies the input cannot have cycles.
func ResolveReferences(resolve bool) Option {
	return func(p *options) { p.resolveReferences = resolve }
}

// Raw tells Syntax to generate the value as is without any simplifications.
func Raw() Option {
	return func(p *options) { p.raw = true }
}

// All indicates that all fields and values should be included in processing
// even if they can be elided or omitted.
func All() Option {
	return func(p *options) {
		p.omitAttrs = false
		p.omitHidden = false
		p.omitDefinitions = false
		p.omitOptional = false
	}
}

// Docs indicates whether docs should be included.
func Docs(include bool) Option {
	return func(p *options) { p.docs = true }
}

// Definitions indicates whether definitions should be included.
//
// Definitions may still be included for certain functions if they are referred
// to by other other values.
func Definitions(include bool) Option {
	return func(p *options) {
		p.hasHidden = true
		p.omitDefinitions = !include
	}
}

// Hidden indicates that definitions and hidden fields should be included.
func Hidden(include bool) Option {
	return func(p *options) {
		p.hasHidden = true
		p.omitHidden = !include
		p.omitDefinitions = !include
	}
}

// Optional indicates that optional fields should be included.
func Optional(include bool) Option {
	return func(p *options) { p.omitOptional = !include }
}

// Attributes indicates that attributes should be included.
func Attributes(include bool) Option {
	return func(p *options) { p.omitAttrs = !include }
}

func getOptions(opts []Option) (o options) {
	o.updateOptions(opts)
	return
}

func (o *options) updateOptions(opts []Option) {
	for _, fn := range opts {
		fn(o)
	}
}

// Validate reports any errors, recursively. The returned error may represent
// more than one error, retrievable with errors.Errors, if more than one
// exists.
func (v Value) Validate(opts ...Option) error {
	o := options{}
	o.updateOptions(opts)

	cfg := &validate.Config{
		Concrete:       o.concrete,
		DisallowCycles: o.disallowCycles,
		AllErrors:      true,
	}

	b := validate.Validate(v.ctx(), v.v, cfg)
	if b != nil {
		return b.Err
	}
	return nil
}

// Walk descends into all values of v, calling f. If f returns false, Walk
// will not descent further. It only visits values that are part of the data
// model, so this excludes optional fields, hidden fields, and definitions.
func (v Value) Walk(before func(Value) bool, after func(Value)) {
	ctx := v.ctx()
	switch v.Kind() {
	case StructKind:
		if before != nil && !before(v) {
			return
		}
		obj, _ := v.structValData(ctx)
		for i := 0; i < obj.Len(); i++ {
			_, v := obj.At(i)
			v.Walk(before, after)
		}
	case ListKind:
		if before != nil && !before(v) {
			return
		}
		list, _ := v.List()
		for list.Next() {
			list.Value().Walk(before, after)
		}
	default:
		if before != nil {
			before(v)
		}
	}
	if after != nil {
		after(v)
	}
}

// Expr reports the operation of the underlying expression and the values it
// operates on.
//
// For unary expressions, it returns the single value of the expression.
//
// For binary expressions it returns first the left and right value, in that
// order. For associative operations however, (for instance '&' and '|'), it may
// return more than two values, where the operation is to be applied in
// sequence.
//
// For selector and index expressions it returns the subject and then the index.
// For selectors, the index is the string value of the identifier.
//
// For interpolations it returns a sequence of values to be concatenated, some
// of which will be literal strings and some unevaluated expressions.
//
// A builtin call expression returns the value of the builtin followed by the
// args of the call.
func (v Value) Expr() (Op, []Value) {
	// TODO: return v if this is complete? Yes for now
	if v.v == nil {
		return NoOp, nil
	}

	var expr adt.Expr
	var env *adt.Environment

	if v.v.IsData() {
		expr = v.v.Value()

	} else {
		switch len(v.v.Conjuncts) {
		case 0:
			if v.v.BaseValue == nil {
				return NoOp, []Value{makeValue(v.idx, v.v, v.parent_)} // TODO: v?
			}
			expr = v.v.Value()

		case 1:
			// the default case, processed below.
			c := v.v.Conjuncts[0]
			env = c.Env
			expr = c.Expr()
			if w, ok := expr.(*adt.Vertex); ok {
				return Value{v.idx, w, v.parent_}.Expr()
			}

		default:
			a := []Value{}
			ctx := v.ctx()
			for _, c := range v.v.Conjuncts {
				// Keep parent here. TODO: do we need remove the requirement
				// from other conjuncts?
				n := &adt.Vertex{
					Parent: v.v.Parent,
					Label:  v.v.Label,
				}
				n.AddConjunct(c)
				n.Finalize(ctx)
				a = append(a, makeValue(v.idx, n, v.parent_))
			}
			return adt.AndOp, a
		}
	}

	// TODO: replace appends with []Value{}. For not leave.
	a := []Value{}
	op := NoOp
	switch x := expr.(type) {
	case *adt.BinaryExpr:
		a = append(a, remakeValue(v, env, x.X))
		a = append(a, remakeValue(v, env, x.Y))
		op = x.Op
	case *adt.UnaryExpr:
		a = append(a, remakeValue(v, env, x.X))
		op = x.Op
	case *adt.BoundExpr:
		a = append(a, remakeValue(v, env, x.Expr))
		op = x.Op
	case *adt.BoundValue:
		a = append(a, remakeValue(v, env, x.Value))
		op = x.Op
	case *adt.Conjunction:
		// pre-expanded unification
		for _, conjunct := range x.Values {
			a = append(a, remakeValue(v, env, conjunct))
		}
		op = AndOp
	case *adt.Disjunction:
		count := 0
	outer:
		for i, disjunct := range x.Values {
			if i < x.NumDefaults {
				for _, n := range x.Values[x.NumDefaults:] {
					if subsume.Value(v.ctx(), n, disjunct) == nil {
						continue outer
					}
				}
			}
			count++
			a = append(a, remakeValue(v, env, disjunct))
		}
		if count > 1 {
			op = OrOp
		}

	case *adt.DisjunctionExpr:
		// Filter defaults that are subsumed by another value.
		count := 0
	outerExpr:
		for _, disjunct := range x.Values {
			if disjunct.Default {
				for _, n := range x.Values {
					a := adt.Vertex{
						Label: v.v.Label,
					}
					b := a
					a.AddConjunct(adt.MakeRootConjunct(env, n.Val))
					b.AddConjunct(adt.MakeRootConjunct(env, disjunct.Val))

					ctx := eval.NewContext(v.idx, nil)
					ctx.Unify(&a, adt.Finalized)
					ctx.Unify(&b, adt.Finalized)
					if allowed(ctx, v.v, &b) != nil {
						// Everything subsumed bottom
						continue outerExpr
					}
					if allowed(ctx, v.v, &a) != nil {
						// An error doesn't subsume anything except another error.
						continue
					}
					a.Parent = v.v.Parent
					if !n.Default && subsume.Value(ctx, &a, &b) == nil {
						continue outerExpr
					}
				}
			}
			count++
			a = append(a, remakeValue(v, env, disjunct.Val))
		}
		if count > 1 {
			op = adt.OrOp
		}

	case *adt.Interpolation:
		for _, p := range x.Parts {
			a = append(a, remakeValue(v, env, p))
		}
		op = InterpolationOp

	case *adt.FieldReference:
		// TODO: allow hard link
		ctx := v.ctx()
		f := ctx.PushState(env, x.Src)
		env := ctx.Env(x.UpCount)
		a = append(a, remakeValue(v, nil, &adt.NodeLink{Node: env.Vertex}))
		a = append(a, remakeValue(v, nil, ctx.NewString(x.Label.SelectorString(ctx))))
		_ = ctx.PopState(f)
		op = SelectorOp

	case *adt.SelectorExpr:
		a = append(a, remakeValue(v, env, x.X))
		// A string selector is quoted.
		a = append(a, remakeValue(v, env, &adt.String{
			Str: x.Sel.SelectorString(v.idx),
		}))
		op = SelectorOp

	case *adt.IndexExpr:
		a = append(a, remakeValue(v, env, x.X))
		a = append(a, remakeValue(v, env, x.Index))
		op = IndexOp
	case *adt.SliceExpr:
		a = append(a, remakeValue(v, env, x.X))
		a = append(a, remakeValue(v, env, x.Lo))
		a = append(a, remakeValue(v, env, x.Hi))
		op = SliceOp
	case *adt.CallExpr:
		// Interpret "and" and "or" builtin semantically.
		if fn, ok := x.Fun.(*adt.Builtin); ok && len(x.Args) == 1 &&
			(fn.Name == "or" || fn.Name == "and") {

			iter, _ := remakeValue(v, env, x.Args[0]).List()
			for iter.Next() {
				a = append(a, iter.Value())
			}

			op = OrOp
			if fn.Name == "and" {
				op = AndOp
			}
			break
		}
		a = append(a, remakeValue(v, env, x.Fun))
		for _, arg := range x.Args {
			a = append(a, remakeValue(v, env, arg))
		}
		op = CallOp
	case *adt.BuiltinValidator:
		a = append(a, remakeValue(v, env, x.Builtin))
		for _, arg := range x.Args {
			a = append(a, remakeValue(v, env, arg))
		}
		op = CallOp

	case *adt.StructLit:
		// Simulate old embeddings.
		envEmbed := &adt.Environment{
			Up:     env,
			Vertex: v.v,
		}
		fields := []adt.Decl{}
		ctx := v.ctx()
		for _, d := range x.Decls {
			switch x := d.(type) {
			case adt.Expr:
				// embedding
				n := &adt.Vertex{Label: v.v.Label}
				c := adt.MakeRootConjunct(envEmbed, x)
				n.AddConjunct(c)
				n.Finalize(ctx)
				n.Parent = v.v.Parent
				a = append(a, makeValue(v.idx, n, v.parent_))

			default:
				fields = append(fields, d)
			}
		}
		if len(a) == 0 {
			a = append(a, v)
			break
		}

		if len(fields) > 0 {
			n := &adt.Vertex{
				Label: v.v.Label,
			}
			c := adt.MakeRootConjunct(env, &adt.StructLit{
				Decls: fields,
			})
			n.AddConjunct(c)
			n.Finalize(ctx)
			n.Parent = v.v.Parent
			a = append(a, makeValue(v.idx, n, v.parent_))
		}

		op = adt.AndOp

	default:
		a = append(a, v)
	}
	return op, a
}
