// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package vdl

// Naming conventions to distinguish this package from reflect:
//   tt - refers to *Type
//   vv - refers to *Value
//   rt - refers to reflect.Type
//   rv - refers to reflect.Value

import (
	"errors"
	"fmt"
	"reflect"
)

var (
	ErrFieldNoExist = errors.New("field doesn't exist")

	errTargetInvalid    = errors.New("invalid target")
	errTargetUnsettable = errors.New("unsettable target")
	errArrayIndex       = errors.New("array index out of range")
)

// convTarget represents the state and logic for value conversion.
//
// TODO(toddw): Split convTarget apart into reflectTarget and valueTarget.
type convTarget struct {
	// Conceptually this is a disjoint union between the two types of destination
	// values: *Value and reflect.Value.  Only one of the vv and rv fields is
	// ever valid.  We split into two fields and perform "if vv == nil" checks in
	// each method rather than using an interface for performance reasons.
	//
	// The tt field is always non-nil, and represents the type of the value.
	tt *Type
	vv *Value
	rv reflect.Value
}

// ReflectTarget returns a conversion Target based on the given reflect.Value.
// Some rules depending on the type of rv:
//   o If rv is a valid *Value, it is filled in directly.
//   o Otherwise rv must be a settable value (i.e. it must be a pointer).
//   o Pointers are followed, and logically "flattened".
//   o New values are automatically created for nil pointers.
//   o Targets convertible to *Type and *Value are filled in directly.
func ReflectTarget(rv reflect.Value) (Target, error) {
	if !rv.IsValid() {
		return nil, errTargetInvalid
	}
	if vv := extractValue(rv); vv.IsValid() {
		return valueConv(vv), nil
	}
	if !rv.CanSet() && rv.Kind() == reflect.Ptr && !rv.IsNil() {
		// Dereference the pointer a single time to make rv settable.
		rv = rv.Elem()
	}
	tt, err := TypeFromReflect(rv.Type())
	if err != nil {
		return nil, err
	}
	target, err := reflectConv(rv, tt)
	if err != nil {
		return nil, err
	}
	return target, nil
}

// ValueTarget returns a conversion Target based on the given Value.
// Returns an error if the given Value isn't valid.
func ValueTarget(vv *Value) (Target, error) {
	if !vv.IsValid() {
		return nil, errTargetInvalid
	}
	return valueConv(vv), nil
}

func reflectConv(rv reflect.Value, tt *Type) (convTarget, error) {
	if !rv.IsValid() {
		return convTarget{}, errTargetInvalid
	}
	if vv := extractValue(rv); vv.IsValid() {
		return valueConv(vv), nil
	}
	if !rv.CanSet() {
		return convTarget{}, errTargetUnsettable
	}
	return convTarget{tt: tt, rv: rv}, nil
}

func valueConv(vv *Value) convTarget {
	return convTarget{tt: vv.Type(), vv: vv}
}

func extractValue(rv reflect.Value) *Value {
	for rv.Kind() == reflect.Ptr && !rv.IsNil() {
		if rv.Type().ConvertibleTo(rtPtrToValue) {
			return rv.Convert(rtPtrToValue).Interface().(*Value)
		}
		rv = rv.Elem()
	}
	return nil
}

// startConvert prepares to fill in c, converting from type ttFrom.  Returns fin
// and fill which are used by finishConvert to finish the conversion; fin
// represents the final target to assign to, and fill represents the target to
// actually fill in.
func startConvert(c convTarget, ttFrom *Type) (fin, fill convTarget, err error) {
	if ttFrom.Kind() == Any {
		return convTarget{}, convTarget{}, fmt.Errorf("can't convert from type %q - either call target.FromNil or target.From* for the element value", ttFrom)
	}
	if !compatible(c.tt, ttFrom) {
		return convTarget{}, convTarget{}, fmt.Errorf("types %q and %q aren't compatible", c.tt, ttFrom)
	}
	fin = createFinTarget(c, ttFrom)
	fill, err = createFillTarget(fin, ttFrom)
	if err != nil {
		return convTarget{}, convTarget{}, err
	}
	return fin, fill, nil
}

// setZeroVDLValue checks whether rv is convertible to *Value, and if so,
// sets rv to the zero value of ttFrom, returning the resulting value.
func setZeroVDLValue(rv reflect.Value, ttFrom *Type) *Value {
	if rv.Type().ConvertibleTo(rtPtrToValue) {
		vv := rv.Convert(rtPtrToValue).Interface().(*Value)
		if !vv.IsValid() {
			vv = ZeroValue(ttFrom)
			rv.Set(reflect.ValueOf(vv).Convert(rv.Type()))
		}
		return vv
	}
	return nil
}

// createFinTarget returns the fin target for the conversion, flattening
// pointers and creating new non-nil values as necessary.
func createFinTarget(c convTarget, ttFrom *Type) convTarget {
	if c.vv == nil {
		// Create new pointers down to the final non-pointer value.
		for c.rv.Kind() == reflect.Ptr {
			// Handle case where rv is *Value; fill it in directly.
			if vv := setZeroVDLValue(c.rv, ttFrom); vv.IsValid() {
				if vv.Kind() == Optional {
					vv.Assign(NonNilZeroValue(vv.Type()))
					return convTarget{tt: ttFrom, vv: vv.Elem()}
				}
				return convTarget{tt: ttFrom, vv: vv}
			}
			// Set nil pointers to new pointers.
			if c.rv.IsNil() {
				c.rv.Set(reflect.New(c.rv.Type().Elem()))
			}
			// Stop at *Type to allow TypeObject values to be assigned.
			if c.rv.Type().Elem() == rtType {
				return c
			}
			c.rv = c.rv.Elem()
		}
		if c.tt.Kind() == Optional {
			c.tt = c.tt.Elem() // flatten c.tt to match c.rv
		}
	} else {
		// Create a non-nil value for optional types.
		if c.tt.Kind() == Optional {
			c.vv.Assign(NonNilZeroValue(c.tt))
			c.tt, c.vv = c.tt.Elem(), c.vv.Elem()
		}
	}
	return c
}

