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

// +build fuchsia

package fidl

import (
	"errors"
	"math"
	"reflect"
	"strconv"
	"strings"
	"sync"
	"syscall/zx"
	"unicode/utf8"
)

type strictness bool

const (
	isFlexible strictness = false
	isStrict   strictness = true
)

// MustCreateMarshaler is like CreateMarshaler but panics if the sample struct
// cannot be used to create a marshaler. It simplifies safe initialization of
// global variables holding marshalers.
func MustCreateMarshaler(sample interface{}) Marshaler {
	m, err := CreateMarshaler(sample)
	if err != nil {
		panic(err)
	}
	return m
}

// CreateMarshaler creates a marshaler from a sample struct.
func CreateMarshaler(sample interface{}) (Marshaler, error) {
	typ := reflect.TypeOf(sample)
	if typ.Kind() == reflect.Ptr {
		typ = typ.Elem()
	}
	if typ.Kind() == reflect.Struct {
		return createMarshaler(typ)
	}
	return nil, errors.New("unable to create marshaler for " + nicefmt(typ))
}

// CreateMarshaler creates a lazy marshaler from a sample struct. This lazy
// marshaler initializes its actual delegate marshaler on first use, rather
// than on creation. As a result, there is no validation on creation, and
// instead the lazy marshaler will panic on first use if a marshaler
// cannot be created of the sample provided.
func CreateLazyMarshaler(sample interface{}) Marshaler {
	return &lazyMarshaler{
		sample: sample,
	}
}

type lazyMarshaler struct {
	once     sync.Once
	sample   interface{}
	delegate Marshaler
}

// Assert that lazyMarshaler implements the Marshaler interface.
var _ Marshaler = &lazyMarshaler{}

func (m *lazyMarshaler) init() {
	m.delegate = MustCreateMarshaler(m.sample)
}

func (m *lazyMarshaler) getMarshalSize(ctx MarshalerContext) int {
	m.once.Do(m.init)
	return m.delegate.getMarshalSize(ctx)
}

func (m *lazyMarshaler) getUnmarshalSize(ctx MarshalerContext) int {
	m.once.Do(m.init)
	return m.delegate.getUnmarshalSize(ctx)
}

func (m *lazyMarshaler) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	m.once.Do(m.init)
	return m.delegate.marshal(ctx, v, out)
}

func (m *lazyMarshaler) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	m.once.Do(m.init)
	return m.delegate.unmarshal(ctx, in, v)
}

// Marshal marshals (or encodes) a message into the data and handles slices.
func Marshal(message Message, data []byte, handles []zx.Handle) (int, int, error) {
	return MarshalWithContext(newCtx(), message, data, handles)
}

// Marshal marshals (or encodes) a message into the data and handles slices.
func MarshalWithContext(ctx MarshalerContext, message Message, data []byte, handles []zx.Handle) (int, int, error) {
	// By construction, we know that message is a pointer to a struct since
	// we only generate pointer receiver methods for top-level messages.
	// Should one implement the interface differently, and call into this
	// code, it would fail in an obsure way withing relfection. Just don't do
	// that.
	var (
		v = reflect.ValueOf(message).Elem()
		m = message.Marshaler()
	)

	// Now, let's get the value of s, marshal the header into a starting
	// buffer, and then marshal the rest of the payload in s.
	out := &encoder{buffer: data[:0], handles: handles[:0]}
	out.head = out.newObject(m.getMarshalSize(ctx))
	if err := m.marshal(ctx, v, out); err != nil {
		return 0, 0, err
	}
	return len(out.buffer), len(out.handles), nil
}

// Unmarshal unmarshals (or decodes) into message using the data and handles
// slices.
func Unmarshal(data []byte, handles []zx.Handle, message Message) (int, int, error) {
	return UnmarshalWithContext(newCtx(), data, handles, message)
}

func UnmarshalWithContext(ctx MarshalerContext, data []byte, handles []zx.Handle, message Message) (int, int, error) {
	// By construction, we know that message is a pointer to a struct since
	// we only generate pointer receiver methods for top-level messages.
	// Should one implement the interface differently, and call into this
	// code, it would fail in an obsure way withing relfection. Just don't do
	// that.
	var (
		v = reflect.ValueOf(message).Elem()
		m = message.Marshaler()
	)

	// Get the payload's value and unmarshal it.
	nextObject := align(m.getUnmarshalSize(ctx), 8)
	in := &decoder{
		buffer:     data,
		handles:    handles,
		nextObject: nextObject,
	}
	if err := m.unmarshal(ctx, in, v); err != nil {
		return 0, 0, err
	}
	return in.nextObject, len(handles) - len(in.handles), nil
}

const tagKey = "fidl"
const tagSizeV1 = "fidl_size_v1"
const tagAlignmentV1 = "fidl_alignment_v1"
const tagOffsetV1 = "fidl_offset_v1"

type tagKind int

const (
	_                 = iota
	structTag tagKind = iota
	unionTag
	xunionTag
	strictXunionTag
	tableTag
	boundsTag
)

type bounds []int

func (b bounds) pop() (int, []int) {
	if len(b) == 0 {
		return math.MaxInt32, nil
	}
	return b[0], b[1:]
}

func nicefmt(typ reflect.Type) string {
	if len(typ.Name()) == 0 {
		return typ.Kind().String()
	} else {
		return typ.Name() + " (" + typ.Kind().String() + ")"
	}
}

