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

// +build fuchsia

package fidl

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

type strictness bool

const (
	isFlexible strictness = false
	isStrict   strictness = true
)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

const tagKey = "fidl"
const tagSizeV1NoEE = "fidl_size_v1_no_ee"
const tagAlignmentV1NoEE = "fidl_alignment_v1_no_ee"

type tagKind int

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

type bounds []int

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

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

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

	sizeV1NoEE, err := readIntTag(tagField, tagSizeV1NoEE)
	if err != nil {
		return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
	}
	alignmentV1NoEE, err := readIntTag(tagField, tagAlignmentV1NoEE)
	if err != nil {
		return nil, errors.New("error creating marshaller for " + typ.String() + ": " + err.Error())
	}

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

		var structFields []mFieldWithOffset
		for i := 0; i < len(fields); i++ {
			structFields = append(structFields, mFieldWithOffset{
				mField: fields[i],
				offset: offsets[i],
			})
		}
		return mStruct{
			fields:          structFields,
			sizeOld:         sizeOld,
			alignmentOld:    alignmentOld,
			sizeV1NoEE:      sizeV1NoEE,
			alignmentV1NoEE: alignmentV1NoEE,
		}, nil
	case unionTag:
		return mUnion{
			fields:          fields,
			ordinals:        ordinals,
			sizeOld:         sizeOld,
			alignmentOld:    alignmentOld,
			sizeV1NoEE:      sizeV1NoEE,
			alignmentV1NoEE: alignmentV1NoEE,
		}, nil
	case xunionTag, strictXunionTag:
		strictness := strictness(kind == strictXunionTag)

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

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

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

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

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

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

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

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

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

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

type MarshalerContext struct {
	DecodeUnionsFromXUnionBytes bool
	EncodeUnionsAsXUnionBytes   bool
}

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

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

type mField struct {
	Marshaler
	index int
}

type mFieldWithOffset struct {
	mField
	offset int
}

type mStruct struct {
	fields                      []mFieldWithOffset
	sizeOld, alignmentOld       int
	sizeV1NoEE, alignmentV1NoEE int
}

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

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

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

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

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

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

type mEmptyStruct struct{}

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

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

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

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

	return nil
}

type mUnion struct {
	fields                      []mField
	ordinals                    []int
	sizeOld, alignmentOld       int
	sizeV1NoEE, alignmentV1NoEE int
}

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

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

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

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

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

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

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

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

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

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

	return nil
}

func (m mUnion) marshalAsXUnion(ctx MarshalerContext, v reflect.Value, out *encoder) error {
	// Ordinal.
	fieldTag := int(v.Field(0).Uint())
	ordinal, err := strconv.ParseInt(v.Type().Field(fieldTag).Tag.Get("fidl"), 0, 64)
	if err != nil {
		return errors.New("error parsing ordinal from tag: " + err.Error())
	}
	out.writeUint(uint64(ordinal), 8)
	// Field.
	field := m.fields[fieldTag-1]
	if err := marshalEnvelopePresent(ctx, field, v.Field(field.index), out); err != nil {
		return err
	}
	return nil
}

func (m mUnion) unmarshal(ctx MarshalerContext, in *decoder, v reflect.Value) error {
	if ctx.DecodeUnionsFromXUnionBytes {
		ordinalToFields := make(map[int]mField)
		for i := 0; i < len(m.fields); i++ {
			ordinalToFields[m.ordinals[i]] = m.fields[i]
		}
		// Just use the xunion unmarshaler because the layout of union and xunion
		// is the same in go.
		xunion := mXUnion{
			fields:          ordinalToFields,
			unionToXunion:   true,
			sizeV1NoEE:      m.sizeV1NoEE,
			alignmentV1NoEE: m.alignmentV1NoEE,
			strictness:      true,
		}
		return xunion.unmarshal(ctx, in, v)
	}

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

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

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

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

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

	return nil
}

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

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

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

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

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

	return nil
}

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

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

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

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

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

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

		return nil
	}

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

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

		v.Field(0).SetUint(ordinal)

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

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

		return nil
	}

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

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

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

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

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

	return nil
}

type mOptXUnion struct {
	mXUnion
	typ reflect.Type
}

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

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

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

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

type mTable struct {
	fields                      []mField
	ordinals                    []int
	sizeOld, alignmentOld       int
	sizeV1NoEE, alignmentV1NoEE int
}

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

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

const envelopeSize = 16

type envelopeHeader struct {
	byteCount   uint32
	handleCount uint32
	presence    uint64
}

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

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

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

type unmarshalEnvelopeMode int

const (
	_ unmarshalEnvelopeMode = iota

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

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

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

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

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

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

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

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

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

	return h, nil
}

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

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

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

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

	return unknownData, nil
}

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

	return true, nil
}

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

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

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

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

		return false, nil
	}

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

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

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

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

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

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

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

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

	return nil
}

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

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

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

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

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

	return nil
}

type mOptStructUnion struct {
	Marshaler
	elemTyp reflect.Type
}

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

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

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

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

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

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

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

	return nil
}

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

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

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

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

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

	return nil
}

type mArray struct {
	Marshaler
	size int
}

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

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

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

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

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

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

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

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

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

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

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

	return nil
}

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

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

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

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

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

	return nil
}

type mOptVector mVector

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

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

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

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

type mBool struct{}

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

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

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

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

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

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

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

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

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

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

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

type mFloat32 struct{}

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

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

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

type mFloat64 struct{}

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

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

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

type mString int

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

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

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

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

	return nil
}

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

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

type mOptString uint64

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

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

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

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

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

type mHandle bool

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

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

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

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

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

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

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

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