// createFillTarget returns the fill target for the conversion, creating new
// values of the appropriate type if necessary.  The fill target must be a
// concrete type; if fin has type interface/any, we'll create a concrete type,
// and finishConvert will assign fin from the fill target.  The type we choose
// to create is either a special-case (error or union), or based on the ttFrom
// type we're converting *from*.
//
// If fin is already a concrete type it's used directly as the fill target.
//
// There is one particularly weird trick that we need to use when the conversion
// target (i.e. fin) is a reflect union interface.  The problem is that
// createFillTarget is called before we know which union field is set, so
// there's no way to create a concrete union struct representing the appropriate
// field.  So we return a vdl.Value as the fill target, to capture the value.
// We still want the concrete union struct to be created at the end of the
// conversion, so we call makeReflectUnion in finishConvert to convert the
// vdl.Value back into a concrete union struct, which needs to work even if the
// type hasn't been registered.
//
// The comments below refer to this trick as the UNION TRICK.
//
// TODO(toddw): The UNION TRICK is probably very slow.  We should benchmark and
// probably re-design our conversion strategy.
//
// TODO(toddw): The conversion logic is way too complicated, with many similar
// branches; rewrite this entire file..
func createFillTarget(fin convTarget, ttFrom *Type) (convTarget, error) {
	if fin.vv == nil {
		// Handle case where fin.rv is the native error type; create the standard
		// WireError struct to fill in.
		if ni, err := nativeInfoForError(); err == nil && fin.rv.Type() == ni.NativeType {
			return reflectConv(reflect.New(rtWireError).Elem(), ErrorType.Elem())
		}
		// Handle case where fin.rv is a native type; return the wire type as the
		// fill target, and rely on finishConvert to perform the final step of
		// converting from the wire type to the native type.
		//
		// TODO(toddw): This doesn't handle pointer native types.
		if ni := nativeInfoFromNative(fin.rv.Type()); ni != nil {
			tt, err := TypeFromReflect(ni.WireType)
			if err != nil {
				return convTarget{}, err
			}
			if tt.Kind() == Union {
				// The wire type is a union.  Apply the UNION TRICK (see above), and
				// fill *Value, since we don't know which field is set.
				return valueConv(ZeroValue(tt)), nil
			}
			return reflectConv(reflect.New(ni.WireType).Elem(), tt)
		}
		if fin.rv.Kind() == reflect.Interface {
			// We're converting into an interface, so we can't just fill into the fin
			// target directly.  Return the appropriate fill value.
			switch {
			case fin.rv.Type() == rtError || ttFrom == ErrorType:
				// Create the standard WireError struct to fill in, with the pointer.
				return reflectConv(reflect.New(rtWireError).Elem(), ErrorType)
			case ttFrom == ErrorType.Elem():
				// Create the standard WireError struct to fill in, without the pointer.
				return reflectConv(reflect.New(rtWireError).Elem(), ErrorType.Elem())
			case fin.tt.Kind() == Union:
				// The fin target is a union interface.  Apply the UNION TRICK (see
				// above), and fill *Value, since we don't know which field is set.
				return valueConv(ZeroValue(fin.tt)), nil
			case fin.tt.Kind() != Any:
				return convTarget{}, fmt.Errorf("internal error - cannot convert to Go type %v vdl type %v from %v", fin.rv.Type(), fin.tt, ttFrom)
			}
			// We're converting into any, and ttFrom is the type we're converting
			// *from*.  First handle the special-case *Type.
			if ttFrom.Kind() == TypeObject {
				return reflectConv(reflect.New(rtPtrToType).Elem(), TypeObjectType)
			}
			// Try to create a reflect.Type out of ttFrom, and if it exists, create a real
			// object to fill in.
			if rt := TypeToReflect(ttFrom); rt != nil {
				if rt.Kind() == reflect.Ptr && ttFrom.Kind() == Optional {
					rt = rt.Elem()
				}
				// Handle case where rt is a native type; return the wire type as the
				// fill target, and rely on finishConvert to perform the final step of
				// converting from the wire type to the native type.
				if ni := nativeInfoFromNative(rt); ni != nil {
					if ttFrom.Kind() == Union {
						// The wire type is a union interface.  Apply the UNION TRICK (see
						// above), and fill *Value, since we don't know which field is set.
						return valueConv(ZeroValue(ttFrom)), nil
					}
					return reflectConv(reflect.New(ni.WireType).Elem(), ttFrom)
				}
				if rt.Kind() == reflect.Interface && ttFrom.Kind() == Union {
					// The wire type is a union interface.  Apply the UNION TRICK (see
					// above), and fill *Value, since we don't know which field is set.
					return valueConv(ZeroValue(ttFrom)), nil
				}
				rv := reflect.New(rt).Elem()
				for rv.Kind() == reflect.Ptr {
					rv.Set(reflect.New(rv.Type().Elem()))
					rv = rv.Elem()
				}
				return reflectConv(rv, ttFrom)
			}
			// We don't have the type name in our registry, so create a concrete
			// *Value to fill in, based on ttFrom.
			if ttFrom.Kind() == Optional {
				return convTarget{tt: ttFrom, vv: ZeroValue(ttFrom.Elem())}, nil
			}
			return convTarget{tt: ttFrom, vv: ZeroValue(ttFrom)}, nil
		}
		// We're not converting into an interface, so we can fill into the fin
		// target directly.  Assign an appropriate zero value.
		fin.rv.Set(rvSettableZeroValue(fin.rv.Type(), ttFrom))
	} else {
		switch fin.vv.Kind() {
		case Any:
			if ttFrom.Kind() == Optional {
				return convTarget{tt: ttFrom, vv: ZeroValue(ttFrom.Elem())}, nil
			}
			return convTarget{tt: ttFrom, vv: ZeroValue(ttFrom)}, nil
		default:
			fin.vv.Assign(nil) // start with zero item
		}
	}
	return fin, nil
}

