// 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.

package fidl

import (
	"errors"
	"math"
	"reflect"
	"strconv"
	"strings"
	"sync"
	"syscall/zx"
	"syscall/zx/fidl/internal/unsafevalue"
	"unicode/utf8"
	"unsafe"
)

type strictness bool

const (
	isFlexible strictness = false
	isStrict   strictness = true
)

type resourceness bool

const (
	isResourceType resourceness = true
	isValueType    resourceness = false
)

// 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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	m.once.Do(m.init)
	return m.delegate.marshal(ctx, v, out, offset, depth)
}

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

// Marshal marshals (or encodes) a message into the data and handles slices.
func Marshal(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 obscure way withing reflection. Just don't do
	// that.
	var (
		v = unsafevalue.ValueOf(message)
		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]}
	offset, err := out.newObject(m.getMarshalSize(ctx), 0)
	if err != nil {
		return 0, 0, err
	}

	if err := m.marshal(ctx, v, out, offset, 1); err != nil {
		return 0, 0, err
	}
	return len(out.buffer), len(out.handleDispositions), nil
}

// UnmarshalBuffer unmarshals (or decodes) into message using the data and handle slices.
// Unlike Unmarshal, it does not check that the entire message is consumed.
func UnmarshalBuffer(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 obscure way withing reflection. Just don't do
	// that.
	var (
		v = unsafevalue.ValueOf(message)
		m = message.Marshaler()
	)

	// Get the payload's value and unmarshal it.
	in := &decoder{
		buffer:      data,
		handleInfos: handleInfos,
	}

	offset, err := in.newObject(m.getUnmarshalSize(ctx), 0)
	if err != nil {
		return 0, 0, err
	}

	if err := m.unmarshal(ctx, in, offset, 1, v); err != nil {
		return 0, 0, err
	}
	return in.nextObject, len(handleInfos) - len(in.handleInfos), nil
}

// Unmarshal unmarshals (or decodes) into message using the data and handle slices.
func Unmarshal(ctx MarshalerContext, data []byte, handleInfos []zx.HandleInfo, message Message) error {
	var hasSucceeded bool
	defer func() {
		if !hasSucceeded {
			for _, handleInfo := range handleInfos {
				handleClose(&handleInfo.Handle)
			}
		}
	}()

	b, h, err := UnmarshalBuffer(ctx, data, handleInfos, message)
	if err != nil {
		return err
	}
	if b != len(data) {
		return newExpectError(ErrTooManyBytesInMessage, b, len(data))
	}
	if h != len(handleInfos) {
		return newExpectError(ErrTooManyHandles, h, len(handleInfos))
	}

	hasSucceeded = true
	return nil
}

const tagSizeV2 = "fidl_size_v2"
const tagAlignmentV2 = "fidl_alignment_v2"
const tagOffsetV2 = "fidl_offset_v2"
const tagHandleRights = "fidl_handle_rights"
const tagHandleSubtype = "fidl_handle_subtype"
const tagOrdinal = "fidl_ordinal"
const tagBounds = "fidl_bounds"
const tagMarshalerKind = "fidl"
const tagIsResource = "fidl_resource"

// 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 {
	typKindName := typ.Kind().String()
	if typName := typ.Name(); len(typName) != 0 {
		return typName + " (" + typKindName + ")"
	}
	return typKindName
}

// Extracts a list of fields for struct, union, table types that can be used
// for iterating.
// This skips the initial 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 := range fields {
		fields[i] = typ.Field(i + 1)
	}
	return fields
}

// Identifies the fields in a union that store unknown data, and that therefore
// do not need to have a field marshaler created
func isUnknownDataField(fieldName string) bool {
	return fieldName == "I_unknownData"
}

// 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 *mInt8, *mInt16, *mInt32, *mInt64, *mUint8, *mUint16, *mUint32, *mUint64:
		return true
	case *mEnumOfInt8, *mEnumOfInt16, *mEnumOfInt32, *mEnumOfInt64:
		// Need to validate.
		return false
	case *mEnumOfUint8, *mEnumOfUint16, *mEnumOfUint32, *mEnumOfUint64:
		// Need to validate.
		return false
	case *mBitsOfUint8, *mBitsOfUint16, *mBitsOfUint32, *mBitsOfUint64:
		// Need to validate.
		return false
	case *mFloat32:
		// Need to validate.
		return false
	case *mFloat64:
		// Need to validate.
		return false
	case *mArray:
		return matchesWireFormatLayout(marshaler.Marshaler, typ.Elem())
	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.useUnsafeCopy {
			return true
		}
		if marshaler.sizeV2 != int(typ.Size()) {
			return false
		}
		if marshaler.alignmentV2 != typ.Align() {
			return false
		}
		var endOfLast uintptr
		for i, rField := range dataFields(typ) {
			field := marshaler.fields[i]
			if field.offset != rField.Offset {
				return false
			}
			if endOfLast != field.offset {
				// There is padding.
				return false
			}
			if !matchesWireFormatLayout(field.Marshaler, rField.Type) {
				return false
			}
			endOfLast = field.offset + rField.Type.Size()
		}
		if endOfLast != typ.Size() {
			return false
		}
		return true
	case *mEmptyStruct:
		// Note: empty struct is 0 or 1 bytes at different times in go.
		return false
	case *mHandle, *mProtocol:
		// 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, *mOptVector, *mString, *mOptString, *mPointer:
		return false
	default:
		panic("unhandledType " + reflect.TypeOf(marshaler).Name() + " for " + typ.String())
	}
}

type creator struct {
	interns map[reflect.Type]Marshaler
}

func createMarshaler(typ reflect.Type) (Marshaler, error) {
	c := &creator{
		interns: map[reflect.Type]Marshaler{},
	}
	return c.createMarshalerForStruct(typ)
}

