// 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) getSize() int {
	m.once.Do(m.init)
	return m.delegate.getSize()
}

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

func (m *lazyMarshaler) unmarshal(in *decoder, v reflect.Value) error {
	m.once.Do(m.init)
	return m.delegate.unmarshal(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) {
	// 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.getSize())
	if err := m.marshal(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) {
	// 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.getSize(), 8)
	in := &decoder{
		buffer:     data,
		handles:    handles,
		nextObject: nextObject,
	}
	if err := m.unmarshal(in, v); err != nil {
		return 0, 0, err
	}
	return in.nextObject, len(handles) - len(in.handles), nil
}

const tagKey = "fidl2"

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
	marshalerKind, marshalerBounds := readTag(typ.Field(0))
	var (
		kind      = marshalerKind
		size      = marshalerBounds[0]
		alignment = marshalerBounds[1]
		fields    []mField
		ordinals  []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 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.
		}
	}

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

		return mStruct{
			fields:    fields,
			size:      size,
			alignment: alignment,
		}, nil
	case unionTag:
		return mUnion{
			fields:    fields,
			size:      size,
			alignment: alignment,
		}, 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,
			size:       size,
			alignment:  alignment,
			strictness: strictness,
		}, nil
	case tableTag:
		return mTable{
			mStruct: mStruct{
				fields:    fields,
				size:      size,
				alignment: alignment,
			},
			ordinals: ordinals,
		}, nil
	default:
		return nil, errors.New("missing kind marker on " + nicefmt(typ))
	}
}

// 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 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 mOptStructUnion{
			Marshaler: m,
			elemTyp:   typ,
		}, nil
	case mStruct:
		return mOptStructUnion{
			Marshaler: m,
			elemTyp:   typ,
		}, nil
	case mUnion:
		return mOptStructUnion{
			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 {
	getSize() int
	marshal(v reflect.Value, out *encoder) error
	unmarshal(in *decoder, v reflect.Value) error
}

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

type mField struct {
	Marshaler
	index int
}

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

func (m mStruct) getSize() int {
	return m.size
}

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

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

type mEmptyStruct struct{}

func (_ mEmptyStruct) getSize() int {
	return 1
}

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

func (_ mEmptyStruct) unmarshal(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
	size, alignment int
}

func (m mUnion) getSize() int {
	return m.size
}

func (m mUnion) marshal(v reflect.Value, out *encoder) error {
	// 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.alignment)

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

	// Re-position head.
	out.head = head + m.size

	return nil
}

func (m mUnion) unmarshal(in *decoder, v reflect.Value) error {
	// 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 alignement before writing its field.
	in.head = align(in.head, m.alignment)

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

	// Re-position head.
	in.head = head + m.size

	return nil
}

type mXUnion struct {
	fields          map[int]mField
	size, alignment int
	strictness
}

func (m mXUnion) getSize() int {
	return m.size
}

func (m mXUnion) marshal(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(field, v.Field(field.index), out); err != nil {
		return err
	}

	return nil
}

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

func (m mXUnion) unmarshalWithOptSpecified(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()
	}

	v.Field(0).SetUint(ordinal)

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

	isPresent, err := unmarshalEnvelope(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) getSize() int {
	return m.size
}

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

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

type mTable struct {
	mStruct
	ordinals []int
}

const envelopeSize = 16

type envelopeHeader struct {
	byteCount   uint32
	handleCount uint32
	presence    uint64
}

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

func marshalEnvelopePresent(m Marshaler, v reflect.Value, out *encoder) error {
	numHandles := len(out.handles)
	numBytes := len(out.buffer)
	head := out.head
	out.head = out.newObject(m.getSize())
	if err := m.marshal(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(header envelopeHeader, m Marshaler, in *decoder, v reflect.Value, mode unmarshalEnvelopeMode) (bool, error) {
	savedHead := in.head
	in.head = in.nextObject
	in.nextObject += align(m.getSize(), 8)
	if err := m.unmarshal(in, v); err != nil {
		return false, err
	}
	in.head = savedHead

	return true, nil
}

func unmarshalEnvelope(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(header, m, in, v, mode)
}

func (m mTable) marshal(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(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(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(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 mOptStructUnion struct {
	Marshaler
	elemTyp reflect.Type
}

func (m mOptStructUnion) getSize() int {
	return 8
}

func (m mOptStructUnion) marshal(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.getSize(), 8))

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

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

	return nil
}

func (m mOptStructUnion) unmarshal(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.getSize(), 8)

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

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

	return nil
}

type mArray struct {
	Marshaler
	size int
}

func (m mArray) getSize() int {
	return m.size * m.Marshaler.getSize()
}

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

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

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

func (m mVector) getSize() int {
	return 16
}

func (m mVector) marshal(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.getSize())

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

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

	return nil
}

func (m mVector) unmarshal(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(in, v, int(size))
	default:
		return newValueError(ErrBadRefEncoding, v)
	}
}

func (m mVector) unmarshalWithUncheckedSize(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.getSize()
	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(in, v.Index(i)); err != nil {
				return err
			}
		}
	}

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

	return nil
}

type mOptVector mVector

func (m mOptVector) getSize() int {
	return 16
}

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

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

func (m mOptVector) unmarshal(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(in, v.Elem(), int(size))
	default:
		return newValueError(ErrBadRefEncoding, v)
	}
}

type mBool struct{}

func (m mBool) getSize() int {
	return 1
}

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

func (m mBool) unmarshal(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) getSize() int {
	return int(m)
}

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

func (m mInt) unmarshal(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) getSize() int {
	return int(m)
}

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

func (m mUint) unmarshal(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) getSize() int {
	return 4
}

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

func (m mFloat32) unmarshal(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) getSize() int {
	return 8
}

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

func (m mFloat64) unmarshal(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) getSize() int {
	return 16
}

func (m mString) marshal(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(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) getSize() int {
	return 16
}

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

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

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

func (m mOptString) unmarshal(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) getSize() int {
	return 4
}

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

func (m mHandle) marshal(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(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) getSize() int {
	return mHandle(m).getSize()
}

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

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