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

// Marshal marshals (or encodes) a message into the data and handles slices.
func MarshalWithContext(ctx MarshalerContext, message Message, data []byte, handleDispositions []zx.HandleDisposition) (int, int, error) {
	// By construction, we know that message is a pointer to a struct since
	// we only generate pointer receiver methods for top-level messages.
	// Should one implement the interface differently, and call into this
	// code, it would fail in an 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
}

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

// UnmarshalWithContext2 behaves identically to UnmarshalWithContext but takes a HandleInfo.
func UnmarshalWithContext2(ctx MarshalerContext, data []byte, handleInfos []zx.HandleInfo, message Message) (int, int, error) {
	// By construction, we know that message is a pointer to a struct since
	// we only generate pointer receiver methods for top-level messages.
	// Should one implement the interface differently, and call into this
	// code, it would fail in an 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
}

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

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

	return UnmarshalWithContext2(ctx, data, handleInfos, message)
}

const tagSizeV1 = "fidl_size_v1"
const tagSizeV2 = "fidl_size_v2"
const tagAlignmentV1 = "fidl_alignment_v1"
const tagAlignmentV2 = "fidl_alignment_v2"
const tagOffsetV1 = "fidl_offset_v1"
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.sizeV1 != int(typ.Size()) {
			return false
		}
		if marshaler.sizeV2 != int(typ.Size()) {
			return false
		}
		if marshaler.alignmentV1 != typ.Align() {
			return false
		}
		if marshaler.alignmentV2 != typ.Align() {
			return false
		}
		for i, rField := range dataFields(typ) {
			field := marshaler.fields[i]
			if field.offset != rField.Offset {
				return false
			}
			if !matchesWireFormatLayout(field.Marshaler, rField.Type) {
				return false
			}
		}
		return true
	case *mEmptyStruct:
		// Note: empty struct is 0 or 1 bytes at different times in go.
		return false
	case *mHandle, *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
		wireOffsetsV1   []int
		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:
			offsetV1, err := readIntTag(field, tagOffsetV1)
			if err != nil {
				return nil, err
			}
			wireOffsetsV1 = append(wireOffsetsV1, offsetV1)
			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})
	}

	sizeV1, err := readIntTag(tagField, tagSizeV1)
	if err != nil {
		return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
	}
	sizeV2, err := readIntTag(tagField, tagSizeV2)
	if err != nil {
		return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
	}
	alignmentV1, err := readIntTag(tagField, tagAlignmentV1)
	if err != nil {
		return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
	}
	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],
				wireOffsetV1: wireOffsetsV1[i],
				wireOffsetV2: wireOffsetsV2[i],
			})
		}
		m.fields = structFields
		m.sizeV1 = sizeV1
		m.sizeV2 = sizeV2
		m.alignmentV1 = alignmentV1
		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.sizeV1 = sizeV1
		m.sizeV2 = sizeV2
		m.alignmentV1 = alignmentV1
		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())
		}
		if sizeV1 != sizeV2 || alignmentV1 != alignmentV2 {
			panic("expected table size to be unchanged between v1 and v2")
		}

		m.fields = fields
		m.presenceOffsets = presenceOffsets
		m.size = sizeV1
		m.alignment = alignmentV1
		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.ObjectType, error) {
	if !containsHandleType(field.Type) {
		// Skip non-handle field types and don't return an error.
		return zx.RightSameRights, zx.ObjectTypeNone, nil
	}

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

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

	return convertedRights, convertedSubtype, nil
}