func (c *creator) createMarshalerForStruct(typ reflect.Type) (Marshaler, error) {
	if seen, ok := c.interns[typ]; ok {
		return seen, nil
	}

	// 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
		wireOffsetsV2   []int
		presenceOffsets []uintptr
	)

	df := dataFields(typ)
	var out Marshaler
	switch kind {
	case structTag:
		if len(df) == 0 {
			return &mEmptyStruct{}, nil
		}
		out = &mStruct{}
	case xunionTag, strictXunionTag:
		out = &mXUnion{}
	case tableTag:
		out = &mTable{}
	default:
		return nil, errors.New("unknown kind tag on " + nicefmt(typ))
	}
	c.interns[typ] = out

	// - 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 df {
		if (kind == xunionTag || kind == tableTag) && isUnknownDataField(field.Name) {
			continue
		}

		if kind == tableTag && index%2 == 0 {
			// Presence field
			if field.Type.Kind() != reflect.Bool {
				return nil, errors.New("incorrect presence field on " + nicefmt(typ))
			}
			presenceOffsets = append(presenceOffsets, field.Offset)
			continue
		}

		fieldBounds := readBoundsTag(field)
		handleRights, handleSubtype, err := readHandleRightsAndSubtype(field)
		if err != nil {
			return nil, err
		}
		switch kind {
		case structTag:
			offsetV2, err := readIntTag(field, tagOffsetV2)
			if err != nil {
				return nil, err
			}
			wireOffsetsV2 = append(wireOffsetsV2, offsetV2)
		case xunionTag, strictXunionTag, tableTag:
			ordinal := readOrdinalTag(field)
			ordinals = append(ordinals, uint64(ordinal))
		default:
		}
		fieldMarshaler, err := c.createMarshalerForField(field.Type, fieldBounds, handleRights, handleSubtype)
		if err != nil {
			return nil, err
		}
		fields = append(fields, mField{fieldMarshaler, field.Index[0], field.Offset})
	}

	sizeV2, err := readIntTag(tagField, tagSizeV2)
	if err != nil {
		return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
	}
	alignmentV2, err := readIntTag(tagField, tagAlignmentV2)
	if err != nil {
		return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
	}

	switch m := out.(type) {
	case *mStruct:
		var structFields []mFieldWithWireOffset
		for i := 0; i < len(fields); i++ {
			structFields = append(structFields, mFieldWithWireOffset{
				mField:       fields[i],
				wireOffsetV2: wireOffsetsV2[i],
			})
		}
		m.fields = structFields
		m.sizeV2 = sizeV2
		m.alignmentV2 = alignmentV2
		m.useUnsafeCopy = matchesWireFormatLayout(m, typ)
		if m.useUnsafeCopy {
			m.fields = nil
		}
		return m, nil
	case *mXUnion:
		strictness := strictness(kind == strictXunionTag)
		isResource, err := readBoolTag(tagField, tagIsResource)
		if err != nil {
			return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
		}

		ordinalToFields := make(map[uint64]mField)
		for i := 0; i < len(fields); i++ {
			ordinalToFields[ordinals[i]] = fields[i]
		}
		m.typ = typ
		m.fields = ordinalToFields
		m.ordinals = ordinals
		m.sizeV2 = sizeV2
		m.alignmentV2 = alignmentV2
		m.strictness = strictness
		m.resourceness = resourceness(isResource)
		return m, nil
	case *mTable:
		isResource, err := readBoolTag(tagField, tagIsResource)
		if err != nil {
			return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
		}

		m.fields = fields
		m.presenceOffsets = presenceOffsets
		m.size = sizeV2
		m.alignment = alignmentV2
		m.ordinals = ordinals
		m.resourceness = resourceness(isResource)
		return m, 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.ObjType, error) {
	if !containsHandleType(field.Type) {
		// Skip non-handle field types and don't return an error.
		return zx.RightSameRights, zx.ObjTypeNone, nil
	}

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

	// Read handle subtype
	val, ok = field.Tag.Lookup(tagHandleSubtype)
	if !ok {
		return zx.RightSameRights, zx.ObjTypeNone, ErrUnspecifiedHandleType
	}
	subtype, err := strconv.ParseInt(val, 0, 64)
	if err != nil {
		return zx.RightSameRights, zx.ObjTypeNone, err
	}
	convertedSubtype := zx.ObjType(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.Array || 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 readBoolTag(field reflect.StructField, tagKey string) (bool, error) {
	content, ok := field.Tag.Lookup(tagKey)
	if !ok {
		return false, errors.New(tagKey + " not found on field " + field.Name)
	}
	res, err := strconv.ParseBool(content)
	if err != nil {
		return false, errors.New("error parsing bool body from tag " + tagKey + " " + err.Error())
	}
	return res, nil
}

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 toInt8Map(values reflect.Value) map[int8]struct{} {
	m := make(map[int8]struct{})
	for i := 0; i < values.Len(); i++ {
		value := values.Index(i)
		m[int8(value.Int())] = struct{}{}
	}
	return m
}

func toInt16Map(values reflect.Value) map[int16]struct{} {
	m := make(map[int16]struct{})
	for i := 0; i < values.Len(); i++ {
		value := values.Index(i)
		m[int16(value.Int())] = struct{}{}
	}
	return m
}
func toInt32Map(values reflect.Value) map[int32]struct{} {
	m := make(map[int32]struct{})
	for i := 0; i < values.Len(); i++ {
		value := values.Index(i)
		m[int32(value.Int())] = struct{}{}
	}
	return m
}
func toInt64Map(values reflect.Value) map[int64]struct{} {
	m := make(map[int64]struct{})
	for i := 0; i < values.Len(); i++ {
		value := values.Index(i)
		m[int64(value.Int())] = struct{}{}
	}
	return m
}

func toUint8Map(values reflect.Value) map[uint8]struct{} {
	m := make(map[uint8]struct{})
	for i := 0; i < values.Len(); i++ {
		value := values.Index(i)
		m[uint8(value.Uint())] = struct{}{}
	}
	return m
}
func toUint16Map(values reflect.Value) map[uint16]struct{} {
	m := make(map[uint16]struct{})
	for i := 0; i < values.Len(); i++ {
		value := values.Index(i)
		m[uint16(value.Uint())] = struct{}{}
	}
	return m
}
func toUint32Map(values reflect.Value) map[uint32]struct{} {
	m := make(map[uint32]struct{})
	for i := 0; i < values.Len(); i++ {
		value := values.Index(i)
		m[uint32(value.Uint())] = struct{}{}
	}
	return m
}
func toUint64Map(values reflect.Value) map[uint64]struct{} {
	m := make(map[uint64]struct{})
	for i := 0; i < values.Len(); i++ {
		value := values.Index(i)
		m[uint64(value.Uint())] = struct{}{}
	}
	return m
}

func (c *creator) createMarshalerForField(typ reflect.Type, bounds bounds, handleRights zx.Rights, handleSubtype zx.ObjType) (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 &mProtocol{
			nullable: nullable != 0,
			rights:   ProtocolRights,
			subtype:  zx.ObjTypeChannel}, nil
	}

	if m, ok := typ.MethodByName("I_EnumValues"); ok {
		values := m.Func.Call([]reflect.Value{reflect.Zero(typ)})[0]
		var isStrict bool
		if m, ok := typ.MethodByName("I_EnumIsStrict"); ok {
			isStrict = m.Func.Call([]reflect.Value{reflect.Zero(typ)})[0].Interface().(bool)
		} else {
			return nil, errors.New("unable to create field marshaler for enum of " + nicefmt(typ) + ", missing I_EnumIsStrict method")
		}
		switch typ.Kind() {
		case reflect.Int8:
			return &mEnumOfInt8{
				isStrict: isStrict,
				values:   toInt8Map(values),
			}, nil
		case reflect.Int16:
			return &mEnumOfInt16{
				isStrict: isStrict,
				values:   toInt16Map(values),
			}, nil
		case reflect.Int32:
			return &mEnumOfInt32{
				isStrict: isStrict,
				values:   toInt32Map(values),
			}, nil
		case reflect.Int64:
			return &mEnumOfInt64{
				isStrict: isStrict,
				values:   toInt64Map(values),
			}, nil
		case reflect.Uint8:
			return &mEnumOfUint8{
				isStrict: isStrict,
				values:   toUint8Map(values),
			}, nil
		case reflect.Uint16:
			return &mEnumOfUint16{
				isStrict: isStrict,
				values:   toUint16Map(values),
			}, nil
		case reflect.Uint32:
			return &mEnumOfUint32{
				isStrict: isStrict,
				values:   toUint32Map(values),
			}, nil
		case reflect.Uint64:
			return &mEnumOfUint64{
				isStrict: isStrict,
				values:   toUint64Map(values),
			}, nil
		default:
			return nil, errors.New("unable to create field marshaler for enum of " + nicefmt(typ))
		}
	}

	if m, ok := typ.MethodByName("I_BitsMask"); ok {
		mask := m.Func.Call([]reflect.Value{reflect.Zero(typ)})[0]
		var isStrict bool
		if m, ok := typ.MethodByName("I_BitsIsStrict"); ok {
			isStrict = m.Func.Call([]reflect.Value{reflect.Zero(typ)})[0].Interface().(bool)
		} else {
			return nil, errors.New("unable to create field marshaler for bits of " + nicefmt(typ) + ", missing I_BitsIsStrict method")
		}
		switch typ.Kind() {
		case reflect.Uint8:
			return &mBitsOfUint8{
				isStrict: isStrict,
				mask:     uint8(mask.Uint()),
			}, nil
		case reflect.Uint16:
			return &mBitsOfUint16{
				isStrict: isStrict,
				mask:     uint16(mask.Uint()),
			}, nil
		case reflect.Uint32:
			return &mBitsOfUint32{
				isStrict: isStrict,
				mask:     uint32(mask.Uint()),
			}, nil
		case reflect.Uint64:
			return &mBitsOfUint64{
				isStrict: isStrict,
				mask:     uint64(mask.Uint()),
			}, nil
		default:
			return nil, errors.New("unable to create field marshaler for bits of " + nicefmt(typ))
		}
	}

	switch typ.Kind() {
	case reflect.Bool:
		return &mBool{}, nil
	case reflect.Int8:
		return &mInt8{}, nil
	case reflect.Int16:
		return &mInt16{}, nil
	case reflect.Int32:
		return &mInt32{}, nil
	case reflect.Int64:
		return &mInt64{}, nil
	case reflect.Uint8:
		return &mUint8{}, nil
	case reflect.Uint16:
		return &mUint16{}, nil
	case reflect.Uint32:
		return &mUint32{}, nil
	case reflect.Uint64:
		return &mUint64{}, nil
	case reflect.Float32:
		return &mFloat32{}, nil
	case reflect.Float64:
		return &mFloat64{}, nil
	case reflect.String:
		maxSize, _ := bounds.pop()
		s := mString(maxSize)
		return &s, nil
	case reflect.Array:
		elemMarshaler, err := c.createMarshalerForField(typ.Elem(), bounds, handleRights, handleSubtype)
		if err != nil {
			return nil, err
		}
		return &mArray{
			Marshaler:  elemMarshaler,
			size:       typ.Len(),
			rtElemSize: typ.Elem().Size(),
		}, nil
	case reflect.Slice:
		maxSize, remainder := bounds.pop()
		elemTyp := typ.Elem()
		elemMarshaler, err := c.createMarshalerForField(elemTyp, remainder, handleRights, handleSubtype)
		if err != nil {
			return nil, err
		}
		return &mVector{
			Marshaler:     elemMarshaler,
			maxSize:       maxSize,
			elemTyp:       elemTyp,
			useUnsafeCopy: matchesWireFormatLayout(elemMarshaler, elemTyp),
		}, nil
	case reflect.Struct:
		return c.createMarshalerForStruct(typ)
	case reflect.Ptr:
		return c.createOptMarshalerForField(typ.Elem(), bounds, handleRights, handleSubtype)
	default:
		return nil, errors.New("unable to create field marshaler for " + nicefmt(typ))
	}
}

func (c *creator) createOptMarshalerForField(typ reflect.Type, bounds bounds, handleRights zx.Rights, handleSubtype zx.ObjType) (Marshaler, error) {
	m, err := c.createMarshalerForField(typ, bounds, handleRights, handleSubtype)
	if err != nil {
		return nil, err
	}
	switch m := m.(type) {
	case *mString:
		o := mOptString(*m)
		return &o, nil
	case *mEmptyStruct:
		return &mPointer{
			Marshaler: m,
			elemTyp:   typ,
		}, nil
	case *mStruct:
		return &mPointer{
			Marshaler: m,
			elemTyp:   typ,
		}, nil
	case *mVector:
		return &mOptVector{
			mVector:  m,
			sliceTyp: 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 unsafevalue.Value, out *encoder, offset int, depth int) error
	unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error
}

// Assert various encoders implement the Marshaler interface.
var _ = []Marshaler{
	(*mString)(nil),
	(*mOptString)(nil),
	(*mBool)(nil),
	(*mInt8)(nil),
	(*mInt16)(nil),
	(*mInt32)(nil),
	(*mInt64)(nil),
	(*mUint8)(nil),
	(*mUint16)(nil),
	(*mUint32)(nil),
	(*mUint64)(nil),
	(*mFloat32)(nil),
	(*mFloat64)(nil),
	(*mEmptyStruct)(nil),
	(*mStruct)(nil),
	(*mXUnion)(nil),
	(*mOptXUnion)(nil),
	(*mTable)(nil),
	(*mPointer)(nil),
	(*mArray)(nil),
	(*mVector)(nil),
	(*mOptVector)(nil),
	(*mEnumOfInt8)(nil),
	(*mEnumOfInt16)(nil),
	(*mEnumOfInt32)(nil),
	(*mEnumOfInt64)(nil),
	(*mEnumOfUint8)(nil),
	(*mEnumOfUint16)(nil),
	(*mEnumOfUint32)(nil),
	(*mEnumOfUint64)(nil),
	(*mBitsOfUint8)(nil),
	(*mBitsOfUint16)(nil),
	(*mBitsOfUint32)(nil),
	(*mBitsOfUint64)(nil),
}

type mField struct {
	Marshaler
	index  int
	offset uintptr
}

type mFieldWithWireOffset struct {
	mField
	wireOffsetV2 int
}

type mStruct struct {
	fields              []mFieldWithWireOffset
	sizeV2, alignmentV2 int
	useUnsafeCopy       bool
}

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

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

func (m *mStruct) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.useUnsafeCopy {
		// Directly copy the object's memory to the buffer.
		sh := reflect.SliceHeader{
			Data: uintptr(unsafe.Pointer(v.UnsafeAddr())),
			Len:  m.sizeV2,
			Cap:  m.sizeV2,
		}
		s := *(*[]uint8)(unsafe.Pointer(&sh))
		copy(out.buffer[offset:], s)
		return nil
	}

	for _, field := range m.fields {
		fieldOffset := offset + field.wireOffsetV2
		if err := field.Marshaler.marshal(ctx, v.StructFieldOffset(field.offset), out, fieldOffset, depth); err != nil {
			return err
		}
	}
	return nil
}

func (m *mStruct) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	if m.useUnsafeCopy {
		size := m.getUnmarshalSize(ctx)
		// Directly copy from the buffer to the object's memory.
		if len(in.buffer) < offset+size {
			return ErrPayloadTooSmall
		}
		sh := reflect.SliceHeader{
			Data: uintptr(unsafe.Pointer(v.UnsafeAddr())),
			Len:  size,
			Cap:  size,
		}
		s := *(*[]uint8)(unsafe.Pointer(&sh))
		copy(s, in.buffer[offset:])
		return nil
	}

	endOfLastWire := 0
	for _, field := range m.fields {
		wireOffset := field.wireOffsetV2
		fieldOffset := offset + wireOffset
		for i := offset + endOfLastWire; i < fieldOffset; i++ {
			if in.buffer[i] != 0 {
				return newValueError(ErrNonZeroPadding, in.buffer[i])
			}
		}
		endOfLastWire = wireOffset + field.getUnmarshalSize(ctx)

		if err := field.Marshaler.unmarshal(ctx, in, fieldOffset, depth, v.StructFieldOffset(field.offset)); err != nil {
			return err
		}
	}
	for i := offset + endOfLastWire; i < offset+m.getUnmarshalSize(ctx); i++ {
		if in.buffer[i] != 0 {
			return newValueError(ErrNonZeroPadding, in.buffer[i])
		}
	}
	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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint8(offset, 0)
	return nil
}