func createMarshaler(typ reflect.Type) (Marshaler, error) {
	// field 0 holds the tag
	tagField := typ.Field(0)
	marshalerKind, marshalerBounds := readTag(tagField)
	var (
		kind         = marshalerKind
		sizeOld      = marshalerBounds[0]
		alignmentOld = marshalerBounds[1]
		fields       []mField
		ordinals     []int
		offsetsOld   []int
		offsetsV1    []int
	)
	// field 1 and up are the actual data fields
	// - structs, unions, and xunions have fields one after the other;
	// - tables have a field, followed by a bool presence indicator, etc.
	for index := 1; index < typ.NumField(); index++ {
		field := typ.Field(index)
		_, fieldBounds := readTag(field)
		switch kind {
		case structTag:
			offsetOld, actualBounds := fieldBounds.pop()
			offsetsOld = append(offsetsOld, offsetOld)
			offsetV1, err := readOffsetV1(field)
			if err != nil {
				return nil, err
			}
			offsetsV1 = append(offsetsV1, offsetV1)
			fieldBounds = actualBounds
		case unionTag, xunionTag, strictXunionTag, tableTag:
			ordinal, actualBounds := fieldBounds.pop()
			ordinals = append(ordinals, ordinal)
			fieldBounds = actualBounds
		default:
		}
		fieldMarshaler, err := createMarshalerForField(field.Type, fieldBounds)
		if err != nil {
			return nil, err
		}
		fields = append(fields, mField{fieldMarshaler, index})
		if kind == tableTag {
			if typ.Field(index+1).Type.Kind() != reflect.Bool {
				return nil, errors.New("incorrect presence field on " + nicefmt(typ))
			}
			index++ // i.e. skip presence field.
		}
	}

	sizeV1, err := readIntTag(tagField, tagSizeV1)
	if err != nil {
		return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
	}
	alignmentV1, err := readIntTag(tagField, tagAlignmentV1)
	if err != nil {
		return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
	}

	switch kind {
	case structTag:
		if len(fields) == 0 {
			return mEmptyStruct{}, nil
		}

		var structFields []mFieldWithOffset
		for i := 0; i < len(fields); i++ {
			structFields = append(structFields, mFieldWithOffset{
				mField:    fields[i],
				offsetOld: offsetsOld[i],
				offsetV1:  offsetsV1[i],
			})
		}
		return mStruct{
			fields:       structFields,
			sizeOld:      sizeOld,
			alignmentOld: alignmentOld,
			sizeV1:       sizeV1,
			alignmentV1:  alignmentV1,
		}, nil
	case unionTag:
		m := mUnion{
			fields:       fields,
			ordinals:     ordinals,
			sizeOld:      sizeOld,
			alignmentOld: alignmentOld,
			sizeV1:       sizeV1,
			alignmentV1:  alignmentV1,
		}
		m.mXUnion = mUnionToMXUnion(m)
		return m, nil
	case xunionTag, strictXunionTag:
		strictness := strictness(kind == strictXunionTag)

		ordinalToFields := make(map[int]mField)
		for i := 0; i < len(fields); i++ {
			ordinalToFields[ordinals[i]] = fields[i]
		}
		return mXUnion{
			fields:       ordinalToFields,
			sizeOld:      sizeOld,
			alignmentOld: alignmentOld,
			sizeV1:       sizeV1,
			alignmentV1:  alignmentV1,
			strictness:   strictness,
		}, nil
	case tableTag:
		return mTable{
			fields:       fields,
			sizeOld:      sizeOld,
			alignmentOld: alignmentOld,
			sizeV1:       sizeV1,
			alignmentV1:  alignmentV1,
			ordinals:     ordinals,
		}, nil
	default:
		return nil, errors.New("missing kind marker on " + nicefmt(typ))
	}
}

func mUnionToMXUnion(m mUnion) mXUnion {
	ordinalToFields := make(map[int]mField)
	for i := 0; i < len(m.fields); i++ {
		ordinalToFields[m.ordinals[i]] = m.fields[i]
	}
	return mXUnion{
		fields:        ordinalToFields,
		unionToXunion: true,
		sizeV1:        m.sizeV1,
		alignmentV1:   m.alignmentV1,
		strictness:    true,
	}
}

func readIntTag(field reflect.StructField, tagKey string) (int, error) {
	content, ok := field.Tag.Lookup(tagKey)
	if !ok {
		return 0, errors.New("tag " + tagKey + " not found")
	}
	res, err := strconv.ParseInt(content, 0, 64)
	if err != nil {
		return 0, errors.New("error parsing int body from tag " + tagKey + " " + err.Error())
	}
	return int(res), nil
}

// readTag reads a fidl tag which can be one of
//
//     s,size,alignment   -- marking a struct, with its size, and alignment
//     u,size,alignment   -- marking a union, with its size, and alignment
//     x,size,alignment   -- marking a flexible xunion, with its size, and alignment
//     x!,size,alignment  -- marking a strict xunion, with its size, and alignment
//     t,size,alignment   -- marking a table, with its size, and alignment
//     num1, num2, ...    -- recording bounds of the types present on the field
//     ! num1, num2, ...  -- strict, recording bounds of the types present on the field
//
// When handles or interfaces are present, the bounds indicate nullability,
// with 0 indicating false (not nullable), and any other value true (nullable).
func readTag(field reflect.StructField) (tagKind, bounds) {
	content, ok := field.Tag.Lookup(tagKey)
	if !ok {
		return boundsTag, nil
	}
	elems := strings.Split(content, ",")

	switch elems[0] {
	case "s":
		return structTag, toBounds(elems[1:])
	case "u":
		return unionTag, toBounds(elems[1:])
	case "x":
		return xunionTag, toBounds(elems[1:])
	case "x!":
		return strictXunionTag, toBounds(elems[1:])
	case "t":
		return tableTag, toBounds(elems[1:])
	default:
		return boundsTag, toBounds(elems)
	}
}

func readOffsetV1(field reflect.StructField) (int, error) {
	val, ok := field.Tag.Lookup(tagOffsetV1)
	if !ok {
		return 0, errors.New(tagOffsetV1 + " not found on field " + field.Name)
	}
	offset, err := strconv.ParseInt(val, 0, 64)
	if err != nil {
		return 0, err
	}
	return int(offset), nil
}

func toBounds(elems []string) bounds {
	var nums []int
	for _, elem := range elems {
		var (
			num = math.MaxInt32
			err error
		)
		if len(elem) != 0 {
			num, err = strconv.Atoi(elem)
			if err != nil {
				panic(elem + ": " + err.Error())
			}
		}
		nums = append(nums, num)
	}
	return bounds(nums)
}

