// 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"
	"unsafe"
)

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, handleDispositions []zx.HandleDisposition) (int, int, error) {
	return MarshalWithContext(newCtx(), message, data, handleDispositions)
}

// Marshal marshals (or encodes) a message into the data and handles slices.
func MarshalWithContext(ctx MarshalerContext, message Message, data []byte, handleDispositions []zx.HandleDisposition) (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], handleDispositions: handleDispositions[: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.handleDispositions), nil
}

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

// UnmarshalWithContext2 behaves identically to UnmarshalWithContext but takes a HandleInfo.
func UnmarshalWithContext2(ctx MarshalerContext, data []byte, handleInfos []zx.HandleInfo, 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,
		handleInfos: handleInfos,
		nextObject:  nextObject,
	}
	if err := m.unmarshal(ctx, in, v); err != nil {
		return 0, 0, err
	}
	return in.nextObject, len(handleInfos) - len(in.handleInfos), nil
}

func UnmarshalWithContext(ctx MarshalerContext, data []byte, handles []zx.Handle, message Message) (int, int, error) {
	resphi := messageHandleInfosPool.Get().([]zx.HandleInfo)
	defer messageHandleInfosPool.Put(resphi)

	for i, handle := range handles {
		resphi[i] = zx.HandleInfo{
			Handle: handle,
			Type:   zx.ObjectTypeNone,
			Rights: zx.RightSameRights,
		}
	}

	return UnmarshalWithContext2(ctx, data, resphi[:len(handles)], message)
}

const tagSizeV1 = "fidl_size_v1"
const tagAlignmentV1 = "fidl_alignment_v1"
const tagOffsetV1 = "fidl_offset_v1"
const tagHandleRights = "fidl_handle_rights"
const tagHandleSubtype = "fidl_handle_subtype"
const tagOrdinal = "fidl_ordinal"
const tagBounds = "fidl_bounds"
const tagMarshalerKind = "fidl"

// These rights come from FTP-028
// (all requests and interfaces have the same handle rights)
const ProtocolRights = zx.RightTransfer | zx.RightWait | zx.RightInspect | zx.RightWrite | zx.RightRead | zx.RightSignal | zx.RightSignalPeer

type tagKind int

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

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() + ")"
	}
}

// Extracts a list of fields for struct, union, table types that can be used
// for iterating.
// This skips the inital tag field.
func dataFields(typ reflect.Type) []reflect.StructField {
	if typ.Kind() != reflect.Struct {
		panic("expected struct")
	}
	if name := typ.Field(0).Name; name != "_" && !strings.HasPrefix(name, "I_") {
		panic("expected first field to be a metadata field")
	}
	fields := make([]reflect.StructField, typ.NumField()-1)
	for i := 1; i < typ.NumField(); i++ {
		fields[i-1] = typ.Field(i)
	}
	return fields
}

// Returns true if the go type has the same layout as the FIDL wire format.
func matchesWireFormatLayout(marshaler Marshaler, typ reflect.Type) bool {
	switch marshaler := marshaler.(type) {
	case mBool:
		// Need to validate 0, 1.
		return false
	case mUint:
		return true
	case mInt:
		return true
	case mFloat32:
		// Need to validate.
		return false
	case mFloat64:
		// Need to validate.
		return false
	case mArray:
		return matchesWireFormatLayout(marshaler.Marshaler, typ.Elem())
	case mStructUnsafeCopy:
		return true
	case mStruct:
		// Note: In some cases, go structs may be different size than wire format
		// structs but otherwise identical. It may be possible to change this
		// logic to allow a partial copy in the future.
		if marshaler.size != int(typ.Size()) {
			return false
		}
		if marshaler.alignment != typ.Align() {
			return false
		}
		for i, rField := range dataFields(typ) {
			field := marshaler.fields[i]
			if field.offset != int(rField.Offset) {
				return false
			}
			if !matchesWireFormatLayout(field.Marshaler, rField.Type) {
				return false
			}
		}
		return true
	case mEmptyStruct:
		// Note: empty struct is 0 or 1 bytes at different times in go.
		return false
	case mHandle:
		// Note: In the future, we might instead consider treating handles
		// like uint32 and decoding in a subsequent step.
		return false
	case mXUnion, mOptXUnion, mTable, mVector, mString, mPointer:
		return false
	default:
		panic("unhandledType " + reflect.TypeOf(marshaler).Name())
	}
}