func (_ *mEmptyStruct) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	if structByte := in.readUint8(offset); structByte != 0 {
		return newValueError(ErrInvalidEmptyStruct, structByte)
	}

	return nil
}

// closeHandles closes all the handles in the provided slice, ignoring any
// errors (best effort)
func closeHandles(handles []zx.HandleInfo) {
	for i := range handles {
		_ = handleClose(&handles[i].Handle)
	}
}

type mXUnion struct {
	typ                 reflect.Type
	fields              map[uint64]mField
	ordinals            []uint64
	sizeV2, alignmentV2 int
	strictness
	resourceness
}

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

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

func (m *mXUnion) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	var ordinal uint64
	ordinal = v.StructFieldOffset(0).Uint64()
	if ordinal == 0 {
		return newValueError(ErrInvalidXUnionTag, ordinal)
	}
	field, ok := m.fields[ordinal]
	out.writeUint64(offset, ordinal)
	if !ok {
		if m.strictness == isStrict {
			return newValueError(ErrInvalidXUnionTag, ordinal)
		}

		fld, fldOk := m.typ.FieldByName("I_unknownData")
		if !fldOk {
			return errorf("internal error (no unknown field found in flexible union to encode)")
		}
		rawUnknownData := v.StructFieldOffset(fld.Offset).Interface()
		unknownData, ok := rawUnknownData.(UnknownData)
		if !ok {
			return errorf("internal error (unexpected union I_unknownData type {})", rawUnknownData)
		}
		if len(unknownData.Handles) > 0 && m.resourceness == isValueType {
			closeHandles(unknownData.Handles)
			return ErrValueTypeHandles
		}
		err := marshalEnvelopeUnknown(
			ctx,
			out,
			offset+8,
			depth,
			unknownData,
		)
		if err != nil {
			return err
		}
		return nil
	}

	// Field.
	if err := marshalEnvelopePresent(ctx, field, v.StructFieldOffset(field.offset), out, offset+8, depth); err != nil {
		return err
	}

	return nil
}

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