func createMarshalerForField(typ reflect.Type, bounds bounds) (Marshaler, error) {
	if isHandleType(typ) {
		// TODO(pascallouis): Check that handles' subtype conform?
		nullable, _ := bounds.pop()
		return mHandle(nullable != 0), nil
	}

	if isInterfaceType(typ) || isInterfaceRequestType(typ) {
		nullable, _ := bounds.pop()
		return mInterface(nullable != 0), nil
	}

	switch typ.Kind() {
	case reflect.Bool:
		return mBool{}, nil
	case reflect.Int8:
		return mInt(1), nil
	case reflect.Int16:
		return mInt(2), nil
	case reflect.Int32:
		return mInt(4), nil
	case reflect.Int64:
		return mInt(8), nil
	case reflect.Uint8:
		return mUint(1), nil
	case reflect.Uint16:
		return mUint(2), nil
	case reflect.Uint32:
		return mUint(4), nil
	case reflect.Uint64:
		return mUint(8), nil
	case reflect.Float32:
		return mFloat32{}, nil
	case reflect.Float64:
		return mFloat64{}, nil
	case reflect.String:
		maxSize, _ := bounds.pop()
		return mString(maxSize), nil
	case reflect.Array:
		elemMarshaler, err := createMarshalerForField(typ.Elem(), bounds)
		if err != nil {
			return nil, err
		}
		return mArray{
			Marshaler: elemMarshaler,
			size:      typ.Len(),
		}, nil
	case reflect.Slice:
		maxSize, remainder := bounds.pop()
		elemTyp := typ.Elem()
		elemMarshaler, err := createMarshalerForField(elemTyp, remainder)
		if err != nil {
			return nil, err
		}
		return mVector{
			Marshaler:     elemMarshaler,
			maxSize:       maxSize,
			sliceTyp:      reflect.SliceOf(elemTyp),
			isVectorUint8: elemTyp.Kind() == reflect.Uint8,
		}, nil
	case reflect.Struct:
		return createMarshaler(typ)
	case reflect.Ptr:
		return createOptMarshalerForField(typ.Elem(), bounds)
	default:
		return nil, errors.New("unable to create field marshaler for " + nicefmt(typ))
	}
}

func createOptMarshalerForField(typ reflect.Type, bounds bounds) (Marshaler, error) {
	m, err := createMarshalerForField(typ, bounds)
	if err != nil {
		return nil, err
	}
	switch m := m.(type) {
	case mString:
		return mOptString(m), nil
	case mVector:
		return mOptVector(m), nil
	case mEmptyStruct:
		return mPointer{
			Marshaler: m,
			elemTyp:   typ,
		}, nil
	case mStruct:
		return mPointer{
			Marshaler: m,
			elemTyp:   typ,
		}, nil
	case mUnion:
		return mOptUnion{
			mPointer: mPointer{
				Marshaler: m,
				elemTyp:   typ,
			},
			mOptXUnion: mOptXUnion{
				mXUnion: m.mXUnion,
				typ:     typ,
			},
		}, nil
	case mXUnion:
		return mOptXUnion{
			mXUnion: m,
			typ:     typ,
		}, nil
	default:
		return nil, errors.New("unable to create optional field marshaler for " + nicefmt(typ))
	}
}

// Message is implemented by any value that represents a FIDL message.
type Message interface {
	Marshaler() Marshaler
}

type MarshalerContext struct {
	DecodeUnionsFromXUnionBytes bool
	EncodeUnionsAsXUnionBytes   bool
}

type Marshaler interface {
	// Marshal and unmarshal sizes can be different because they can be context dependent.
	// e.g. it is possible to write a new format but still read the old format
	getMarshalSize(ctx MarshalerContext) int
	getUnmarshalSize(ctx MarshalerContext) int
	marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error
	unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error
}

// Assert various encoders implement the Marshaler interface.
var _ = []Marshaler{
	mStruct{},
	mEmptyStruct{},
	mUnion{},
	mXUnion{},
	mOptXUnion{},
	mTable{},
	mPointer{},
	mOptUnion{},
	mArray{},
	mVector{},
	mOptVector{},
	mBool{},
	mInt(0),
	mUint(0),
	mFloat32{},
	mFloat64{},
	mString(0),
	mOptString(0),
}

type mField struct {
	Marshaler
	index int
}

type mFieldWithOffset struct {
	mField
	offsetOld int
	offsetV1  int
}

func (m mFieldWithOffset) getMarshalOffset(ctx MarshalerContext) int {
	if ctx.EncodeUnionsAsXUnionBytes {
		return m.offsetV1
	}
	return m.offsetOld
}

func (m mFieldWithOffset) getUnmarshalOffset(ctx MarshalerContext) int {
	if ctx.DecodeUnionsFromXUnionBytes {
		return m.offsetV1
	}
	return m.offsetOld
}

type mStruct struct {
	fields                []mFieldWithOffset
	sizeOld, alignmentOld int
	sizeV1, alignmentV1   int
}

func (m mStruct) getMarshalSize(ctx MarshalerContext) int {
	if ctx.EncodeUnionsAsXUnionBytes {
		return m.sizeV1
	}
	return m.sizeOld
}

func (m mStruct) getUnmarshalSize(ctx MarshalerContext) int {
	if ctx.DecodeUnionsFromXUnionBytes {
		return m.sizeV1
	}
	return m.sizeOld
}

func (m mStruct) getMarshalAlignment(ctx MarshalerContext) int {
	if ctx.EncodeUnionsAsXUnionBytes {
		return m.alignmentV1
	}
	return m.alignmentOld
}

func (m mStruct) getUnmarshalAlignment(ctx MarshalerContext) int {
	if ctx.DecodeUnionsFromXUnionBytes {
		return m.alignmentV1
	}
	return m.alignmentOld
}

func (m mStruct) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	structStart := align(out.head, m.getMarshalAlignment(ctx))
	for _, field := range m.fields {
		out.head = structStart + field.getMarshalOffset(ctx)
		if err := field.Marshaler.marshal(ctx, v.Field(field.index), out); err != nil {
			return err
		}
	}
	out.head = align(out.head, m.getMarshalAlignment(ctx))
	return nil
}

func (m mStruct) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	structStart := align(in.head, m.getUnmarshalAlignment(ctx))
	for _, field := range m.fields {
		in.head = structStart + field.getUnmarshalOffset(ctx)
		if err := field.Marshaler.unmarshal(ctx, in, v.Field(field.index)); err != nil {
			return err
		}
	}
	in.head = align(in.head, m.getUnmarshalAlignment(ctx))
	return nil
}

