// 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/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)
	i.cur = makeValue(i.val.idx, f.arc)
	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.
//
// 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
}

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 makeValue(v.idx, 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)
}

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)
}

// 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)
	return makeValue(v.idx, n)
}

func makeValue(idx *runtime.Runtime, v *adt.Vertex) 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}
}

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}
	}
	n := &adt.Vertex{Label: base.v.Label}
	n.AddConjunct(adt.MakeRootConjunct(env, v))
	n = manifest(base.ctx(), n)
	n.Parent = base.v.Parent
	return makeValue(base.idx, 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 makeValue(base.idx, n)
}

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

func (v Value) makeChild(ctx *adt.OpContext, i uint32, a *adt.Vertex) Value {
	a.Parent = v.v
	return makeValue(v.idx, a)
}

// 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)
	// 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), 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 := makeValue(s.v.idx, 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{}
	}
	p := v.v.Path()
	a := make([]Selector, len(p))
	for i, f := range p {
		switch f.Typ() {
		case adt.IntLabel:
			a[i] = Selector{indexSelector(f)}

		case adt.DefinitionLabel:
			a[i] = Selector{definitionSelector(f.SelectorString(v.idx))}

		case adt.HiddenDefinitionLabel, adt.HiddenLabel:
			a[i] = Selector{scopedSelector{
				name: f.IdentString(v.idx),
				pkg:  f.PkgID(v.idx),
			}}

		case adt.StringLabel:
			a[i] = Selector{stringSelector(f.StringValue(v.idx))}
		}
	}
	return Path{path: a}
}

// 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.
//
// 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.
//
// List paths are not supported at this time.
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 adt.Node, adt.Feature:
		panic("cannot set internal Value or Feature type")
	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-- {
		expr = &adt.StructLit{Decls: []adt.Decl{
			&adt.Field{
				Label: p.path[i].sel.feature(v.idx),
				Value: expr,
			},
		}}
	}
	n := &adt.Vertex{}
	n.AddConjunct(adt.MakeRootConjunct(nil, expr))
	n.Finalize(ctx)
	w := makeValue(v.idx, n)
	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)
	}
	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)
}

// 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)
	}
	if err := allowed(ctx, accept.v, n); err != nil {
		return newErrValue(accept, err)
	}

	return makeValue(v.idx, n)
}

// 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{}
	}
	return makeValue(v.idx, x), 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)}
			}
			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}.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))
			}
			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))

			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))
		}

		op = adt.AndOp

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