func (m *mXUnion) unmarshalWithOptSpecified(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.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 := in.readUint64(offset)

	// ordinal=0 indicates that there MUST be no envelope.
	if ordinal == 0 {
		h, err := unmarshalEnvelopeHeader(ctx, in, offset+8)
		if err != nil {
			return err
		}

		if !optAllowed && !h.isPresent(ctx) {
			return newValueError(ErrUnexpectedNullRef, ordinal)
		}
		if !optAllowed || h.isPresent(ctx) {
			return newValueError(ErrInvalidXUnionTag, ordinal)
		}

		return nil
	}

	// If we reach here, ordinal != 0.
	field, ok := m.fields[ordinal]
	if !ok {
		v.StructFieldOffset(0).SetUint64(ordinal)

		unknownDataItem, err := unmarshalEnvelopeUnknown(ctx, in, offset+8, depth)
		if err != nil {
			return err
		}
		if m.strictness == isStrict {
			closeHandles(unknownDataItem.Handles)
			return newValueError(ErrInvalidXUnionTag, ordinal)
		}
		if len(unknownDataItem.Handles) > 0 && m.resourceness == isValueType {
			closeHandles(unknownDataItem.Handles)
			return ErrValueTypeHandles
		}
		fld, ok := m.typ.FieldByName("I_unknownData")
		if !ok {
			return errorf("internal error (no unknown field found in flexible union to decode into)")
		}
		v.StructFieldOffset(fld.Offset).SetInterface(unknownDataItem)
		return nil
	}

	if optAllowed {
		v.PointerSetNew(m.typ)
		v = v.PointerElem()
	}

	ordinalOrFieldIndex := ordinal
	v.StructFieldOffset(0).SetUint64(ordinalOrFieldIndex)

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

	isPresent, err := unmarshalEnvelope(ctx, field.Marshaler, in, offset+8, depth, v.StructFieldOffset(field.offset), mode)
	if err != nil {
		return err
	}

	if !isPresent {
		v.PointerSetNil()
	}

	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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	if v.PointerIsNil() {
		out.writeUint64(offset, 0) // ordinal + padding
		marshalEnvelopeAbsent(ctx, out, offset+8)
		return nil
	} else {
		return m.mXUnion.marshal(ctx, v.PointerElem(), out, offset, depth)
	}
}

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

// This assumes that I_unknownData in tables is always the first non-zero
// sized member.
const unknownTableDataOffset = 0

type mTable struct {
	typ             reflect.Type
	fields          []mField
	presenceOffsets []uintptr
	ordinals        []uint64
	size, alignment int
	resourceness
}

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

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

func envelopeSize(ctx MarshalerContext) int {
	return 8
}

type envelopeState int

const (
	emptyEnvelope envelopeState = iota
	inlineEnvelope
	outOfLineEnvelope
)

type envelopeHeader struct {
	byteValue   []byte
	byteCount   uint32
	handleCount uint32
	state       envelopeState
}

func (h envelopeHeader) isPresent(ctx MarshalerContext) bool {
	return h.state != emptyEnvelope
}

func marshalEnvelopePresent(ctx MarshalerContext, m Marshaler, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	numHandleDispositions := len(out.handleDispositions)

	if m.getMarshalSize(ctx) <= 4 {
		if err := m.marshal(ctx, v, out, offset, depth+1); err != nil {
			return err
		}
		numHandleDispositions = len(out.handleDispositions) - numHandleDispositions
		out.writeUint16(offset+4, uint16(numHandleDispositions))
		out.writeUint16(offset+6, 1)
		return nil
	}

	numBytes := len(out.buffer)

	outOfLineOffset, err := out.newObject(m.getMarshalSize(ctx), depth)
	if err != nil {
		return err
	}

	if err := m.marshal(ctx, v, out, outOfLineOffset, depth+1); err != nil {
		return err
	}
	numHandleDispositions = len(out.handleDispositions) - numHandleDispositions
	numBytes = len(out.buffer) - numBytes

	out.writeUint32(offset, uint32(numBytes))
	out.writeUint16(offset+4, uint16(numHandleDispositions))
	out.writeUint16(offset+6, 0)
	return nil
}

func marshalEnvelopeAbsent(ctx MarshalerContext, out *encoder, offset int) {
	out.writeUint64(offset, 0) // zero envelope
}

func marshalEnvelopeUnknown(ctx MarshalerContext, out *encoder, offset int, depth int, unknownData UnknownData) error {
	for _, info := range unknownData.Handles {
		out.handleDispositions = append(out.handleDispositions, zx.HandleDisposition{
			Operation: zx.HandleOpMove,
			Handle:    info.Handle,
			Type:      info.Type,
			Rights:    info.Rights,
			Result:    zx.ErrOk,
		})
	}

	if len(unknownData.Bytes) <= 4 {
		copy(out.buffer[offset:], unknownData.Bytes)
		out.writeUint16(offset+4, uint16(len(unknownData.Handles)))
		out.writeUint16(offset+6, 1)
		return nil
	}

	outOfLineOffset, err := out.newObject(len(unknownData.Bytes), depth)
	if err != nil {
		return err
	}

	copy(out.buffer[outOfLineOffset:], unknownData.Bytes)

	out.writeUint32(offset, uint32(len(unknownData.Bytes)))
	out.writeUint16(offset+4, uint16(len(unknownData.Handles)))
	out.writeUint16(offset+6, 0)
	return nil
}

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(ctx MarshalerContext, in *decoder, offset int) (envelopeHeader, error) {
	var h envelopeHeader
	inlineIndicator := in.readUint16(offset + 6)
	switch inlineIndicator {
	case 1:
		h = envelopeHeader{
			byteValue:   in.buffer[offset : offset+4],
			handleCount: uint32(in.readUint16(offset + 4)),
			state:       inlineEnvelope,
		}
	case 0:
		h = envelopeHeader{
			byteCount:   in.readUint32(offset),
			handleCount: uint32(in.readUint16(offset + 4)),
		}
		if h.byteCount == 0 && h.handleCount == 0 {
			h.state = emptyEnvelope
		} else {
			h.state = outOfLineEnvelope
		}
		if h.byteCount%8 != 0 {
			return h, newValueError(ErrInvalidNumBytesInEnvelope, h.byteCount)
		}
	default:
		return h, newValueError(ErrBadInlineIndicatorEncoding, h)
	}
	return h, nil
}