// finishConvert finishes converting a value, taking the fin and fill returned
// by startConvert.  This is necessary since interface/any values are assigned
// by value, and can't be filled in by reference.
func finishConvert(fin, fill convTarget) error {
	// The logic here mirrors the logic in createFillTarget.
	if fin.vv == nil {
		// Handle mirrored case in createFillTarget where fin.rv is the native error
		// type; fill.rv is WireError.
		if ni, err := nativeInfoForError(); err == nil && fin.rv.Type() == ni.NativeType {
			return ni.ToNative(fill.rv, fin.rv.Addr())
		}
		// Handle mirrored case in createFillTarget where fin.rv is a native type;
		// fill.rv is the wire type that has been filled in.
		if ni := nativeInfoFromNative(fin.rv.Type()); ni != nil {
			tt, err := TypeFromReflect(ni.WireType)
			if err != nil {
				return err
			}
			rvFill := fill.rv
			if tt.Kind() == Union {
				// If the fill target is a union type, finish conversion for the UNION
				// TRICK (see above), to turn it into a concrete field struct.
				if rvFill, err = makeReflectUnion(ni.WireType, fill.vv); err != nil {
					return err
				}
			}
			return ni.ToNative(rvFill, fin.rv.Addr())
		}
		if fin.rv.Kind() == reflect.Interface {
			// The fill value may be set to either rv or vv in startConvert above.
			var rvFill reflect.Value
			if fill.vv == nil {
				rvFill = fill.rv
				if fill.rv.Type() == rtWireError {
					// Handle case where fill.rv has type WireError; if error conversions
					// have been registered with the vdl package, we need to convert to
					// the standard error interface.
					if ni, err := nativeInfoForError(); err == nil {
						newNative := reflect.New(ni.NativeType)
						if err := ni.ToNative(fill.rv, newNative); err != nil {
							return err
						}
						rvFill = newNative.Elem()
					}
				} else if ni := nativeInfoFromWire(fill.rv.Type()); ni != nil {
					// Handle case where fill.rv is a wire type with a native type; set
					// rvFill to a new native type and call ToNative to fill it in.
					newNative := reflect.New(ni.NativeType)
					if err := ni.ToNative(fill.rv, newNative); err != nil {
						return err
					}
					rvFill = newNative.Elem()
				}
				if fill.tt.Kind() == Optional {
					// Convert rvFill into a pointer if it should be optional.
					if rvFill.CanAddr() {
						rvFill = rvFill.Addr()
					} else {
						rvNew := reflect.New(rvFill.Type())
						rvNew.Elem().Set(rvFill)
						rvFill = rvNew
					}
				}
			} else {
				// If the fill target is a union type, finish conversion for the UNION
				// TRICK (see above), to turn it into a concrete field struct.
				if fill.tt.Kind() == Union {
					var err error
					rvFill, err = makeReflectUnion(fin.rv.Type(), fill.vv)
					if err != nil {
						// Handle case where fin.rv is a native type; fill.vv is the union
						// wire type that has been filled in.
						if rt := TypeToReflect(fill.tt); rt != nil {
							if ni := nativeInfoFromNative(rt); ni != nil {
								rvWireUnion, err := makeReflectUnion(ni.WireType, fill.vv)
								if err != nil {
									return err
								}
								newNative := reflect.New(ni.NativeType)
								if err := ni.ToNative(rvWireUnion, newNative); err != nil {
									return err
								}
								rvFill = newNative.Elem()
							}
						}
					}
				}
				if !rvFill.IsValid() {
					switch fill.tt.Kind() {
					case Optional:
						rvFill = reflect.ValueOf(OptionalValue(fill.vv))
					default:
						rvFill = reflect.ValueOf(fill.vv)
					}
				}
			}
			if to, from := fin.rv.Type(), rvFill.Type(); !from.AssignableTo(to) {
				return fmt.Errorf("%v not assignable from %v", to, from)
			}
			fin.rv.Set(rvFill)
		}
	} else {
		switch fin.vv.Kind() {
		case Any:
			if fill.tt.Kind() == Optional {
				fin.vv.Assign(OptionalValue(fill.vv))
			} else {
				fin.vv.Assign(fill.vv)
			}
		}
	}
	return nil
}