type mEmptyStruct struct{}

func (_ mEmptyStruct) getMarshalSize(ctx MarshalerContext) int {
	return 1
}

func (_ mEmptyStruct) getUnmarshalSize(ctx MarshalerContext) int {
	return 1
}

func (_ mEmptyStruct) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	out.writeUint(0, 1)
	return nil
}

func (_ mEmptyStruct) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	zero, err := in.readUint(1)
	if err != nil {
		return err
	} else if zero != 0 {
		return newValueError(ErrInvalidEmptyStruct, zero)
	}

	return nil
}

type mUnion struct {
	fields                []mField
	ordinals              []int
	sizeOld, alignmentOld int
	sizeV1, alignmentV1   int

	mXUnion
}

func (m mUnion) getMarshalSize(ctx MarshalerContext) int {
	if ctx.EncodeUnionsAsXUnionBytes {
		return m.sizeV1
	}
	return m.sizeOld
}

func (m mUnion) getUnmarshalSize(ctx MarshalerContext) int {
	if ctx.DecodeUnionsFromXUnionBytes {
		return m.sizeV1
	}
	return m.sizeOld
}

func (m mUnion) getMarshalAlignment(ctx MarshalerContext) int {
	if ctx.EncodeUnionsAsXUnionBytes {
		return m.alignmentV1
	}
	return m.alignmentOld
}

func (m mUnion) getUnmarshalAlignment(ctx MarshalerContext) int {
	if ctx.DecodeUnionsFromXUnionBytes {
		return m.alignmentV1
	}
	return m.alignmentOld
}

func (m mUnion) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	if ctx.EncodeUnionsAsXUnionBytes {
		return m.mXUnion.marshal(ctx, v, out)
	}

	// Kind.
	kind := int(v.Field(0).Uint()) - 1
	if kind < 0 || len(m.fields) <= kind {
		return newValueError(ErrInvalidUnionTag, kind)
	}

	// Save the head for proper padding.
	head := out.head
	out.writeUint(uint64(kind), 4)

	// Re-align to the union's alignment before writing its field.
	out.head = align(out.head, m.getMarshalAlignment(ctx))

	// Marshal field.
	if err := m.fields[kind].Marshaler.marshal(ctx, v.Field(kind+1), out); err != nil {
		return err
	}

	// Re-position head.
	out.head = head + m.getMarshalSize(ctx)

	return nil
}

func (m mUnion) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	if ctx.DecodeUnionsFromXUnionBytes {
		return m.mXUnion.unmarshal(ctx, in, v)
	}

	// Save the head for proper padding.
	head := in.head

	// Kind.
	kind, err := in.readUint(4)
	if err != nil {
		return err
	}
	if uint64(len(m.fields)) <= kind {
		return newValueError(ErrInvalidUnionTag, kind)
	}
	v.Field(0).SetUint(kind + 1)

	// Re-align to the union's alignment before writing its field.
	in.head = align(in.head, m.getUnmarshalAlignment(ctx))

	// Unmarshal field.
	ikind := int(kind)
	if err := m.fields[ikind].Marshaler.unmarshal(ctx, in, v.Field(ikind+1)); err != nil {
		return err
	}

	// Re-position head.
	in.head = head + m.getUnmarshalSize(ctx)

	return nil
}

type mXUnion struct {
	fields                map[int]mField
	unionToXunion         bool
	sizeOld, alignmentOld int
	sizeV1, alignmentV1   int
	strictness
}

func (m mXUnion) getMarshalSize(ctx MarshalerContext) int {
	if ctx.EncodeUnionsAsXUnionBytes {
		return m.sizeV1
	}
	return m.sizeOld
}

func (m mXUnion) getUnmarshalSize(ctx MarshalerContext) int {
	if ctx.DecodeUnionsFromXUnionBytes {
		return m.sizeV1
	}
	return m.sizeOld
}

func (m mXUnion) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	// Ordinal.
	ordinal := int(v.Field(0).Uint())
	field, ok := m.fields[ordinal]
	if !ok {
		return newValueError(ErrInvalidXUnionTag, ordinal)
	}
	out.writeUint(uint64(ordinal), 8)

	// Field.
	if err := marshalEnvelopePresent(ctx, field, v.Field(field.index), out); err != nil {
		return err
	}

	return nil
}

func (m mXUnion) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	return m.unmarshalWithOptSpecified(ctx, in, v, nil)
}

func (m mXUnion) unmarshalWithOptSpecified(ctx MarshalerContext, in *decoder, v reflect.Value, typ reflect.Type) error {
	// Can this envelope be optional? If it can, the type must be provided
	// in order to reflectively create a pointer container.
	optAllowed := typ != nil

	ordinal, err := in.readUint(4)
	if err != nil {
		return err
	}

	padding, err := in.readUint(4)
	if err != nil {
		return err
	}
	if padding != 0 {
		return newValueError(ErrNonZeroPadding, padding)
	}

	// ordinal=0 indicates that there MUST be no envelope.
	if ordinal == 0 && !optAllowed {
		return newValueError(ErrInvalidXUnionTag, ordinal)
	} else if ordinal == 0 && optAllowed {
		h, err := unmarshalEnvelopeHeader(in)
		if err != nil {
			return err
		}

		if h.isPresent() {
			return newValueError(ErrInvalidXUnionTag, ordinal)
		}

		return nil
	}

	// If we reach here, ordinal != 0.

	field, ok := m.fields[int(ordinal)]
	if !ok {
		if m.strictness == isStrict {
			return newValueError(ErrInvalidXUnionTag, ordinal)
		}

		v.Field(0).SetUint(ordinal)

		unknownData, err := unmarshalEnvelopeUnknown(in)
		if err != nil {
			return err
		}

		unknownDataField := v.FieldByName("I_unknownData")
		// * FieldByName() returns a zero Value, which is _non-settable_ & non-addressable, if the
		//   field isn't found.
		// * So, we use .CanSet() below on the returned field to check whether the field exists.
		// * This enables this code to properly work with FIDL-generated Go bindings that hasn't
		//   been updated with the UnknownValue field yet.
		// * This enables this code to land as a soft transition
		//   <https://fuchsia.googlesource.com/fuchsia/+/master/docs/development/workflows/multilayer_changes.md#hard-and-soft-transitions>.
		if unknownDataField.CanSet() {
			unknownDataField.SetBytes(unknownData)
		}

		return nil
	}

	if optAllowed {
		v.Set(reflect.New(typ))
		v = v.Elem()
	}

	ordinalToSet := ordinal
	if m.unionToXunion {
		ordinalToSet = uint64(field.index)
	}
	v.Field(0).SetUint(ordinalToSet)

	var mode unmarshalEnvelopeMode
	if optAllowed {
		mode = knownMayBeAbsent
	} else {
		mode = knownMustBePresent
	}

	isPresent, err := unmarshalEnvelope(ctx, field.Marshaler, in, v.Field(field.index), mode)
	if err != nil {
		return err
	}

	if !isPresent {
		v.Set(reflect.Zero(reflect.PtrTo(typ)))
	}

	return nil
}