func unmarshalEnvelopeUnknown(ctx MarshalerContext, in *decoder, offset int, depth int) (UnknownData, error) {
	header, err := unmarshalEnvelopeHeader(ctx, in, offset)
	if err != nil {
		return UnknownData{}, err
	}

	var unknownHandles []zx.HandleInfo
	if header.handleCount > uint32(len(in.handleInfos)) {
		return UnknownData{}, newValueError(ErrTooManyHandles, header)
	}
	if header.handleCount != 0 {
		// Slice the end off first; in Go, slicing the head is a more conservative
		// operation than slicing the tail because the tail is allowed to reach
		// into capacity, but the head may only use length. Slicing the head first
		// allows the compiler to elide bounds checks on all the subsequent code.
		//
		// Even slicing from zero incurs a bounds check, hence the above check.
		usedHandles := in.handleInfos[header.handleCount:]
		// The compiler's bounds check elimination is not smart enough to avoid
		// bounds checks in the loop body without this local variable.
		unknownHandles = in.handleInfos[:header.handleCount]
		in.handleInfos = usedHandles
	}

	if header.state == inlineEnvelope {
		unknownBytes := in.buffer[offset:][:4]
		return UnknownData{Bytes: unknownBytes, Handles: unknownHandles}, nil
	}

	start, err := in.newObject(int(header.byteCount), depth)
	if err != nil {
		return UnknownData{}, err
	}

	unknownBytes := in.buffer[start:][:header.byteCount]

	return UnknownData{Bytes: unknownBytes, Handles: unknownHandles}, nil
}

func unmarshalEnvelopeContent(ctx MarshalerContext, header envelopeHeader, m Marshaler, in *decoder, depth int, v unsafevalue.Value, mode unmarshalEnvelopeMode) (bool, error) {
	if header.state == inlineEnvelope {
		// Inline envelope.
		var innerDecoderHandleInfos []zx.HandleInfo
		if header.handleCount != 0 {
			if header.handleCount != 1 {
				return false, newValueError(ErrInvalidNumHandlesInEnvelope, header.handleCount)
			}
			if len(in.handleInfos) > 0 {
				innerDecoderHandleInfos = []zx.HandleInfo{in.handleInfos[0]}
				in.handleInfos = in.handleInfos[1:]
			}
		}
		for _, elem := range header.byteValue[m.getUnmarshalSize(ctx):] {
			if elem != 0 {
				return false, newValueError(ErrNonZeroPadding, elem)
			}
		}
		d := decoder{
			buffer:      header.byteValue,
			handleInfos: innerDecoderHandleInfos,
		}
		if err := m.unmarshal(ctx, &d, 0, depth+1, v); err != nil {
			return false, err
		}
		return true, nil
	}

	outOfLineOffset, err := in.newObject(m.getUnmarshalSize(ctx), depth)
	if err != nil {
		return false, err
	}

	if err := m.unmarshal(ctx, in, outOfLineOffset, depth+1, v); err != nil {
		return false, err
	}

	return true, nil
}

func unmarshalEnvelope(ctx MarshalerContext, m Marshaler, in *decoder, offset int, depth int, v unsafevalue.Value, mode unmarshalEnvelopeMode) (bool, error) {
	startingFrom := in.nextObject
	unclaimedHandles := uint32(len(in.handleInfos))
	header, err := unmarshalEnvelopeHeader(ctx, in, offset)
	if err != nil {
		return false, err
	}

	if m.getUnmarshalSize(ctx) > 4 && header.state == inlineEnvelope {
		return false, newExpectError(ErrInvalidInlineBitValueInEnvelope, header.state, outOfLineEnvelope)
	}
	if m.getUnmarshalSize(ctx) <= 4 && header.state == outOfLineEnvelope {
		return false, newExpectError(ErrInvalidInlineBitValueInEnvelope, header.state, inlineEnvelope)
	}

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

		return false, nil
	}

	success, err := unmarshalEnvelopeContent(ctx, header, m, in, depth, v, mode)
	if err != nil {
		return false, err
	}

	consumedHandles := unclaimedHandles - uint32(len(in.handleInfos))
	consumedBytes := in.nextObject - startingFrom
	if header.handleCount != consumedHandles {
		return false, newExpectError(ErrInvalidNumHandlesInEnvelope, header.handleCount, consumedHandles)
	}
	if header.byteCount != uint32(consumedBytes) {
		return false, newExpectError(ErrInvalidNumBytesInEnvelope, header.byteCount, consumedBytes)
	}
	return success, nil
}

// closeUnknownFieldHandles closes all of the handles in the provided map,
// ignoring any errors (best effort).
func closeUnknownFieldHandles(unknownFields map[uint64]UnknownData) {
	for _, data := range unknownFields {
		closeHandles(data.Handles)
	}
}

func (m *mTable) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	var (
		maxOrdinal   uint64
		numKnown     = len(m.ordinals)
		fieldPresent = make([]bool, numKnown)
		unknownData  map[uint64]UnknownData
	)

	rawUnknownData := v.StructFieldOffset(unknownTableDataOffset).Interface()
	if rawUnknownData != nil {
		var ok bool
		unknownData, ok = rawUnknownData.(map[uint64]UnknownData)
		if !ok {
			return errorf("internal error (unexpected table I_unknownData type {})", rawUnknownData)
		}
		// Determining max ordinal from unknown ordinals.
		for unknownOrdinal := range unknownData {
			if maxOrdinal < unknownOrdinal {
				maxOrdinal = unknownOrdinal
			}
		}
	}

	if m.resourceness == isValueType {
		for _, data := range unknownData {
			if len(data.Handles) > 0 {
				closeUnknownFieldHandles(unknownData)
				return ErrValueTypeHandles
			}
		}
	}

	// Determining max ordinal from known ordinals.
	for index := 0; index < numKnown; index++ {
		fieldPresent[index] = v.StructFieldOffset(m.presenceOffsets[index]).Bool()
		if fieldPresent[index] {
			if fieldOrdinal := m.ordinals[index]; maxOrdinal < fieldOrdinal {
				maxOrdinal = fieldOrdinal
			}
		}
	}

	// Vector of envelopes header.
	out.writeUint64(offset, maxOrdinal)
	out.writeUint64(offset+8, allocPresent)

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

	// Encode in the out-of-line object.
	outOfLineOffset, err := out.newObject(int(maxOrdinal)*envelopeSize(ctx), depth)
	if err != nil {
		return err
	}

	// Envelopes.
	var (
		ordinal uint64 = 1
		index          = 0
	)
	envelopeOffset := outOfLineOffset
	for ordinal <= maxOrdinal {
		fieldKnown := index < numKnown && ordinal == m.ordinals[index]
		if fieldKnown && fieldPresent[index] {
			if fieldPresent[index] {
				if err := marshalEnvelopePresent(ctx, m.fields[index], v.StructFieldOffset(m.fields[index].offset), out, envelopeOffset, depth+1); err != nil {
					return err
				}
			} else {
				// This else clause is redundant with the else clause in the top level if statement but
				// saves a map lookup in the common case (all fields are known)
				marshalEnvelopeAbsent(ctx, out, envelopeOffset)
			}
		} else if unknownField, ok := unknownData[ordinal]; ok {
			err := marshalEnvelopeUnknown(
				ctx,
				out,
				envelopeOffset,
				depth+1,
				unknownField,
			)
			if err != nil {
				return err
			}
		} else {
			marshalEnvelopeAbsent(ctx, out, envelopeOffset)
		}

		ordinal++
		envelopeOffset += 8
		if fieldKnown {
			index++
		}
	}

	return nil
}