// rvSettableZeroValue returns a settable zero value corresponding to rt / tt.
// This isn't trivial since VDL and Go define zero values slightly differently.
// In particular in VDL:
//    TypeObject: AnyType
//    Union:      zero value of the type at index 0
// These are translated into Go as follows, with their standard Go zero values:
//    *Type: nil
//    interface: nil
// Thus we must special-case values of these types.
//
// TODO(toddw): This logic is recursive and complicated because our convTarget
// methods don't take the convTarget as a pointer receiver, so we can't mutate
// the target as we decode.  When we split convTarget into separate valueTarget
// and reflectTarget objects, we should also take the target as a pointer
// receiver.  That'll simplify this logic.
func rvSettableZeroValue(rt reflect.Type, tt *Type) reflect.Value {
	rv := reflect.New(rt).Elem()
	// Easy fastpath; if the type doesn't contain inline typeobject or union, the
	// regular Go zero value is good enough.
	if !tt.ContainsKind(WalkInline, TypeObject, Union) {
		return rv
	}
	// Handle typeobject, which has the zero value of AnyType.
	if rtPtrToType.ConvertibleTo(rt) {
		return reflect.ValueOf(AnyType).Convert(rt)
	}
	// Handle composite types with inline subtypes.
	switch {
	case tt.Kind() == Union:
		if nativeInfoFromNative(rt) != nil {
			return rv
		}
		if rt.Kind() == reflect.Struct {
			// Union struct, which represents a single field.
			rv.Field(0).Set(rvSettableZeroValue(rt.Field(0).Type, tt.Field(0).Type))
			return rv
		}
		// Union interface, which represents one of the fields.  Initialize with the
		// zero value of the type at index 0.
		ri, _, err := deriveReflectInfo(rt)
		if err != nil {
			panic(fmt.Errorf("vdl: invalid union type rt: %v tt: %v err: %v", rt, tt, err))
		}
		rv.Set(rvSettableZeroValue(ri.UnionFields[0].RepType, tt.Field(0).Type))
		return rv
	case rt.Kind() == reflect.Array:
		for ix := 0; ix < rt.Len(); ix++ {
			rv.Index(ix).Set(rvSettableZeroValue(rt.Elem(), tt.Elem()))
		}
		return rv
	case rt.Kind() == reflect.Struct:
		for ix := 0; ix < rt.NumField(); ix++ {
			rtField := rt.Field(ix)
			ttField, index := tt.FieldByName(rtField.Name)
			if index < 0 {
				// Ignore fields that aren't described in tt; e.g. unexported fields.
				continue
			}
			rv.Field(ix).Set(rvSettableZeroValue(rtField.Type, ttField.Type))
		}
		return rv
	}
	panic(fmt.Errorf("vdl: rvSettableZeroValue unhandled rt: %v tt: %v", rt, tt))
}

// makeReflectUnion returns the union concrete struct based on the union
// interface type rt, corresponding to the field that is set in vv.  The point
// of this machinery is to ensure union can always be created, without any type
// registration.
func makeReflectUnion(rt reflect.Type, vv *Value) (reflect.Value, error) {
	// TODO(toddw): Cache the field types for faster access.
	ri, _, err := deriveReflectInfo(rt)
	if err != nil || len(ri.UnionFields) == 0 {
		// If rt isn't a union interface type, it still might be registered, so we
		// can get the reflect type from vv.
		if rt2 := TypeToReflect(vv.Type()); rt2 != nil {
			rt = rt2
			ri, _, err = deriveReflectInfo(rt)
		}
	}
	switch {
	case err != nil:
		return reflect.Value{}, err
	case len(ri.UnionFields) == 0 || vv.Kind() != Union:
		return reflect.Value{}, fmt.Errorf("vdl: makeReflectUnion(%v, %v) must only be called on Union", rt, vv.Type())
	}
	index, vvField := vv.UnionField()
	if index >= len(ri.UnionFields) {
		return reflect.Value{}, fmt.Errorf("vdl: makeReflectUnion(%v, %v) field index %d out of range, len=%d", rt, vv.Type(), index, len(ri.UnionFields))
	}
	// Run our regular conversion from vvField to rvField.  Keep in mind that
	// rvField is the concrete union struct, so we convert into Field(0), which
	// corresponds to the "Value" field.
	rvField := reflect.New(ri.UnionFields[index].RepType).Elem()
	target, err := ReflectTarget(rvField.Field(0))
	if err != nil {
		return reflect.Value{}, err
	}
	if err := FromValue(target, vvField); err != nil {
		return reflect.Value{}, err
	}
	return rvField, nil
}

func removeOptional(tt *Type) *Type {
	if tt.Kind() == Optional {
		tt = tt.Elem()
	}
	return tt
}

// FromNil implements the Target interface method.
func (c convTarget) FromNil(tt *Type) error {
	if !compatible(c.tt, tt) {
		return fmt.Errorf("types %q and %q aren't compatible", c.tt, tt)
	}
	if !tt.CanBeNil() || !c.tt.CanBeNil() {
		return fmt.Errorf("invalid conversion from %v(nil) to %v", tt, c.tt)
	}
	if c.vv == nil {
		// The strategy is to create new pointers down to either a single pointer,
		// or the final interface, and set that to nil.  We create all the pointers
		// to be consistent with our behavior in the non-nil case, where we
		// similarly create all the pointers.  It also makes the tests simpler.
		rv := c.rv
		for rv.Kind() == reflect.Ptr {
			if vv := setZeroVDLValue(rv, tt); vv.IsValid() {
				return nil
			}
			if k := rv.Type().Elem().Kind(); k != reflect.Ptr && k != reflect.Interface {
				break
			}
			// Next elem is a pointer or interface, keep looping.
			if rv.IsNil() {
				rv.Set(reflect.New(rv.Type().Elem()))
			}
			rv = rv.Elem()
		}
		// Now rv.Type is either a single pointer or an interface.  If it is an
		// interface, check to see whether we can create a Go object from tt.
		rt := rv.Type()
		if rv.Kind() == reflect.Interface {
			if rtFromTT := TypeToReflect(tt); rtFromTT != nil {
				rt = rtFromTT
			}
		}
		// Set the zero value of the pointer or interface, which will give us nil of
		// the correct type.
		rv.Set(reflect.Zero(rt))
	} else {
		vvNil := ZeroValue(tt)
		if to, from := c.vv.Type(), vvNil; !to.AssignableFrom(from) {
			return fmt.Errorf("%v not assignable from %v", to, from)
		}
		c.vv.Assign(vvNil)
	}
	return nil
}

// FromBool implements the Target interface method.
func (c convTarget) FromBool(src bool, tt *Type) error {
	fin, fill, err := startConvert(c, tt)
	if err != nil {
		return err
	}
	if err := fill.fromBool(src); err != nil {
		return err
	}
	return finishConvert(fin, fill)
}