type mOptXUnion struct {
	mXUnion
	typ reflect.Type
}

func (m mOptXUnion) getMarshalSize(ctx MarshalerContext) int {
	return m.mXUnion.getMarshalSize(ctx)
}

func (m mOptXUnion) getUnmarshalSize(ctx MarshalerContext) int {
	return m.mXUnion.getUnmarshalSize(ctx)
}

func (m mOptXUnion) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	if v.IsNil() {
		out.writeUint(0, 8) // ordinal + padding
		marshalEnvelopeAbsent(out)
		return nil
	} else {
		return m.mXUnion.marshal(ctx, v.Elem(), out)
	}
}

func (m mOptXUnion) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	return m.unmarshalWithOptSpecified(ctx, in, v, m.typ)
}

type mTable struct {
	fields                []mField
	ordinals              []int
	sizeOld, alignmentOld int
	sizeV1, alignmentV1   int
}

func (m mTable) getMarshalSize(ctx MarshalerContext) int {
	if ctx.EncodeUnionsAsXUnionBytes {
		return m.sizeV1
	}
	return m.sizeOld
}

func (m mTable) getUnmarshalSize(ctx MarshalerContext) int {
	if ctx.DecodeUnionsFromXUnionBytes {
		return m.sizeV1
	}
	return m.sizeOld
}

const envelopeSize = 16

type envelopeHeader struct {
	byteCount   uint32
	handleCount uint32
	presence    uint64
}

func (h envelopeHeader) isPresent() bool {
	return h.presence == allocPresent
}

func marshalEnvelopePresent(ctx MarshalerContext, m Marshaler, v reflect.Value, out *encoder) error {
	numHandles := len(out.handles)
	numBytes := len(out.buffer)
	head := out.head
	out.head = out.newObject(m.getMarshalSize(ctx))
	if err := m.marshal(ctx, v, out); err != nil {
		return err
	}
	numHandles = len(out.handles) - numHandles
	numBytes = len(out.buffer) - numBytes
	out.head = head
	out.writeUint(uint64(numBytes), 4)
	out.writeUint(uint64(numHandles), 4)
	out.writeUint(allocPresent, 8)
	return nil
}

func marshalEnvelopeAbsent(out *encoder) {
	out.writeUint(0, 8) // both numBytes, and numHandles
	out.writeUint(noAlloc, 8)
}

type unmarshalEnvelopeMode int

const (
	_ unmarshalEnvelopeMode = iota

	// knownMayBeAbsent indicates that the content of the envelope is known,
	// and that it may be absent, i.e. encountering an empty envelope is
	// expected
	knownMayBeAbsent

	// knownMustBePresent indicates that the content of the envelope is known,
	// and that it must be present, i.e. encountering an empty envelope
	// should be considered a failure
	knownMustBePresent
)

func unmarshalEnvelopeHeader(in *decoder) (envelopeHeader, error) {
	var h envelopeHeader

	byteCount, err := in.readUint(4)
	if err != nil {
		return h, err
	}
	h.byteCount = uint32(byteCount)

	handleCount, err := in.readUint(4)
	if err != nil {
		return h, err
	}
	h.handleCount = uint32(handleCount)

	h.presence, err = in.readUint(8)
	if err != nil {
		return h, err
	}

	switch h.presence {
	case allocPresent, noAlloc:
		break
	default:
		return h, newValueError(ErrBadRefEncoding, h)
	}

	if end := in.nextObject + int(h.byteCount); end < 0 || end > len(in.buffer) {
		return h, newValueError(ErrEnvelopeTooLong, h)
	}

	if h.handleCount > uint32(len(in.handles)) {
		return h, newValueError(ErrTooManyHandles, h)
	}

	return h, nil
}

func unmarshalEnvelopeUnknown(in *decoder) ([]byte, error) {
	header, err := unmarshalEnvelopeHeader(in)
	if err != nil {
		return nil, err
	}

	for i := uint32(0); i < header.handleCount; i++ {
		in.handles[0].Close() // best effort
		in.handles = in.handles[1:]
	}

	// Don't need to check for overflow when calculating the end of the envelope, since
	// unmarshalEnvelopeHeader() does that.
	start := in.nextObject
	end := in.nextObject + int(header.byteCount)

	unknownData := in.buffer[start:end]
	in.nextObject = end

	return unknownData, nil
}

func unmarshalEnvelopeContent(ctx MarshalerContext, header envelopeHeader, m Marshaler, in *decoder, v reflect.Value, mode unmarshalEnvelopeMode) (bool, error) {
	savedHead := in.head
	in.head = in.nextObject
	in.nextObject += align(m.getUnmarshalSize(ctx), 8)
	if err := m.unmarshal(ctx, in, v); err != nil {
		return false, err
	}
	in.head = savedHead

	return true, nil
}