func containsHandleType(typ reflect.Type) bool {
	// Protocols and requests are technically handle types but their rights /
	// subtypes are handled elsewhere.
	if typ.ConvertibleTo(proxyType) || typ.ConvertibleTo(interfaceRequestType) {
		return false
	}
	if isHandleType(typ) {
		return true
	}
	if typ.Kind() == reflect.Slice || typ.Kind() == reflect.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.ObjectType) (Marshaler, error) {
	if isHandleType(typ) {
		nullable, _ := bounds.pop()
		return &mHandle{nullable: nullable != 0, rights: handleRights, subtype: handleSubtype}, nil
	}

	if typ.ConvertibleTo(proxyType) || typ.ConvertibleTo(interfaceRequestType) {
		nullable, _ := bounds.pop()
		return &mProtocol{
			nullable: nullable != 0,
			rights:   ProtocolRights,
			subtype:  zx.ObjectTypeChannel}, 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.ObjectType) (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
	wireOffsetV1 int
	wireOffsetV2 int
}

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

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

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

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.sizeV1,
			Cap:  m.sizeV1,
		}
		s := *(*[]uint8)(unsafe.Pointer(&sh))
		copy(out.buffer[offset:], s)
		return nil
	}

	for _, field := range m.fields {
		fieldOffset := offset + field.wireOffsetV1
		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
	}

	for _, field := range m.fields {
		fieldOffset := offset
		if ctx.isV2WireFormatDecodingEnabled() {
			fieldOffset += field.wireOffsetV2
		} else {
			fieldOffset += field.wireOffsetV1
		}
		if err := field.Marshaler.unmarshal(ctx, in, fieldOffset, depth, v.StructFieldOffset(field.offset)); err != nil {
			return err
		}
	}
	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
	sizeV1, sizeV2, alignmentV1, alignmentV2 int
	strictness
	resourceness
}

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

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