// FromUint implements the Target interface method.
func (c convTarget) FromUint(src uint64, tt *Type) error {
	fin, fill, err := startConvert(c, tt)
	if err != nil {
		return err
	}
	if err := fill.fromUint(src); err != nil {
		return err
	}
	return finishConvert(fin, fill)
}

// FromInt implements the Target interface method.
func (c convTarget) FromInt(src int64, tt *Type) error {
	fin, fill, err := startConvert(c, tt)
	if err != nil {
		return err
	}
	if err := fill.fromInt(src); err != nil {
		return err
	}
	return finishConvert(fin, fill)
}

// FromFloat implements the Target interface method.
func (c convTarget) FromFloat(src float64, tt *Type) error {
	fin, fill, err := startConvert(c, tt)
	if err != nil {
		return err
	}
	if err := fill.fromFloat(src); err != nil {
		return err
	}
	return finishConvert(fin, fill)
}

// FromComplex implements the Target interface method.
func (c convTarget) FromComplex(src complex128, tt *Type) error {
	fin, fill, err := startConvert(c, tt)
	if err != nil {
		return err
	}
	if err := fill.fromComplex(src); err != nil {
		return err
	}
	return finishConvert(fin, fill)
}

// FromBytes implements the Target interface method.
func (c convTarget) FromBytes(src []byte, tt *Type) error {
	fin, fill, err := startConvert(c, tt)
	if err != nil {
		return err
	}
	if err := fill.fromBytes(src, tt); err != nil {
		return err
	}
	return finishConvert(fin, fill)
}

// FromString implements the Target interface method.
func (c convTarget) FromString(src string, tt *Type) error {
	fin, fill, err := startConvert(c, tt)
	if err != nil {
		return err
	}
	if err := fill.fromString(src); err != nil {
		return err
	}
	return finishConvert(fin, fill)
}

// FromEnumLabel implements the Target interface method.
func (c convTarget) FromEnumLabel(src string, tt *Type) error {
	return c.FromString(src, tt)
}

// FromTypeObject implements the Target interface method.
func (c convTarget) FromTypeObject(src *Type) error {
	fin, fill, err := startConvert(c, TypeObjectType)
	if err != nil {
		return err
	}
	if err := fill.fromTypeObject(src); err != nil {
		return err
	}
	return finishConvert(fin, fill)
}

func (c convTarget) fromBool(src bool) error {
	if c.vv == nil {
		if c.rv.Kind() == reflect.Bool {
			c.rv.SetBool(src)
			return nil
		}
	} else {
		if c.vv.Kind() == Bool {
			c.vv.AssignBool(src)
			return nil
		}
	}
	return fmt.Errorf("invalid conversion from bool to %v", c.tt)
}

func (c convTarget) fromUint(src uint64) error {
	if c.vv == nil {
		switch kind := c.rv.Kind(); kind {
		case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
			if !overflowUint(src, bitlenR(kind)) {
				c.rv.SetUint(src)
				return nil
			}
		case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
			if isrc, ok := convertUintToInt(src, bitlenR(kind)); ok {
				c.rv.SetInt(isrc)
				return nil
			}
		case reflect.Float32, reflect.Float64:
			if fsrc, ok := convertUintToFloat(src, bitlenR(kind)); ok {
				c.rv.SetFloat(fsrc)
				return nil
			}
		case reflect.Complex64, reflect.Complex128:
			if fsrc, ok := convertUintToFloat(src, bitlenR(kind)); ok {
				c.rv.SetComplex(complex(fsrc, 0))
				return nil
			}
		}
	} else {
		switch kind := c.vv.Kind(); kind {
		case Byte, Uint16, Uint32, Uint64:
			if !overflowUint(src, bitlenV(kind)) {
				c.vv.AssignUint(src)
				return nil
			}
		case Int8, Int16, Int32, Int64:
			if isrc, ok := convertUintToInt(src, bitlenV(kind)); ok {
				c.vv.AssignInt(isrc)
				return nil
			}
		case Float32, Float64:
			if fsrc, ok := convertUintToFloat(src, bitlenV(kind)); ok {
				c.vv.AssignFloat(fsrc)
				return nil
			}
		case Complex64, Complex128:
			if fsrc, ok := convertUintToFloat(src, bitlenV(kind)); ok {
				c.vv.AssignComplex(complex(fsrc, 0))
				return nil
			}
		}
	}
	return fmt.Errorf("invalid conversion from uint(%d) to %v", src, c.tt)
}

func (c convTarget) fromInt(src int64) error {
	if c.vv == nil {
		switch kind := c.rv.Kind(); kind {
		case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
			if usrc, ok := convertIntToUint(src, bitlenR(kind)); ok {
				c.rv.SetUint(usrc)
				return nil
			}
		case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
			if !overflowInt(src, bitlenR(kind)) {
				c.rv.SetInt(src)
				return nil
			}
		case reflect.Float32, reflect.Float64:
			if fsrc, ok := convertIntToFloat(src, bitlenR(kind)); ok {
				c.rv.SetFloat(fsrc)
				return nil
			}
		case reflect.Complex64, reflect.Complex128:
			if fsrc, ok := convertIntToFloat(src, bitlenR(kind)); ok {
				c.rv.SetComplex(complex(fsrc, 0))
				return nil
			}
		}
	} else {
		switch kind := c.vv.Kind(); kind {
		case Byte, Uint16, Uint32, Uint64:
			if usrc, ok := convertIntToUint(src, bitlenV(kind)); ok {
				c.vv.AssignUint(usrc)
				return nil
			}
		case Int8, Int16, Int32, Int64:
			if !overflowInt(src, bitlenV(kind)) {
				c.vv.AssignInt(src)
				return nil
			}
		case Float32, Float64:
			if fsrc, ok := convertIntToFloat(src, bitlenV(kind)); ok {
				c.vv.AssignFloat(fsrc)
				return nil
			}
		case Complex64, Complex128:
			if fsrc, ok := convertIntToFloat(src, bitlenV(kind)); ok {
				c.vv.AssignComplex(complex(fsrc, 0))
				return nil
			}
		}
	}
	return fmt.Errorf("invalid conversion from int(%d) to %v", src, c.tt)
}