func createMarshaler(typ reflect.Type) (Marshaler, error) {
	// field 0 holds the tag
	tagField := typ.Field(0)
	marshalerKind, err := readKindTag(tagField)
	if err != nil {
		return nil, err
	}

	var (
		kind     = marshalerKind
		fields   []mField
		ordinals []uint64
		offsets  []int
	)

	// - structs, unions, and xunions have fields one after the other;
	// - tables have a field, followed by a bool presence indicator, etc.
	for index, field := range dataFields(typ) {
		if kind == tableTag && index%2 == 1 {
			// Presence field
			if field.Type.Kind() != reflect.Bool {
				return nil, errors.New("incorrect presence field on " + nicefmt(typ))
			}
			continue
		}
		fieldBounds := readBoundsTag(field)
		handleRights, handleSubtype, err := readHandleRightsAndSubtype(field)
		if err != nil {
			return nil, err
		}
		switch kind {
		case structTag:
			offset, err := readIntTag(field, tagOffsetV1)
			if err != nil {
				return nil, err
			}
			offsets = append(offsets, offset)
		case xunionTag, strictXunionTag, tableTag:
			ordinal := readOrdinalTag(field)
			ordinals = append(ordinals, uint64(ordinal))
		default:
		}
		fieldMarshaler, err := createMarshalerForField(field.Type, fieldBounds, handleRights, handleSubtype)
		if err != nil {
			return nil, err
		}
		fields = append(fields, mField{fieldMarshaler, field.Index[0]})
	}

	size, err := readIntTag(tagField, tagSizeV1)
	if err != nil {
		return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
	}
	alignment, 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],
				offset: offsets[i],
			})
		}
		s := mStruct{
			fields:    structFields,
			size:      size,
			alignment: alignment,
		}
		if matchesWireFormatLayout(s, typ) {
			return mStructUnsafeCopy{
				fields:    structFields,
				size:      size,
				alignment: alignment,
			}, nil
		}
		return s, nil
	case xunionTag, strictXunionTag:
		strictness := strictness(kind == strictXunionTag)

		ordinalToFields := make(map[uint64]mField)
		for i := 0; i < len(fields); i++ {
			ordinalToFields[ordinals[i]] = fields[i]
		}
		return mXUnion{
			fields:     ordinalToFields,
			ordinals:   ordinals,
			size:       size,
			alignment:  alignment,
			strictness: strictness,
		}, nil
	case tableTag:
		return mTable{
			fields:    fields,
			size:      size,
			alignment: alignment,
			ordinals:  ordinals,
		}, nil
	default:
		return nil, errors.New("unknown kind tag on " + nicefmt(typ))
	}
}

func readKindTag(field reflect.StructField) (tagKind, error) {
	content, ok := field.Tag.Lookup(tagMarshalerKind)
	if !ok {
		return 0, errors.New(tagMarshalerKind + " not found on field " + field.Name)
	}
	switch content {
	case "s":
		return structTag, nil
	case "x":
		return xunionTag, nil
	case "x!":
		return strictXunionTag, nil
	case "t":
		return tableTag, nil
	default:
		return 0, errors.New("unknown kind tag: " + content)
	}
}

func readHandleRightsAndSubtype(field reflect.StructField) (zx.Rights, zx.ObjectType, error) {
	if !containsHandleType(field.Type) {
		// Skip non-handle field types and don't return an error.
		return zx.RightSameRights, zx.ObjectTypeNone, nil
	}

	// Read handle rights
	val, ok := field.Tag.Lookup(tagHandleRights)
	if !ok {
		return zx.RightSameRights, zx.ObjectTypeNone, ErrUnspecifiedHandleRights
	}
	rights, err := strconv.ParseInt(val, 0, 64)
	if err != nil {
		return zx.RightSameRights, zx.ObjectTypeNone, err
	}
	convertedRights := zx.Rights(rights)

	// Read handle subtype
	val, ok = field.Tag.Lookup(tagHandleSubtype)
	if !ok {
		return zx.RightSameRights, zx.ObjectTypeNone, ErrUnspecifiedHandleType
	}
	subtype, err := strconv.ParseInt(val, 0, 64)
	if err != nil {
		return zx.RightSameRights, zx.ObjectTypeNone, err
	}
	convertedSubtype := zx.ObjectType(subtype)

	return convertedRights, convertedSubtype, nil
}

func containsHandleType(typ reflect.Type) bool {
	// Protocols and requests are technically handle types but their rights /
	// subtypes are handled elsewhere.
	if typ.ConvertibleTo(proxyType) || typ.ConvertibleTo(interfaceRequestType) {
		return false
	}
	if isHandleType(typ) {
		return true
	}
	if typ.Kind() == reflect.Slice || typ.Kind() == reflect.Ptr {
		return containsHandleType(typ.Elem())
	}
	return false
}