func (m *mXUnion) marshal(ctx MarshalerContext, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	var ordinal uint64
	ordinal = v.StructFieldOffset(0).Uint64()
	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(
			out,
			offset+8,
			depth,
			unknownData.Bytes,
			unknownData.Handles,
		)
		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 {
		if !optAllowed {
			return newValueError(ErrInvalidXUnionTag, ordinal)
		}

		h, err := unmarshalEnvelopeHeader(ctx, in, offset+8)
		if err != nil {
			return err
		}

		if 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)

		bytes, handles, err := unmarshalEnvelopeUnknown(ctx, in, offset+8, depth)
		if err != nil {
			return err
		}
		if m.strictness == isStrict {
			closeHandles(handles)
			return newValueError(ErrInvalidXUnionTag, ordinal)
		}
		if len(handles) > 0 && m.resourceness == isValueType {
			closeHandles(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(UnknownData{
			Bytes:   bytes,
			Handles: handles,
		})
		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(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 {
	if ctx.UseV2WireFormat {
		return 8
	}
	return 16
}

type envelopeHeader struct {
	byteValue   []byte
	byteCount   uint32
	handleCount uint32
	isInline    bool
}

func (h envelopeHeader) isPresent(ctx MarshalerContext) bool {
	if h.isInline {
		return true
	}
	return h.byteCount != 0 || h.handleCount != 0
}

func marshalEnvelopePresent(ctx MarshalerContext, m Marshaler, v unsafevalue.Value, out *encoder, offset int, depth int) error {
	numHandleDispositions := len(out.handleDispositions)
	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.writeUint32(offset+4, uint32(numHandleDispositions))
	out.writeUint64(offset+8, allocPresent)
	return nil
}

func marshalEnvelopeAbsent(out *encoder, offset int) {
	out.writeUint64(offset, 0) // both numBytes, and numHandleDispositions
	out.writeUint64(offset+8, noAlloc)
}

func marshalEnvelopeUnknown(out *encoder, offset int, depth int, unknownData []byte, unknownHandles []zx.HandleInfo) error {
	outOfLineOffset, err := out.newObject(len(unknownData), depth)
	if err != nil {
		return err
	}

	copy(out.buffer[outOfLineOffset:], unknownData)
	for _, info := range unknownHandles {
		out.handleDispositions = append(out.handleDispositions, zx.HandleDisposition{
			Operation: zx.HandleOpMove,
			Handle:    info.Handle,
			Type:      info.Type,
			Rights:    info.Rights,
			Result:    zx.ErrOk,
		})
	}
	out.writeUint32(offset, uint32(len(unknownData)))
	out.writeUint32(offset+4, uint32(len(unknownHandles)))
	out.writeUint64(offset+8, allocPresent)
	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
	if ctx.isV2WireFormatDecodingEnabled() {
		inlineIndicator := in.readUint16(offset + 6)
		switch inlineIndicator {
		case 1:
			h = envelopeHeader{
				byteValue:   in.buffer[offset : offset+4],
				handleCount: uint32(in.readUint16(offset + 4)),
				isInline:    true,
			}
		case 0:
			h = envelopeHeader{
				byteCount:   in.readUint32(offset),
				handleCount: uint32(in.readUint16(offset + 4)),
			}
		default:
			return h, newValueError(ErrBadInlineIndicatorEncoding, h)
		}

	} else {
		h = envelopeHeader{
			byteCount:   in.readUint32(offset),
			handleCount: in.readUint32(offset + 4),
		}
		presence := in.readUint64(offset + 8)
		switch presence {
		case allocPresent:
			if h.byteCount == 0 {
				return h, newValueError(ErrInvalidNumBytesInEnvelope, h.byteCount)
			}
		case noAlloc:
			if h.byteCount != 0 {
				return h, newValueError(ErrInvalidNumBytesInEnvelope, h.byteCount)
			}
			if h.handleCount != 0 {
				return h, newValueError(ErrInvalidNumHandlesInEnvelope, h.handleCount)
			}
		default:
			return h, newValueError(ErrBadRefEncoding, h)
		}
	}
	if h.byteCount%8 != 0 {
		return h, newValueError(ErrInvalidNumBytesInEnvelope, h.byteCount)
	}

	return h, nil
}

func unmarshalEnvelopeUnknown(ctx MarshalerContext, in *decoder, offset int, depth int) ([]byte, []zx.HandleInfo, error) {
	header, err := unmarshalEnvelopeHeader(ctx, in, offset)
	if err != nil {
		return nil, nil, err
	}

	var unknownHandles []zx.HandleInfo
	if header.handleCount > uint32(len(in.handleInfos)) {
		return nil, nil, 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.isInline {
		unknownData := in.buffer[offset:][:4]
		return unknownData, unknownHandles, nil
	}

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

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

	return unknownData, unknownHandles, nil
}

func unmarshalEnvelopeContent(ctx MarshalerContext, header envelopeHeader, m Marshaler, in *decoder, depth int, v unsafevalue.Value, mode unmarshalEnvelopeMode) (bool, error) {
	if ctx.isV2WireFormatDecodingEnabled() && header.isInline {
		// 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:]
			}
		}
		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
}

// TODO(fxbug.dev/81180) Validate inline size <= 4 if header has inline bit set.
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
	}

	shouldBeInlined := ctx.UseV2WireFormat && m.getUnmarshalSize(ctx) <= 4
	if header.isInline != shouldBeInlined {
		return false, newExpectError(ErrInvalidInlineBitValueInEnvelope, header.isInline, shouldBeInlined)
	}

	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(out, envelopeOffset)
			}
		} else if unknownField, ok := unknownData[ordinal]; ok {
			err := marshalEnvelopeUnknown(
				out,
				envelopeOffset,
				depth+1,
				unknownField.Bytes,
				unknownField.Handles,
			)
			if err != nil {
				return err
			}
		} else {
			marshalEnvelopeAbsent(out, envelopeOffset)
		}

		ordinal++
		envelopeOffset += 16
		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)
	// uints/ints are only guaranteed to be 32 bit longs.
	// we use maxOrdinal as an int, so we must make sure that it fits.
	if mou > uint64(^uint(0)) {
		return newValueError(ErrUnexpectedOrdinal, v)
	}
	maxOrdinal := mou

	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 {
			bytes, handles, err := unmarshalEnvelopeUnknown(ctx, in, envelopeOffset, depth+1)
			if err != nil {
				return err
			}
			if len(bytes) > 0 || len(handles) > 0 {
				if unknownData == nil {
					unknownData = make(map[uint64]UnknownData)
					v.StructFieldOffset(unknownTableDataOffset).SetInterface(unknownData)
				}
				unknownData[ordinal] = UnknownData{
					Bytes:   bytes,
					Handles: handles,
				}
			}
		}
		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:
		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:
		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.ObjectType
}

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

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

func (m *mHandle) marshal(ctx MarshalerContext, v 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 ErrUnexpectedNullHandle
		}
		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 ErrUnexpectedNullHandle
		}
		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.ObjectTypeNone && 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))
}