func (c convTarget) fromFloat(src float64) error {
	if c.vv == nil {
		switch kind := c.rv.Kind(); kind {
		case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
			if usrc, ok := convertFloatToUint(src, bitlenR(kind)); ok {
				c.rv.SetUint(usrc)
				return nil
			}
		case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
			if isrc, ok := convertFloatToInt(src, bitlenR(kind)); ok {
				c.rv.SetInt(isrc)
				return nil
			}
		case reflect.Float32, reflect.Float64:
			c.rv.SetFloat(convertFloatToFloat(src, bitlenR(kind)))
			return nil
		case reflect.Complex64, reflect.Complex128:
			c.rv.SetComplex(complex(convertFloatToFloat(src, bitlenR(kind)), 0))
			return nil
		}
	} else {
		switch kind := c.vv.Kind(); kind {
		case Byte, Uint16, Uint32, Uint64:
			if usrc, ok := convertFloatToUint(src, bitlenV(kind)); ok {
				c.vv.AssignUint(usrc)
				return nil
			}
		case Int8, Int16, Int32, Int64:
			if isrc, ok := convertFloatToInt(src, bitlenV(kind)); ok {
				c.vv.AssignInt(isrc)
				return nil
			}
		case Float32, Float64:
			c.vv.AssignFloat(convertFloatToFloat(src, bitlenV(kind)))
			return nil
		case Complex64, Complex128:
			c.vv.AssignComplex(complex(convertFloatToFloat(src, bitlenV(kind)), 0))
			return nil
		}
	}
	return fmt.Errorf("invalid conversion from float(%g) to %v", src, c.tt)
}

func (c convTarget) fromComplex(src complex128) error {
	if c.vv == nil {
		switch kind := c.rv.Kind(); kind {
		case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
			if usrc, ok := convertComplexToUint(src, bitlenR(kind)); ok {
				c.rv.SetUint(usrc)
				return nil
			}
		case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
			if isrc, ok := convertComplexToInt(src, bitlenR(kind)); ok {
				c.rv.SetInt(isrc)
				return nil
			}
		case reflect.Float32, reflect.Float64:
			if imag(src) == 0 {
				c.rv.SetFloat(convertFloatToFloat(real(src), bitlenR(kind)))
				return nil
			}
		case reflect.Complex64, reflect.Complex128:
			re := convertFloatToFloat(real(src), bitlenR(kind))
			im := convertFloatToFloat(imag(src), bitlenR(kind))
			c.rv.SetComplex(complex(re, im))
			return nil
		}
	} else {
		switch kind := c.vv.Kind(); kind {
		case Byte, Uint16, Uint32, Uint64:
			if usrc, ok := convertComplexToUint(src, bitlenV(kind)); ok {
				c.vv.AssignUint(usrc)
				return nil
			}
		case Int8, Int16, Int32, Int64:
			if isrc, ok := convertComplexToInt(src, bitlenV(kind)); ok {
				c.vv.AssignInt(isrc)
				return nil
			}
		case Float32, Float64:
			if imag(src) == 0 {
				c.vv.AssignFloat(convertFloatToFloat(real(src), bitlenV(kind)))
				return nil
			}
		case Complex64, Complex128:
			re := convertFloatToFloat(real(src), bitlenV(kind))
			im := convertFloatToFloat(imag(src), bitlenV(kind))
			c.vv.AssignComplex(complex(re, im))
			return nil
		}
	}
	return fmt.Errorf("invalid conversion from complex(%g) to %v", src, c.tt)
}

func (c convTarget) fromBytes(src []byte, tt *Type) error {
	if c.tt.IsBytes() {
		return c.fromBytesToBytes(src)
	}
	elemType := tt.Elem()
	for i, b := range src {
		elem, err := c.startElem(i)
		if err != nil {
			return err
		}
		if err := elem.FromUint(uint64(b), elemType); err != nil {
			return err
		}
		if err := c.finishElem(elem); err != nil {
			return err
		}
	}
	return nil
}

func (c convTarget) fromBytesToBytes(src []byte) error {
	if c.vv == nil {
		switch {
		case c.rv.Kind() == reflect.Array:
			if c.rv.Type().Elem() == rtByte && c.rv.Len() == len(src) {
				reflect.Copy(c.rv, reflect.ValueOf(src))
				return nil
			}
		case c.rv.Kind() == reflect.Slice:
			if c.rv.Type().Elem() == rtByte {
				if len(src) == 0 {
					c.rv.SetBytes(nil)
				} else {
					cp := make([]byte, len(src))
					copy(cp, src)
					c.rv.SetBytes(cp)
				}
				return nil
			}
		}
	} else {
		switch c.vv.Kind() {
		case Array:
			if c.vv.Type().Len() == len(src) {
				c.vv.AssignBytes(src)
				return nil
			}
		case List:
			c.vv.AssignBytes(src)
			return nil
		}
	}
	return fmt.Errorf("invalid conversion from bytes to %v", c.tt)
}

// settable exists to avoid a call to reflect.Call() to invoke Set()
// which results in an allocation
type settable interface {
	Set(string) error
}