func readOrdinalTag(field reflect.StructField) int {
	ordinal, err := readIntTag(field, tagOrdinal)
	if err != nil {
		return math.MaxInt32
	}
	return ordinal
}

func readBoundsTag(field reflect.StructField) bounds {
	content, ok := field.Tag.Lookup(tagBounds)
	if !ok {
		return nil
	}

	var nums []int
	for _, elem := range strings.Split(content, ",") {
		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 readIntTag(field reflect.StructField, tagKey string) (int, error) {
	content, ok := field.Tag.Lookup(tagKey)
	if !ok {
		return 0, errors.New(tagKey + " not found on field " + field.Name)
	}
	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
}

func readHandleRightsTag(field reflect.StructField) (zx.Rights, error) {
	val, ok := field.Tag.Lookup(tagHandleRights)
	if !ok {
		return zx.RightSameRights, nil
	}
	rights, err := strconv.ParseInt(val, 0, 64)
	if err != nil {
		return zx.RightSameRights, err
	}
	convertedRights := zx.Rights(rights)
	return convertedRights, nil
}

func createMarshalerForField(typ reflect.Type, bounds bounds, handleRights zx.Rights, handleSubtype zx.ObjectType) (Marshaler, error) {
	if isHandleType(typ) {
		nullable, _ := bounds.pop()
		return mHandle{nullable: nullable != 0, rights: handleRights, subtype: handleSubtype}, nil
	}

	if typ.ConvertibleTo(proxyType) || typ.ConvertibleTo(interfaceRequestType) {
		nullable, _ := bounds.pop()
		return mInterface{
			nullable: nullable != 0,
			rights:   ProtocolRights,
			subtype:  zx.ObjectTypeChannel}, 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, handleRights, handleSubtype)
		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, handleRights, handleSubtype)
		if err != nil {
			return nil, err
		}
		return mVector{
			Marshaler: elemMarshaler,
			maxSize:   maxSize,
			sliceTyp:  reflect.SliceOf(elemTyp),
			// The fast path only supports `[]uint8`. A slice of aliased types must be handled via the slow path.
			// We therefore prefer a monomorphic check.
			isVectorUint8: elemTyp == reflect.TypeOf(uint8(0)),
		}, nil
	case reflect.Struct:
		return createMarshaler(typ)
	case reflect.Ptr:
		return createOptMarshalerForField(typ.Elem(), bounds, handleRights, handleSubtype)
	default:
		return nil, errors.New("unable to create field marshaler for " + nicefmt(typ))
	}
}

func createOptMarshalerForField(typ reflect.Type, bounds bounds, handleRights zx.Rights, handleSubtype zx.ObjectType) (Marshaler, error) {
	m, err := createMarshalerForField(typ, bounds, handleRights, handleSubtype)
	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, mStructUnsafeCopy:
		return mPointer{
			Marshaler: m,
			elemTyp:   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 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{},
	mStructUnsafeCopy{},
	mEmptyStruct{},
	mXUnion{},
	mOptXUnion{},
	mTable{},
	mPointer{},
	mArray{},
	mVector{},
	mOptVector{},
	mBool{},
	mInt(0),
	mUint(0),
	mFloat32{},
	mFloat64{},
	mString(0),
	mOptString(0),
}

type mField struct {
	Marshaler
	index int
}

type mFieldWithOffset struct {
	mField
	offset int
}

func (m mFieldWithOffset) getMarshalOffset(ctx MarshalerContext) int {
	return m.offset
}

func (m mFieldWithOffset) getUnmarshalOffset(ctx MarshalerContext) int {
	return m.offset
}

type mStruct struct {
	fields          []mFieldWithOffset
	size, alignment int
}

func (m mStruct) getMarshalSize(ctx MarshalerContext) int {
	return m.size
}

func (m mStruct) getUnmarshalSize(ctx MarshalerContext) int {
	return m.size
}

func (m mStruct) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	structStart := align(out.head, m.alignment)
	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.alignment)
	return nil
}

func (m mStruct) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	structStart := align(in.head, m.alignment)
	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.alignment)
	return nil
}

type mStructUnsafeCopy struct {
	fields          []mFieldWithOffset
	size, alignment int
}

func (m mStructUnsafeCopy) getMarshalSize(ctx MarshalerContext) int {
	return m.size
}

func (m mStructUnsafeCopy) getUnmarshalSize(ctx MarshalerContext) int {
	return m.size
}

func (m mStructUnsafeCopy) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	// Directly copy the object's memory to the buffer.
	out.head = align(out.head, m.alignment)
	sh := reflect.SliceHeader{
		Data: uintptr(unsafe.Pointer(v.UnsafeAddr())),
		Len:  m.size,
		Cap:  m.size,
	}
	s := *(*[]uint8)(unsafe.Pointer(&sh))
	copy(out.buffer[out.head:], s)
	out.head += m.size
	return nil
}