func (m *mTable) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	mou := in.readUint64(offset)
	// The wire format requires vector counts to fit in uint32.
	if mou > uint64(^uint32(0)) {
		return newValueError(ErrUnexpectedOrdinal, v)
	}
	maxOrdinal := mou

	switch allocPtr := in.readUint64(offset + 8); 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              = 0
		unknownData map[uint64]UnknownData
	)
	outOfLineOffset, err := in.newObject(int(maxOrdinal)*envelopeSize(ctx), depth)
	if err != nil {
		return err
	}

	envelopeOffset := outOfLineOffset
	for ordinal <= maxOrdinal {
		fieldKnown := index < numKnown && ordinal == m.ordinals[index]
		if fieldKnown {
			if isPresent, err := unmarshalEnvelope(ctx, m.fields[index], in, envelopeOffset, depth+1, v.StructFieldOffset(m.fields[index].offset), knownMayBeAbsent); err != nil {
				return err
			} else if isPresent {
				v.StructFieldOffset(m.presenceOffsets[index]).SetBool(true)
			}
		} else {
			unknownDataItem, err := unmarshalEnvelopeUnknown(ctx, in, envelopeOffset, depth+1)
			if err != nil {
				return err
			}
			if len(unknownDataItem.Bytes) > 0 || len(unknownDataItem.Handles) > 0 {
				if unknownData == nil {
					unknownData = make(map[uint64]UnknownData)
					v.StructFieldOffset(unknownTableDataOffset).SetInterface(unknownData)
				}
				unknownData[ordinal] = unknownDataItem
			}
		}
		ordinal++
		envelopeOffset += envelopeSize(ctx)
		if fieldKnown {
			index++
		}
	}

	if m.resourceness == isValueType {
		for _, data := range unknownData {
			if len(data.Handles) > 0 {
				closeUnknownFieldHandles(unknownData)
				return ErrValueTypeHandles
			}
		}
	}
	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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	// Nil?
	if v.PointerIsNil() {
		out.writeUint64(offset, noAlloc)
		return nil
	}

	// Write out allocation marker.
	out.writeUint64(offset, allocPresent)

	// Set up the out-of-line space.
	outOfLineOffset, err := out.newObject(align(m.Marshaler.getMarshalSize(ctx), 8), depth)
	if err != nil {
		return err
	}

	// Marshal field.
	if err := m.Marshaler.marshal(ctx, v.PointerElem(), out, outOfLineOffset, depth+1); err != nil {
		return err
	}

	return nil
}

func (m *mPointer) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	// Nil?
	switch ptr := in.readUint64(offset); ptr {
	case noAlloc:
		v.PointerSetNil()
		return nil
	case allocPresent:
		// good
	default:
		return newValueError(ErrBadRefEncoding, v)
	}

	// Create the new struct.
	v.PointerSetNew(m.elemTyp)

	// Set up the out-of-line space and the head.
	outOfLineOffset, err := in.newObject(m.Marshaler.getUnmarshalSize(ctx), depth)
	if err != nil {
		return err
	}

	// Unmarshal field.
	if err := m.Marshaler.unmarshal(ctx, in, outOfLineOffset, depth+1, v.PointerElem()); err != nil {
		return err
	}

	return nil
}

type mArray struct {
	Marshaler
	rtElemSize uintptr
	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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	elemSize := m.Marshaler.getMarshalSize(ctx)
	for i, len := 0, m.size; i < len; i++ {
		if err := m.Marshaler.marshal(ctx, v.ArrayIndex(m.rtElemSize, i), out, offset+i*elemSize, depth); err != nil {
			return err
		}
	}
	return nil
}

func (m *mArray) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	elemSize := m.Marshaler.getUnmarshalSize(ctx)
	for i, len := 0, m.size; i < len; i++ {
		if err := m.Marshaler.unmarshal(ctx, in, offset+i*elemSize, depth, v.ArrayIndex(m.rtElemSize, i)); err != nil {
			return err
		}
	}
	return nil
}

type mVector struct {
	Marshaler
	maxSize       int
	elemTyp       reflect.Type
	useUnsafeCopy 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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	// Bounds check.
	vLen := v.SliceLen()
	if m.maxSize < vLen {
		return newExpectError(ErrVectorTooLong, m.maxSize, vLen)
	}

	// Vector header.
	out.writeUint64(offset, uint64(vLen))
	out.writeUint64(offset+8, allocPresent)

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

	// Encode in the out-of-line object.
	outOfLineOffset, err := out.newObject(vLen*m.Marshaler.getMarshalSize(ctx), depth)
	if err != nil {
		return err
	}

	// Marshal elements.
	wireElemSize := m.Marshaler.getMarshalSize(ctx)
	if m.useUnsafeCopy {
		var bytes []byte
		sh := (*reflect.SliceHeader)(unsafe.Pointer(&bytes))
		sh.Data = (*reflect.SliceHeader)(unsafe.Pointer(v.UnsafeAddr())).Data
		sh.Len = vLen * wireElemSize
		sh.Cap = vLen * wireElemSize
		copy(out.buffer[outOfLineOffset:], bytes)
	} else {
		elemTypSize := m.elemTyp.Size()
		for i := 0; i < vLen; i++ {
			if err := m.Marshaler.marshal(ctx, v.SliceIndex(elemTypSize, i), out, outOfLineOffset+i*wireElemSize, depth+1); err != nil {
				return err
			}
		}
	}

	return nil
}

func (m *mVector) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	size := in.readUint64(offset)
	ptr := in.readUint64(offset + 8)
	switch ptr {
	case noAlloc:
		return newValueError(ErrUnexpectedNullRef, v)
	case allocPresent:
		return m.unmarshalWithUncheckedSize(ctx, in, depth, v, int(size))
	default:
		return newValueError(ErrBadRefEncoding, v)
	}
}

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

	// Unmarshal in the out-of-line object.
	elemSize := m.Marshaler.getUnmarshalSize(ctx)
	outOfLineOffset, err := in.newObject(size*elemSize, depth)
	if err != nil {
		return err
	}

	// Unmarshal elements.
	if m.useUnsafeCopy {
		// Copy the data as bytes, then construct a slice header with the appropriate size
		// for the slice type (if it is not bytes).
		s := make([]byte, size*m.Marshaler.getUnmarshalSize(ctx))
		copy(s, in.buffer[outOfLineOffset:])
		sh := (*reflect.SliceHeader)(unsafe.Pointer(v.UnsafeAddr()))
		sh.Data = (*reflect.SliceHeader)(unsafe.Pointer(&s)).Data
		sh.Len = size
		sh.Cap = size
	} else {
		elemTypSize := m.elemTyp.Size()
		v.SliceSetMakeSlice(m.elemTyp, size, size)
		for i := 0; i < size; i++ {
			if err := m.Marshaler.unmarshal(ctx, in, outOfLineOffset+i*elemSize, depth+1, v.SliceIndex(elemTypSize, i)); err != nil {
				return err
			}
		}
	}

	return nil
}

type mOptVector struct {
	*mVector
	sliceTyp reflect.Type
}

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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	if v.PointerIsNil() {
		out.writeUint64(offset, 0)
		out.writeUint64(offset+8, noAlloc)
		return nil
	}

	return m.mVector.marshal(ctx, v.PointerElem(), out, offset, depth)
}

func (m *mOptVector) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	size := in.readUint64(offset)
	ptr := in.readUint64(offset + 8)
	switch ptr {
	case noAlloc:
		if size > 0 {
			return newValueError(ErrUnexpectedNullRef, ptr)
		}
		v.PointerSetNil()
		return nil
	case allocPresent:
		v.PointerSetNew(m.sliceTyp)
		return m.mVector.unmarshalWithUncheckedSize(ctx, in, depth, v.PointerElem(), 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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	if v.Bool() {
		out.writeUint8(offset, 1)
	} else {
		out.writeUint8(offset, 0)
	}
	return nil
}

func (m *mBool) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	b := in.readUint8(offset)
	switch b {
	case 0, 1:
		v.SetBool(b == 1)
		return nil
	default:
		return newValueError(ErrInvalidBoolValue, b)
	}
}