func unmarshalEnvelope(ctx MarshalerContext, m Marshaler, in *decoder, v reflect.Value, mode unmarshalEnvelopeMode) (bool, error) {
	header, err := unmarshalEnvelopeHeader(in)
	if err != nil {
		return false, err
	}

	if !header.isPresent() {
		if mode == knownMustBePresent {
			return false, newValueError(ErrUnexpectedNullRef, v)
		}

		if header.byteCount != 0 {
			return false, newValueError(ErrUnexpectedNumBytes, header.byteCount)
		}

		if header.handleCount != 0 {
			return false, newValueError(ErrUnexpectedNumHandles, header.handleCount)
		}

		return false, nil
	}

	return unmarshalEnvelopeContent(ctx, header, m, in, v, mode)
}

func (m mTable) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	// Determining max ordinal.
	var (
		maxOrdinal   int
		numKnown     = len(m.ordinals)
		fieldPresent = make([]bool, numKnown)
	)
	for index := 0; index < numKnown; index++ {
		presenceIndex := index*2 + 2
		fieldPresent[index] = v.Field(presenceIndex).Bool()
		if fieldPresent[index] {
			if fieldOrdinal := m.ordinals[index]; maxOrdinal < fieldOrdinal {
				maxOrdinal = fieldOrdinal
			}
		}
	}

	// Vector of envelopes header.
	out.writeUint(uint64(maxOrdinal), 8)
	out.writeUint(allocPresent, 8)

	// Early exit on empty table.
	if maxOrdinal == 0 {
		return nil
	}

	// Encode in the out-of-line object.
	oldHead := out.head
	out.head = out.newObject(maxOrdinal * envelopeSize)

	// Envelopes.
	var (
		ordinal                          = 1
		index, fieldIndex, presenceIndex = 0, 1, 2
	)
	for ordinal <= maxOrdinal {
		fieldKnown := index < numKnown && ordinal == m.ordinals[index]
		if fieldKnown && fieldPresent[index] {
			if err := marshalEnvelopePresent(ctx, m.fields[index], v.Field(fieldIndex), out); err != nil {
				return err
			}
		} else {
			marshalEnvelopeAbsent(out)
		}

		ordinal++
		if fieldKnown {
			index++
			fieldIndex += 2    // i.e. skip presenece field
			presenceIndex += 2 // i.e. skip field
		}
	}

	// Re-position head.
	out.head = oldHead

	return nil
}

func (m mTable) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	mou, err := in.readUint(8)
	if err != nil {
		return err
	}

	// uints/ints are only guaranteed to be 32 bit longs.
	// we use maxOrdinal as an int, so we must make sure that it fits.
	if mou > uint64(^uint(0)) {
		return newValueError(ErrUnexpectedOrdinal, v)
	}
	maxOrdinal := int(mou)

	allocPtr, err := in.readUint(8)
	if err != nil {
		return err
	}
	switch allocPtr {
	case allocPresent:
		// good
	case noAlloc:
		return newValueError(ErrUnexpectedNullRef, v)
	default:
		return newValueError(ErrBadRefEncoding, v)
	}

	// Early exit on empty table.
	if maxOrdinal == 0 {
		return nil
	}

	// Envelopes.
	var (
		numKnown                         = len(m.ordinals)
		ordinal                          = 1
		index, fieldIndex, presenceIndex = 0, 1, 2
	)
	tableBodyHead := in.nextObject
	in.nextObject += maxOrdinal * envelopeSize
	oldHead := in.head
	in.head = tableBodyHead
	for ordinal <= maxOrdinal {
		fieldKnown := index < numKnown && ordinal == m.ordinals[index]
		if fieldKnown {
			if isPresent, err := unmarshalEnvelope(ctx, m.fields[index], in, v.Field(fieldIndex), knownMayBeAbsent); err != nil {
				return err
			} else if isPresent {
				v.Field(presenceIndex).SetBool(true)
			}
		} else {
			if _, err := unmarshalEnvelopeUnknown(in); err != nil {
				return err
			}
		}
		ordinal++
		if fieldKnown {
			index++
			fieldIndex += 2    // i.e skip presence field
			presenceIndex += 2 // i.e skip field
		}
	}
	in.head = oldHead

	return nil
}

type mPointer struct {
	Marshaler
	elemTyp reflect.Type
}

func (m mPointer) getMarshalSize(ctx MarshalerContext) int {
	return 8
}

func (m mPointer) getUnmarshalSize(ctx MarshalerContext) int {
	return 8
}

func (m mPointer) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	// Nil?
	if v.IsNil() {
		out.writeUint(noAlloc, 8)
		return nil
	}

	// Write out allocation marker.
	out.writeUint(allocPresent, 8)

	// Set up the out-of-line space and the head.
	oldHead := out.head
	out.head = out.newObject(align(m.Marshaler.getMarshalSize(ctx), 8))

	// Marshal field.
	if err := m.Marshaler.marshal(ctx, v.Elem(), out); err != nil {
		return err
	}

	// Re-position head.
	out.head = oldHead

	return nil
}

func (m mPointer) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	// Nil?
	ptr, err := in.readUint(8)
	if err != nil {
		return err
	}
	switch ptr {
	case noAlloc:
		v.Set(reflect.Zero(v.Type()))
		return nil
	case allocPresent:
		// good
	default:
		return newValueError(ErrBadRefEncoding, v)
	}

	// Create the new struct.
	v.Set(reflect.New(m.elemTyp))

	// Set up the out-of-line space and the head.
	oldHead := in.head
	in.head = in.nextObject
	in.nextObject += align(m.Marshaler.getUnmarshalSize(ctx), 8)

	// Unmarshal field.
	if err := m.Marshaler.unmarshal(ctx, in, v.Elem()); err != nil {
		return err
	}

	// Re-position head.
	in.head = oldHead

	return nil
}

type mOptUnion struct {
	mPointer
	mOptXUnion
}

func (m mOptUnion) getMarshalSize(ctx MarshalerContext) int {
	if ctx.EncodeUnionsAsXUnionBytes {
		return 24
	}
	return 8
}

func (m mOptUnion) getUnmarshalSize(ctx MarshalerContext) int {
	if ctx.DecodeUnionsFromXUnionBytes {
		return 24
	}
	return 8
}

func (m mOptUnion) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	if ctx.EncodeUnionsAsXUnionBytes {
		return m.mOptXUnion.marshal(ctx, v, out)
	} else {
		return m.mPointer.marshal(ctx, v, out)
	}
}