func (m mStructUnsafeCopy) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	// Directly copy from the buffer to the object's memory.
	in.head = align(in.head, m.alignment)
	if len(in.buffer) < in.head+m.size {
		return ErrPayloadTooSmall
	}
	sh := reflect.SliceHeader{
		Data: uintptr(unsafe.Pointer(v.UnsafeAddr())),
		Len:  m.size,
		Cap:  m.size,
	}
	s := *(*[]uint8)(unsafe.Pointer(&sh))
	copy(s, in.buffer[in.head:])
	in.head += m.size
	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 mXUnion struct {
	fields          map[uint64]mField
	ordinals        []uint64
	size, alignment int
	strictness
}

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

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

func (m mXUnion) marshal(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	var ordinal uint64
	ordinal = v.Field(0).Uint()
	field, ok := m.fields[ordinal]
	if !ok {
		return newValueError(ErrInvalidXUnionTag, ordinal)
	}
	out.writeUint(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(8)
	if err != nil {
		return err
	}

	// 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[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()
	}

	ordinalOrFieldIndex := ordinal
	v.Field(0).SetUint(ordinalOrFieldIndex)

	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        []uint64
	size, alignment int
}

func (m mTable) getMarshalSize(ctx MarshalerContext) int {
	return m.size
}

func (m mTable) getUnmarshalSize(ctx MarshalerContext) int {
	return m.size
}

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 {
	numHandleDispositions := len(out.handleDispositions)
	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
	}
	numHandleDispositions = len(out.handleDispositions) - numHandleDispositions
	numBytes = len(out.buffer) - numBytes
	out.head = head
	out.writeUint(uint64(numBytes), 4)
	out.writeUint(uint64(numHandleDispositions), 4)
	out.writeUint(allocPresent, 8)
	return nil
}

func marshalEnvelopeAbsent(out *encoder) {
	out.writeUint(0, 8) // both numBytes, and numHandleDispositions
	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.handleInfos)) {
		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.handleInfos[0].Handle.Close() // best effort
		in.handleInfos = in.handleInfos[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   uint64
		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(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(int(maxOrdinal) * envelopeSize)

	// Envelopes.
	var (
		ordinal                          uint64 = 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 := 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                          uint64 = 1
		index, fieldIndex, presenceIndex        = 0, 1, 2
	)
	tableBodyHead := in.nextObject
	in.nextObject += int(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 {
	return 24
}

func (m mOptUnion) getUnmarshalSize(ctx MarshalerContext) int {
	return 24
}

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

func (m mOptUnion) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	return m.mOptXUnion.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)
	}

	if !utf8.ValidString(s) {
		return newValueError(ErrStringNotUTF8, v)
	}

	// 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 struct {
	nullable bool
	rights   zx.Rights
	subtype  zx.ObjectType
}

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

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

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.handleDispositions = append(out.handleDispositions, zx.HandleDisposition{
		Operation: zx.HandleOpMove,
		Handle:    raw,
		Type:      m.subtype,
		Rights:    m.rights,
		Result:    zx.ErrOk,
	})
	out.writeUint(uint64(handlePresent), 4)
	return nil
}

func (m mHandle) requiredRightsArePresent(actual zx.Rights) bool {
	if m.rights == zx.RightSameRights {
		return true
	}
	return actual.SupersetOf(m.rights)
}

func (m mHandle) filterOutUnspecifiedRights(actual zx.Rights) zx.Rights {
	if m.rights == zx.RightSameRights {
		return actual
	}
	return actual & m.rights
}

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.handleInfos) == 0 {
			return ErrNotEnoughHandles
		}
		handleInfo := in.handleInfos[0]
		in.handleInfos = in.handleInfos[1:]

		if !m.requiredRightsArePresent(handleInfo.Rights) {
			return newExpectError(ErrMissingRequiredHandleRights, m.rights, handleInfo.Rights)
		}

		handle := handleInfo.Handle
		reducedRights := m.filterOutUnspecifiedRights(handleInfo.Rights)
		if handleInfo.Rights != reducedRights {
			handle, err = handle.Replace(reducedRights)
			if err != nil {
				return newValueError(ErrUnableToReduceHandleRights, handle)
			}
		}

		if m.subtype != zx.ObjectTypeNone && m.subtype != handleInfo.Type {
			return newExpectError(ErrIncorrectHandleType, m.subtype, handleInfo.Type)
		}

		v.SetUint(uint64(handle))
		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))
}