type mInt8 struct{}

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

func (m *mInt8) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint8(offset, uint8(v.Int8()))
	return nil
}

func (m *mInt8) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	v.SetInt8(int8(in.readUint8(offset)))
	return nil
}

type mInt16 struct{}

func (m *mInt16) getMarshalSize(ctx MarshalerContext) int {
	return 2
}
func (m *mInt16) getUnmarshalSize(ctx MarshalerContext) int {
	return 2
}

func (m *mInt16) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint16(offset, uint16(v.Int16()))
	return nil
}

func (m *mInt16) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	v.SetInt16(int16(in.readUint16(offset)))
	return nil
}

type mInt32 struct{}

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

func (m *mInt32) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint32(offset, uint32(v.Int32()))
	return nil
}

func (m *mInt32) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	v.SetInt32(int32(in.readUint32(offset)))
	return nil
}

type mInt64 struct{}

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

func (m *mInt64) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint64(offset, uint64(v.Int64()))
	return nil
}

func (m *mInt64) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	v.SetInt64(int64(in.readUint64(offset)))
	return nil
}

type mUint8 struct{}

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

func (m *mUint8) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint8(offset, v.Uint8())
	return nil
}

func (m *mUint8) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	v.SetUint8(in.readUint8(offset))
	return nil
}

type mUint16 struct{}

func (m *mUint16) getMarshalSize(ctx MarshalerContext) int {
	return 2
}
func (m *mUint16) getUnmarshalSize(ctx MarshalerContext) int {
	return 2
}

func (m *mUint16) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint16(offset, v.Uint16())
	return nil
}

func (m *mUint16) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	v.SetUint16(in.readUint16(offset))
	return nil
}

type mUint32 struct{}

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

func (m *mUint32) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint32(offset, v.Uint32())
	return nil
}

func (m *mUint32) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	v.SetUint32(in.readUint32(offset))
	return nil
}

type mUint64 struct{}

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

func (m *mUint64) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint64(offset, v.Uint64())
	return nil
}

func (m *mUint64) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	v.SetUint64(in.readUint64(offset))
	return nil
}

type mEnumOfInt8 struct {
	isStrict bool
	values   map[int8]struct{}
}

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

func (m *mEnumOfInt8) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if _, ok := m.values[v.Int8()]; !ok {
			return newValueError(ErrInvalidEnumValue, v.Int8())
		}
	}
	out.writeUint8(offset, uint8(v.Int8()))
	return nil
}

func (m *mEnumOfInt8) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := int8(in.readUint8(offset))
	if m.isStrict {
		if _, ok := m.values[i]; !ok {
			return newValueError(ErrInvalidEnumValue, i)
		}
	}
	v.SetInt8(i)
	return nil
}

type mEnumOfInt16 struct {
	isStrict bool
	values   map[int16]struct{}
}

func (m *mEnumOfInt16) getMarshalSize(ctx MarshalerContext) int {
	return 2
}
func (m *mEnumOfInt16) getUnmarshalSize(ctx MarshalerContext) int {
	return 2
}

func (m *mEnumOfInt16) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if _, ok := m.values[v.Int16()]; !ok {
			return newValueError(ErrInvalidEnumValue, v.Int16())
		}
	}
	out.writeUint16(offset, uint16(v.Int16()))
	return nil
}

func (m *mEnumOfInt16) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := int16(in.readUint16(offset))
	if m.isStrict {
		if _, ok := m.values[i]; !ok {
			return newValueError(ErrInvalidEnumValue, i)
		}
	}
	v.SetInt16(i)
	return nil
}

type mEnumOfInt32 struct {
	isStrict bool
	values   map[int32]struct{}
}

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

func (m *mEnumOfInt32) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if _, ok := m.values[v.Int32()]; !ok {
			return newValueError(ErrInvalidEnumValue, v.Int32())
		}
	}
	out.writeUint32(offset, uint32(v.Int32()))
	return nil
}

func (m *mEnumOfInt32) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := int32(in.readUint32(offset))
	if m.isStrict {
		if _, ok := m.values[i]; !ok {
			return newValueError(ErrInvalidEnumValue, i)
		}
	}
	v.SetInt32(i)
	return nil
}

type mEnumOfInt64 struct {
	isStrict bool
	values   map[int64]struct{}
}

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

func (m *mEnumOfInt64) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if _, ok := m.values[v.Int64()]; !ok {
			return newValueError(ErrInvalidEnumValue, v.Int64())
		}
	}
	out.writeUint64(offset, uint64(v.Int64()))
	return nil
}

func (m *mEnumOfInt64) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := int64(in.readUint64(offset))
	if m.isStrict {
		if _, ok := m.values[i]; !ok {
			return newValueError(ErrInvalidEnumValue, i)
		}
	}
	v.SetInt64(i)
	return nil
}

type mEnumOfUint8 struct {
	isStrict bool
	values   map[uint8]struct{}
}

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

func (m *mEnumOfUint8) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if _, ok := m.values[v.Uint8()]; !ok {
			return newValueError(ErrInvalidEnumValue, v.Uint8())
		}
	}
	out.writeUint8(offset, v.Uint8())
	return nil
}

func (m *mEnumOfUint8) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := in.readUint8(offset)
	if m.isStrict {
		if _, ok := m.values[i]; !ok {
			return newValueError(ErrInvalidEnumValue, i)
		}
	}
	v.SetUint8(i)
	return nil
}

type mEnumOfUint16 struct {
	isStrict bool
	values   map[uint16]struct{}
}

func (m *mEnumOfUint16) getMarshalSize(ctx MarshalerContext) int {
	return 2
}
func (m *mEnumOfUint16) getUnmarshalSize(ctx MarshalerContext) int {
	return 2
}

func (m *mEnumOfUint16) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if _, ok := m.values[v.Uint16()]; !ok {
			return newValueError(ErrInvalidEnumValue, v.Uint16())
		}
	}
	out.writeUint16(offset, v.Uint16())
	return nil
}

func (m *mEnumOfUint16) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := in.readUint16(offset)
	if m.isStrict {
		if _, ok := m.values[i]; !ok {
			return newValueError(ErrInvalidEnumValue, i)
		}
	}
	v.SetUint16(i)
	return nil
}

type mEnumOfUint32 struct {
	isStrict bool
	values   map[uint32]struct{}
}

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

func (m *mEnumOfUint32) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if _, ok := m.values[v.Uint32()]; !ok {
			return newValueError(ErrInvalidEnumValue, v.Uint32())
		}
	}
	out.writeUint32(offset, v.Uint32())
	return nil
}

func (m *mEnumOfUint32) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := in.readUint32(offset)
	if m.isStrict {
		if _, ok := m.values[i]; !ok {
			return newValueError(ErrInvalidEnumValue, i)
		}
	}
	v.SetUint32(i)
	return nil
}

type mEnumOfUint64 struct {
	isStrict bool
	values   map[uint64]struct{}
}

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

func (m *mEnumOfUint64) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if _, ok := m.values[v.Uint64()]; !ok {
			return newValueError(ErrInvalidEnumValue, v.Uint64())
		}
	}
	out.writeUint64(offset, v.Uint64())
	return nil
}

func (m *mEnumOfUint64) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := in.readUint64(offset)
	if m.isStrict {
		if _, ok := m.values[i]; !ok {
			return newValueError(ErrInvalidEnumValue, i)
		}
	}
	v.SetUint64(i)
	return nil
}

type mBitsOfUint8 struct {
	isStrict bool
	mask     uint8
}

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