func (m mOptUnion) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	if ctx.DecodeUnionsFromXUnionBytes {
		return m.mOptXUnion.unmarshal(ctx, in, v)
	} else {
		return m.mPointer.unmarshal(ctx, in, v)
	}
}

type mArray struct {
	Marshaler
	size int
}

func (m mArray) getMarshalSize(ctx MarshalerContext) int {
	return m.size * m.Marshaler.getMarshalSize(ctx)
}
func (m mArray) getUnmarshalSize(ctx MarshalerContext) int {
	return m.size * m.Marshaler.getUnmarshalSize(ctx)
}

func (m mArray) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	for i, len := 0, v.Len(); i < len; i++ {
		if err := m.Marshaler.marshal(ctx, v.Index(i), out); err != nil {
			return err
		}
	}
	return nil
}

func (m mArray) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	for i, len := 0, v.Len(); i < len; i++ {
		if err := m.Marshaler.unmarshal(ctx, in, v.Index(i)); err != nil {
			return err
		}
	}
	return nil
}

type mVector struct {
	Marshaler
	maxSize       int
	sliceTyp      reflect.Type
	isVectorUint8 bool
}

func (m mVector) getMarshalSize(ctx MarshalerContext) int {
	return 16
}
func (m mVector) getUnmarshalSize(ctx MarshalerContext) int {
	return 16
}

func (m mVector) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	// Bounds check.
	vLen := v.Len()
	if m.maxSize < vLen {
		return newExpectError(ErrVectorTooLong, m.maxSize, vLen)
	}

	// Vector header.
	out.writeUint(uint64(vLen), 8)
	out.writeUint(allocPresent, 8)

	// Early exit if the vector is empty.
	if vLen == 0 {
		return nil
	}

	// Encode in the out-of-line object.
	oldHead := out.head
	out.head = out.newObject(vLen * m.Marshaler.getMarshalSize(ctx))

	// Marshal elements.
	if m.isVectorUint8 {
		copy(out.buffer[out.head:], v.Bytes())
	} else {
		for i := 0; i < vLen; i++ {
			if err := m.Marshaler.marshal(ctx, v.Index(i), out); err != nil {
				return err
			}
		}
	}

	// Re-position head.
	out.head = oldHead

	return nil
}

func (m mVector) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	size, err := in.readUint(8)
	if err != nil {
		return err
	}
	ptr, err := in.readUint(8)
	if err != nil {
		return err
	}
	switch ptr {
	case noAlloc:
		return newValueError(ErrUnexpectedNullRef, v)
	case allocPresent:
		return m.unmarshalWithUncheckedSize(ctx, in, v, int(size))
	default:
		return newValueError(ErrBadRefEncoding, v)
	}
}

func (m mVector) unmarshalWithUncheckedSize(ctx MarshalerContext, in *decoder, v reflect.Value, size int) error {
	if size < 0 || m.maxSize < size {
		return newExpectError(ErrVectorTooLong, m.maxSize, size)
	}

	// Unmarshal in the out-of-line object.
	oldHead := in.head
	in.head = in.nextObject
	elemSize := m.Marshaler.getUnmarshalSize(ctx)
	in.nextObject += align(size*elemSize, 8)

	// Unmarshal elements.
	if m.isVectorUint8 {
		data := make([]uint8, size, size)
		copy(data, in.buffer[in.head:])
		v.Set(reflect.ValueOf(data))
	} else {
		v.Set(reflect.MakeSlice(m.sliceTyp, size, size))
		for i := 0; i < size; i++ {
			if err := m.Marshaler.unmarshal(ctx, in, v.Index(i)); err != nil {
				return err
			}
		}
	}

	// Re-position head.
	in.head = oldHead

	return nil
}

type mOptVector mVector

func (m mOptVector) getMarshalSize(ctx MarshalerContext) int {
	return 16
}
func (m mOptVector) getUnmarshalSize(ctx MarshalerContext) int {
	return 16
}

func (m mOptVector) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	if v.IsNil() {
		out.writeUint(0, 8)
		out.writeUint(noAlloc, 8)
		return nil
	}

	return mVector(m).marshal(ctx, v.Elem(), out)
}

func (m mOptVector) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	size, err := in.readUint(8)
	if err != nil {
		return err
	}
	ptr, err := in.readUint(8)
	if err != nil {
		return err
	}
	switch ptr {
	case noAlloc:
		v.Set(reflect.Zero(reflect.PtrTo(m.sliceTyp)))
		return nil
	case allocPresent:
		v.Set(reflect.New(m.sliceTyp))
		return mVector(m).unmarshalWithUncheckedSize(ctx, in, v.Elem(), int(size))
	default:
		return newValueError(ErrBadRefEncoding, v)
	}
}

type mBool struct{}

func (m mBool) getMarshalSize(ctx MarshalerContext) int {
	return 1
}
func (m mBool) getUnmarshalSize(ctx MarshalerContext) int {
	return 1
}

func (m mBool) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	if v.Bool() {
		out.writeUint(1, 1)
	} else {
		out.writeUint(0, 1)
	}
	return nil
}

func (m mBool) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	b, err := in.readUint(1)
	if err != nil {
		return err
	}
	switch b {
	case 0, 1:
		v.SetBool(b == 1)
		return nil
	default:
		return newValueError(ErrInvalidBoolValue, b)
	}
}

// int is size (1 for int8, 2 for int16, etc.)
type mInt int

func (m mInt) getMarshalSize(ctx MarshalerContext) int {
	return int(m)
}
func (m mInt) getUnmarshalSize(ctx MarshalerContext) int {
	return int(m)
}

func (m mInt) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	size := int(m)
	out.writeUint(uint64(v.Int()), size)
	return nil
}

func (m mInt) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	size := int(m)
	val, err := in.readUint(size)
	if err != nil {
		return err
	}
	v.SetInt(int64(val))
	return nil
}

// uint is size (1 for uint8, 2 f   or uint16, etc.)
type mUint int

func (m mUint) getMarshalSize(ctx MarshalerContext) int {
	return int(m)
}
func (m mUint) getUnmarshalSize(ctx MarshalerContext) int {
	return int(m)
}