func (c convTarget) fromString(src string) error {
	if c.vv == nil {
		tt := removeOptional(c.tt)
		switch {
		case tt.Kind() == Enum:
			// Handle special-case enum first, by calling the Assign method.  Note
			// that TypeFromReflect has already validated the Assign method, so we
			// can call without error checking.
			if c.rv.CanAddr() {
				err := c.rv.Addr().Interface().(settable).Set(src)
				if err != nil {
					return err
				}
				return nil
			}
		case c.rv.Kind() == reflect.String:
			c.rv.SetString(src) // TODO(toddw): check utf8
			return nil
		}
	} else {
		switch c.vv.Kind() {
		case String:
			c.vv.AssignString(src) // TODO(toddw): check utf8
			return nil
		case Enum:
			if index := c.vv.Type().EnumIndex(src); index >= 0 {
				c.vv.AssignEnumIndex(index)
				return nil
			}
		}
	}
	return fmt.Errorf("invalid conversion from string or enum to %v", c.tt)
}

func (c convTarget) fromTypeObject(src *Type) error {
	if c.vv == nil {
		if rtPtrToType.ConvertibleTo(c.rv.Type()) {
			c.rv.Set(reflect.ValueOf(src).Convert(c.rv.Type()))
			return nil
		}
	} else {
		if c.vv.Kind() == TypeObject {
			c.vv.AssignTypeObject(src)
			return nil
		}
	}
	return fmt.Errorf("invalid conversion from typeobject to %v", c.tt)
}

// StartList implements the Target interface method.
func (c convTarget) StartList(tt *Type, len int) (ListTarget, error) {
	// TODO(bprosnitz) Re-think allocation strategy and possibly use len (currently unused).
	fin, fill, err := startConvert(c, tt)
	return compConvTarget{fin, fill}, err
}

// FinishList implements the Target interface method.
func (c convTarget) FinishList(x ListTarget) error {
	cc := x.(compConvTarget)
	return finishConvert(cc.fin, cc.fill)
}

// StartSet implements the Target interface method.
func (c convTarget) StartSet(tt *Type, len int) (SetTarget, error) {
	fin, fill, err := startConvert(c, tt)
	return compConvTarget{fin, fill}, err
}

// FinishSet implements the Target interface method.
func (c convTarget) FinishSet(x SetTarget) error {
	cc := x.(compConvTarget)
	return finishConvert(cc.fin, cc.fill)
}

// StartMap implements the Target interface method.
func (c convTarget) StartMap(tt *Type, len int) (MapTarget, error) {
	fin, fill, err := startConvert(c, tt)
	return compConvTarget{fin, fill}, err
}

// FinishMap implements the Target interface method.
func (c convTarget) FinishMap(x MapTarget) error {
	cc := x.(compConvTarget)
	return finishConvert(cc.fin, cc.fill)
}

// StartFields implements the Target interface method.
func (c convTarget) StartFields(tt *Type) (FieldsTarget, error) {
	fin, fill, err := startConvert(c, tt)
	return compConvTarget{fin, fill}, err
}

// FinishFields implements the Target interface method.
func (c convTarget) FinishFields(x FieldsTarget) error {
	cc := x.(compConvTarget)
	return finishConvert(cc.fin, cc.fill)
}

// compConvTarget represents the state and logic for composite value conversion.
type compConvTarget struct {
	fin, fill convTarget // fields returned by startConvert.
}

// StartElem implements the ListTarget interface method.
func (cc compConvTarget) StartElem(index int) (elem Target, _ error) {
	return cc.fill.startElem(index)
}

// FinishElem implements the ListTarget interface method.
func (cc compConvTarget) FinishElem(elem Target) error {
	return cc.fill.finishElem(elem.(convTarget))
}

// StartKey implements the SetTarget and MapTarget interface method.
func (cc compConvTarget) StartKey() (key Target, _ error) {
	return cc.fill.startKey()
}

// FinishKeyStartField implements the MapTarget interface method.
func (cc compConvTarget) FinishKeyStartField(key Target) (field Target, _ error) {
	return cc.fill.finishKeyStartField(key.(convTarget))
}

// FinishField implements the MapTarget and FieldsTarget interface method.
func (cc compConvTarget) FinishField(key, field Target) error {
	return cc.fill.finishField(key.(convTarget), field.(convTarget))
}

// StartField implements the FieldsTarget interface method.
func (cc compConvTarget) StartField(name string) (key, field Target, _ error) {
	var err error
	if key, err = cc.StartKey(); err != nil {
		return nil, nil, err
	}
	if err = key.FromString(name, StringType); err != nil {
		return nil, nil, err
	}
	if field, err = cc.FinishKeyStartField(key); err != nil {
		return nil, nil, err
	}
	return
}

// FinishKey implements the SetTarget interface method.
func (cc compConvTarget) FinishKey(key Target) error {
	field, err := cc.FinishKeyStartField(key)
	if err != nil {
		return err
	}
	return cc.FinishField(key, field)
}

func (c convTarget) startElem(index int) (convTarget, error) {
	if c.vv == nil {
		tt := removeOptional(c.tt)
		switch c.rv.Kind() {
		case reflect.Array:
			if index >= c.rv.Len() {
				return convTarget{}, errArrayIndex
			}
			return reflectConv(c.rv.Index(index), tt.Elem())
		case reflect.Slice:
			newlen := index + 1
			if newlen < c.rv.Len() {
				newlen = c.rv.Len()
			}
			if newlen > c.rv.Cap() {
				rvNew := reflect.MakeSlice(c.rv.Type(), newlen, newlen*2)
				reflect.Copy(rvNew, c.rv)
				c.rv.Set(rvNew)
			} else {
				c.rv.SetLen(newlen)
			}
			return reflectConv(c.rv.Index(index), tt.Elem())
		}
	} else {
		switch c.vv.Kind() {
		case Array:
			if index >= c.vv.Len() {
				return convTarget{}, errArrayIndex
			}
			return valueConv(c.vv.Index(index)), nil
		case List:
			newlen := index + 1
			if newlen < c.vv.Len() {
				newlen = c.vv.Len()
			}
			return valueConv(c.vv.AssignLen(newlen).Index(index)), nil
		}
	}
	return convTarget{}, fmt.Errorf("type %v doesn't support StartElem", c.tt)
}