func (m *mBitsOfUint8) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if (v.Uint8() & m.mask) != v.Uint8() {
			return newValueError(ErrInvalidBitsValue, v.Uint8())
		}
	}
	out.writeUint8(offset, v.Uint8())
	return nil
}

func (m *mBitsOfUint8) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := in.readUint8(offset)
	if m.isStrict {
		if (i & m.mask) != i {
			return newValueError(ErrInvalidBitsValue, i)
		}
	}
	v.SetUint8(i)
	return nil
}

type mBitsOfUint16 struct {
	isStrict bool
	mask     uint16
}

func (m *mBitsOfUint16) getMarshalSize(ctx MarshalerContext) int {
	return 2
}
func (m *mBitsOfUint16) getUnmarshalSize(ctx MarshalerContext) int {
	return 2
}

func (m *mBitsOfUint16) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if (v.Uint16() & m.mask) != v.Uint16() {
			return newValueError(ErrInvalidBitsValue, v.Uint16())
		}
	}
	out.writeUint16(offset, v.Uint16())
	return nil
}

func (m *mBitsOfUint16) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := in.readUint16(offset)
	if m.isStrict {
		if (i & m.mask) != i {
			return newValueError(ErrInvalidBitsValue, i)
		}
	}
	v.SetUint16(i)
	return nil
}

type mBitsOfUint32 struct {
	isStrict bool
	mask     uint32
}

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

func (m *mBitsOfUint32) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if (v.Uint32() & m.mask) != v.Uint32() {
			return newValueError(ErrInvalidBitsValue, v.Uint32())
		}
	}
	out.writeUint32(offset, v.Uint32())
	return nil
}

func (m *mBitsOfUint32) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := in.readUint32(offset)
	if m.isStrict {
		if (i & m.mask) != i {
			return newValueError(ErrInvalidBitsValue, i)
		}
	}
	v.SetUint32(i)
	return nil
}

type mBitsOfUint64 struct {
	isStrict bool
	mask     uint64
}

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

func (m *mBitsOfUint64) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	if m.isStrict {
		if (v.Uint64() & m.mask) != v.Uint64() {
			return newValueError(ErrInvalidBitsValue, v.Uint64())
		}
	}
	out.writeUint64(offset, v.Uint64())
	return nil
}

func (m *mBitsOfUint64) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	i := in.readUint64(offset)
	if m.isStrict {
		if (i & m.mask) != i {
			return newValueError(ErrInvalidBitsValue, i)
		}
	}
	v.SetUint64(i)
	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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint32(offset, math.Float32bits(v.Float32()))
	return nil
}

func (m *mFloat32) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	v.SetFloat32(math.Float32frombits(in.readUint32(offset)))
	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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	out.writeUint64(offset, math.Float64bits(v.Float64()))
	return nil
}

func (m *mFloat64) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	v.SetFloat64(math.Float64frombits(in.readUint64(offset)))
	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 unsafevalue.Value, out *encoder, offset int, depth int) 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.writeUint64(offset, uint64(length))
	out.writeUint64(offset+8, allocPresent)

	// Create a new out-of-line object and write bytes of the string.
	head, err := out.newObject(length, depth)
	if err != nil {
		return err
	}

	copy(out.buffer[head:], s)
	return nil
}

func (m *mString) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	size := in.readUint64(offset)
	ptr := in.readUint64(offset + 8)
	switch ptr {
	case noAlloc:
		return newValueError(ErrUnexpectedNullRef, "string")
	case allocPresent:
		return m.unmarshalWithUncheckedSize(in, depth, v, int(size))
	default:
		return newValueError(ErrBadRefEncoding, "string")
	}
}

func (m *mString) unmarshalWithUncheckedSize(in *decoder, depth int, v unsafevalue.Value, size int) error {
	if maxSize := int(*m); size < 0 || maxSize < size {
		return newExpectError(ErrStringTooLong, maxSize, size)
	}
	start, err := in.newObject(size, depth)
	if err != nil {
		return err
	}

	s := string(in.buffer[start:][:size])
	if !utf8.ValidString(s) {
		return newValueError(ErrStringNotUTF8, v)
	}
	v.SetString(s)
	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 unsafevalue.Value, out *encoder, offset int, depth int) error {
	if v.PointerIsNil() {
		out.writeUint64(offset, 0)
		out.writeUint64(offset+8, noAlloc)
		return nil
	}

	s := mString(*m)
	return (&s).marshal(ctx, v.PointerElem(), out, offset, depth)
}

var (
	typString = reflect.TypeOf("")
)

func (m *mOptString) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	size := in.readUint64(offset)
	ptr := in.readUint64(offset + 8)
	switch ptr {
	case noAlloc:
		if size > 0 {
			return newValueError(ErrUnexpectedNullRef, ptr)
		}
		v.PointerSetNil()
		return nil
	case allocPresent:
		v.PointerSetNew(typString)
		s := mString(*m)
		return (&s).unmarshalWithUncheckedSize(in, depth, v.PointerElem(), int(size))
	default:
		return newValueError(ErrBadRefEncoding, v)
	}
}

type mHandle struct {
	nullable bool
	rights   zx.Rights
	subtype  zx.ObjType
}

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 unsafevalue.Value, out *encoder, offset int, depth int) 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.Uint32())
	if raw == zx.HandleInvalid {
		if !m.isOpt() {
			return ErrUnexpectedNullRef
		}
		out.writeUint32(offset, noHandle)
		return nil
	}
	out.handleDispositions = append(out.handleDispositions, zx.HandleDisposition{
		Operation: zx.HandleOpMove,
		Handle:    raw,
		Type:      m.subtype,
		Rights:    m.rights,
		Result:    zx.ErrOk,
	})
	out.writeUint32(offset, handlePresent)
	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, offset int, depth int, v unsafevalue.Value) error {
	h := in.readUint32(offset)
	switch uint32(h) {
	case noHandle:
		if !m.isOpt() {
			return ErrUnexpectedNullRef
		}
		v.SetUint32(uint32(zx.HandleInvalid))
		return nil
	case handlePresent:
		if len(in.handleInfos) == 0 {
			return ErrNotEnoughHandles
		}
		handleInfo := in.handleInfos[0]
		in.handleInfos = in.handleInfos[1:]

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

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

		handle := handleInfo.Handle
		reducedRights := m.filterOutUnspecifiedRights(handleInfo.Rights)
		if handleInfo.Rights != reducedRights {
			var err error
			handle, err = handleReplace(handle, reducedRights)
			if err != nil {
				handleClose(&handleInfo.Handle)
				return newValueError(ErrUnableToReduceHandleRights, handle)
			}
		}

		v.SetUint32(uint32(handle))
		return nil
	default:
		return newValueError(ErrBadHandleEncoding, h)
	}
}

// mProtocol marshals FIDL protocols' client and server ends. A client end
// (a.k.a "a protocol") is represented by a `Proxy`, whose first field is a
// `zx.Channel`. Similarly, a server end (a.k.a. "a protocol request") is
// represented by an `InterfaceRequest` whose first field is a `zx.Channel`.
type mProtocol mHandle

func (m *mProtocol) asHandle() *mHandle {
	h := mHandle(*m)
	return &h
}

func (m *mProtocol) getMarshalSize(ctx MarshalerContext) int {
	return m.asHandle().getMarshalSize(ctx)
}
func (m *mProtocol) getUnmarshalSize(ctx MarshalerContext) int {
	return m.asHandle().getUnmarshalSize(ctx)
}

func (m *mProtocol) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	return m.asHandle().marshal(ctx, v.StructFieldOffset(0), out, offset, depth)
}

func (m *mProtocol) unmarshal(ctx MarshalerContext, in *decoder, offset int, depth int, v unsafevalue.Value) error {
	return m.asHandle().unmarshal(ctx, in, offset, depth, v.StructFieldOffset(0))
}