func (m mUint) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	size := int(m)
	out.writeUint(v.Uint(), size)
	return nil
}

func (m mUint) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	size := int(m)
	val, err := in.readUint(size)
	if err != nil {
		return err
	}
	v.SetUint(val)
	return nil
}

type mFloat32 struct{}

func (m mFloat32) getMarshalSize(ctx MarshalerContext) int {
	return 4
}
func (m mFloat32) getUnmarshalSize(ctx MarshalerContext) int {
	return 4
}

func (m mFloat32) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	out.writeUint(uint64(math.Float32bits(float32(v.Float()))), 4)
	return nil
}

func (m mFloat32) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	val, err := in.readUint(4)
	if err != nil {
		return err
	}
	v.SetFloat(float64(math.Float32frombits(uint32(val))))
	return nil
}

type mFloat64 struct{}

func (m mFloat64) getMarshalSize(ctx MarshalerContext) int {
	return 8
}
func (m mFloat64) getUnmarshalSize(ctx MarshalerContext) int {
	return 8
}

func (m mFloat64) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	out.writeUint(math.Float64bits(v.Float()), 8)
	return nil
}

func (m mFloat64) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	val, err := in.readUint(8)
	if err != nil {
		return err
	}
	v.SetFloat(math.Float64frombits(val))
	return nil
}

type mString int

func (m mString) getMarshalSize(ctx MarshalerContext) int {
	return 16
}
func (m mString) getUnmarshalSize(ctx MarshalerContext) int {
	return 16
}

func (m mString) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	var (
		maxSize = int(m)
		s       = v.String()
		length  = len(s)
	)
	if maxSize < length {
		return newExpectError(ErrStringTooLong, maxSize, length)
	}

	// length, allocPresent
	out.writeUint(uint64(length), 8)
	out.writeUint(allocPresent, 8)

	// Create a new out-of-line object and write bytes of the string.
	head := out.newObject(length)
	copy(out.buffer[head:], s)

	return nil
}

func (m mString) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	size, err := in.readUint(8)
	if err != nil {
		return err
	}
	ptr, err := in.readUint(8)
	if err != nil {
		return err
	}
	switch ptr {
	case noAlloc:
		return newValueError(ErrUnexpectedNullRef, "string")
	case allocPresent:
		return m.unmarshalWithUncheckedSize(in, v, int(size))
	default:
		return newValueError(ErrBadRefEncoding, "string")
	}
}

func (m mString) unmarshalWithUncheckedSize(in *decoder, v reflect.Value, size int) error {
	if maxSize := int(m); size < 0 || maxSize < size {
		return newExpectError(ErrStringTooLong, maxSize, size)
	}
	start, end := in.nextObject, in.nextObject+size
	if len(in.buffer) < end {
		return newValueError(ErrMessageTooSmall, v)
	}
	s := string(in.buffer[start:end])
	if !utf8.ValidString(s) {
		return newValueError(ErrStringNotUTF8, v)
	}
	v.SetString(s)
	in.nextObject += align(size, 8)
	return nil
}

type mOptString uint64

func (m mOptString) getMarshalSize(ctx MarshalerContext) int {
	return 16
}
func (m mOptString) getUnmarshalSize(ctx MarshalerContext) int {
	return 16
}

func (m mOptString) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	if v.IsNil() {
		out.writeUint(0, 8)
		out.writeUint(noAlloc, 8)
		return nil
	}

	return mString(m).marshal(ctx, v.Elem(), out)
}

var (
	nilString = reflect.Zero(reflect.PtrTo(reflect.TypeOf("")))
	typString = reflect.TypeOf("")
)

func (m mOptString) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	size, err := in.readUint(8)
	if err != nil {
		return err
	}
	ptr, err := in.readUint(8)
	if err != nil {
		return err
	}
	switch ptr {
	case noAlloc:
		v.Set(nilString)
		return nil
	case allocPresent:
		v.Set(reflect.New(typString))
		return mString(m).unmarshalWithUncheckedSize(in, v.Elem(), int(size))
	default:
		return newValueError(ErrBadRefEncoding, v)
	}
}

type mHandle bool

func (m mHandle) getMarshalSize(ctx MarshalerContext) int {
	return 4
}
func (m mHandle) getUnmarshalSize(ctx MarshalerContext) int {
	return 4
}

func (m mHandle) isOpt() bool {
	return bool(m)
}

func (m mHandle) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	// The underlying type of all the handles is a uint32, so we're
	// safe calling Uint(). This will panic if that is no longer true.
	raw := zx.Handle(v.Uint())
	if raw == zx.HandleInvalid {
		if !m.isOpt() {
			return ErrUnexpectedNullHandle
		}
		out.writeUint(uint64(noHandle), 4)
		return nil
	}
	out.handles = append(out.handles, raw)
	out.writeUint(uint64(handlePresent), 4)
	return nil
}

func (m mHandle) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	h, err := in.readUint(4)
	if err != nil {
		return err
	}
	switch uint32(h) {
	case noHandle:
		if !m.isOpt() {
			return ErrUnexpectedNullHandle
		}
		v.SetUint(uint64(zx.HandleInvalid))
		return nil
	case handlePresent:
		if len(in.handles) == 0 {
			return ErrNotEnoughHandles
		}
		v.SetUint(uint64(in.handles[0]))
		in.handles = in.handles[1:]
		return nil
	default:
		return newValueError(ErrBadHandleEncoding, h)
	}
}

// An interface is represented by a Proxy, whose first field is
// a zx.Channel, and we can just marshal that. Same goes for an
// interface request, which is just an InterfaceRequest whose
// first field is a zx.Channel.
type mInterface mHandle

func (m mInterface) getMarshalSize(ctx MarshalerContext) int {
	return mHandle(m).getMarshalSize(ctx)
}
func (m mInterface) getUnmarshalSize(ctx MarshalerContext) int {
	return mHandle(m).getUnmarshalSize(ctx)
}

func (m mInterface) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	return mHandle(m).marshal(ctx, v.Field(0), out)
}

func (m mInterface) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	return mHandle(m).unmarshal(ctx, in, v.Field(0))
}