func (c convTarget) finishElem(elem convTarget) error {
	if c.vv == nil {
		switch c.rv.Kind() {
		case reflect.Array, reflect.Slice:
			return nil
		}
	} else {
		switch c.vv.Kind() {
		case Array, List:
			return nil
		}
	}
	return fmt.Errorf("type %v doesn't support FinishElem", c.tt)
}

func (c convTarget) startKey() (convTarget, error) {
	if c.vv == nil {
		tt := removeOptional(c.tt)
		switch c.rv.Kind() {
		case reflect.Map:
			return reflectConv(rvSettableZeroValue(c.rv.Type().Key(), tt.Key()), tt.Key())
		case reflect.Struct:
			// The key for struct is the field name, which is a string.
			return reflectConv(reflect.New(rtString).Elem(), StringType)
		}
	} else {
		switch c.vv.Kind() {
		case Set, Map:
			return valueConv(ZeroValue(c.vv.Type().Key())), nil
		case Struct, Union:
			// The key for struct and union is the field name, which is a string.
			return valueConv(ZeroValue(StringType)), nil
		}
	}
	return convTarget{}, fmt.Errorf("type %v doesn't support StartKey", c.tt)
}

func (c convTarget) finishKeyStartField(key convTarget) (convTarget, error) {
	// There are various special-cases regarding bool values below.  These are to
	// handle different representations of sets; the following types are all
	// convertible to each other:
	//   set[string], map[string]bool, struct{X, Y, Z bool}
	//
	// To deal with these cases in a uniform manner, we return a bool field for
	// set[string], and initialize bool fields to true.
	if c.vv == nil {
		tt := removeOptional(c.tt)
		switch c.rv.Kind() {
		case reflect.Map:
			var ttField *Type
			var rvField reflect.Value
			switch rtField := c.rv.Type().Elem(); {
			case tt.Kind() == Set:
				// The map actually represents a set
				ttField = BoolType
				rvField = reflect.New(rtBool).Elem()
				rvField.SetBool(true)
			case rtField.Kind() == reflect.Bool:
				ttField = tt.Elem()
				rvField = reflect.New(rtField).Elem()
				rvField.SetBool(true)
			default:
				// TODO(toddw): This doesn't work correctly for map[_]any.
				ttField = tt.Elem()
				rvField = rvSettableZeroValue(rtField, ttField)
			}
			return reflectConv(rvField, ttField)
		case reflect.Struct:
			if tt.Kind() == Union {
				// Special-case: the fill target is a union concrete field struct.  This
				// means that we should only return a field if the field name matches.
				name := c.rv.Interface().(nameable).Name()
				if name != key.rv.String() {
					return convTarget{}, ErrFieldNoExist
				}
				ttField, _ := tt.FieldByName(name)
				return reflectConv(c.rv.FieldByName("Value"), ttField.Type)
			}
			rvField := c.rv.FieldByName(key.rv.String())
			ttField, index := tt.FieldByName(key.rv.String())
			if !rvField.IsValid() || index < 0 {
				// TODO(toddw): Add a way to track extra and missing fields.
				return convTarget{}, ErrFieldNoExist
			}
			if rvField.Kind() == reflect.Bool {
				rvField.SetBool(true)
			}
			return reflectConv(rvField, ttField.Type)
		}
	} else {
		switch c.vv.Kind() {
		case Set:
			return valueConv(BoolValue(true)), nil
		case Map:
			vvField := ZeroValue(c.vv.Type().Elem())
			if vvField.Kind() == Bool {
				vvField.AssignBool(true)
			}
			return valueConv(vvField), nil
		case Struct:
			_, index := c.vv.Type().FieldByName(key.vv.RawString())
			if index < 0 {
				// TODO(toddw): Add a way to track extra and missing fields.
				return convTarget{}, ErrFieldNoExist
			}
			vvField := c.vv.StructField(index)
			if vvField.Kind() == Bool {
				vvField.AssignBool(true)
			}
			return valueConv(vvField), nil
		case Union:
			f, index := c.vv.Type().FieldByName(key.vv.RawString())
			if index < 0 {
				return convTarget{}, ErrFieldNoExist
			}
			vvField := ZeroValue(f.Type)
			return valueConv(vvField), nil
		}
	}
	return convTarget{}, fmt.Errorf("type %v doesn't support FinishKeyStartField", c.tt)
}

func (c convTarget) finishField(key, field convTarget) error {
	// The special-case handling of bool fields matches the special-cases in
	// FinishKeyStartField.
	if c.vv == nil {
		tt := removeOptional(c.tt)
		switch c.rv.Kind() {
		case reflect.Map:
			rvField := field.rv
			if tt.Kind() == Set {
				// The map actually represents a set
				if !field.rv.Bool() {
					return fmt.Errorf("%v can only be converted from true fields", tt)
				}
				rvField = reflect.Zero(c.rv.Type().Elem())
			}
			if c.rv.IsNil() {
				c.rv.Set(reflect.MakeMap(c.rv.Type()))
			}
			c.rv.SetMapIndex(key.rv, rvField)
			return nil
		case reflect.Struct:
			return nil
		}
	} else {
		switch c.vv.Kind() {
		case Set:
			if !field.vv.Bool() {
				return fmt.Errorf("%v can only be converted from true fields", c.vv.Type())
			}
			c.vv.AssignSetKey(key.vv)
			return nil
		case Map:
			c.vv.AssignMapIndex(key.vv, field.vv)
			return nil
		case Struct:
			return nil
		case Union:
			_, index := c.vv.Type().FieldByName(key.vv.RawString())
			c.vv.AssignUnionField(index, field.vv)
			return nil
		}
	}
	return fmt.Errorf("type %v doesn't support FinishField", c.tt)
}
