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

//! Encoding contains functions and traits for FIDL2 encoding and decoding.

use crate::invoke_for_handle_types;
use {
    crate::handle::{Handle, HandleBased, MessageBuf},
    crate::{Error, Result},
    bitflags::bitflags,
    fuchsia_zircon_status as zx_status,
    static_assertions::{assert_not_impl_any, assert_obj_safe},
    std::{cell::RefCell, cmp, convert::TryFrom, mem, ptr, str, u32, u64},
};

thread_local!(static CODING_BUF: RefCell<MessageBuf> = RefCell::new(MessageBuf::new()));

const MIN_TLS_CODING_BUF_SIZE: usize = 512;

/// Acquire a mutable reference to the thread-local encoding buffers.
///
/// This function may not be called recursively.
pub fn with_tls_coding_bufs<R>(f: impl FnOnce(&mut Vec<u8>, &mut Vec<Handle>) -> R) -> R {
    CODING_BUF.with(|buf| {
        let mut buf = buf.borrow_mut();
        let (bytes, handles) = buf.split_mut();
        if bytes.capacity() == 0 {
            bytes.reserve(MIN_TLS_CODING_BUF_SIZE);
        }
        let res = f(bytes, handles);
        buf.clear();
        res
    })
}

/// Encodes the provided type into the thread-local encoding buffers.
///
/// This function may not be called recursively.
pub fn with_tls_encoded<T, E: From<Error>>(
    val: &mut impl Encodable,
    f: impl FnOnce(&mut Vec<u8>, &mut Vec<Handle>) -> std::result::Result<T, E>,
) -> std::result::Result<T, E> {
    with_tls_coding_bufs(|bytes, handles| {
        Encoder::encode(bytes, handles, val)?;
        f(bytes, handles)
    })
}

/// Resize a vector without zeroing added bytes.
///
/// The type `T` must be `Copy`. This is not enforced in the type signature
/// because it is used in generic contexts where verifying this requires looking
/// at control flow. See `decode_vector` for an example.
///
/// # Safety
///
/// This is unsafe when `new_len > old_len` because it leaves new elements at
/// indices `old_len..new_len` unintialized. The caller must overwrite all the
/// new elements before reading them. "Reading" includes any operation that
/// extends the vector, such as `push`, because this could reallocate the vector
/// and copy the uninitialized bytes.
///
/// FIDL conformance tests are used to validate that there are no uninitialized
/// bytes in the output across a range types and values.
unsafe fn resize_vec_no_zeroing<T>(buf: &mut Vec<T>, new_len: usize) {
    if new_len > buf.capacity() {
        buf.reserve(new_len - buf.len());
    }
    // Safety:
    // - `new_len` must be less than or equal to `capacity()`:
    //   The if-statement above guarantees this.
    // - The elements at `old_len..new_len` must be initialized:
    //   They are purposely left uninitialized, making this function unsafe.
    buf.set_len(new_len);
}

/// Rounds `x` up if necessary so that it is a multiple of `align`.
///
/// Requires `align` to be a (nonzero) power of two.
pub fn round_up_to_align(x: usize, align: usize) -> usize {
    debug_assert_ne!(align, 0);
    debug_assert_eq!(align & (align - 1), 0);
    // https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
    (x + align - 1) & !(align - 1)
}

/// Split off the first element from a mutable slice.
fn split_off_first_mut<'a, T>(slice: &mut &'a mut [T]) -> Result<&'a mut T> {
    split_off_front_mut(slice, 1).map(|res| &mut res[0])
}

/// Split of the first `n` mutable bytes from `slice`.
fn split_off_front_mut<'a, T>(slice: &mut &'a mut [T], n: usize) -> Result<&'a mut [T]> {
    if n > slice.len() {
        return Err(Error::OutOfRange);
    }
    let original = take_slice_mut(slice);
    let (head, tail) = original.split_at_mut(n);
    *slice = tail;
    Ok(head)
}

/// Empty out a mutable slice.
fn take_slice_mut<'a, T>(x: &mut &'a mut [T]) -> &'a mut [T] {
    mem::replace(x, &mut [])
}

#[doc(hidden)] // only exported for macro use
pub fn take_handle<T: HandleBased>(handle: &mut T) -> Handle {
    let invalid = T::from_handle(Handle::invalid());
    mem::replace(handle, invalid).into_handle()
}

/// The maximum recursion depth of encoding and decoding.
/// Each nested aggregate type (structs, unions, arrays, or vectors) counts as one step in the
/// recursion depth.
pub const MAX_RECURSION: usize = 32;

/// Indicates that an optional value is present.
pub const ALLOC_PRESENT_U64: u64 = u64::MAX;
/// Indicates that an optional value is present.
pub const ALLOC_PRESENT_U32: u32 = u32::MAX;
/// Indicates that an optional value is absent.
pub const ALLOC_ABSENT_U64: u64 = 0;
/// Indicates that an optional value is absent.
pub const ALLOC_ABSENT_U32: u32 = 0;

/// Special ordinal signifying an epitaph message.
pub const EPITAPH_ORDINAL: u64 = 0xffffffffffffffffu64;

/// The current wire format magic number
pub const MAGIC_NUMBER_INITIAL: u8 = 1;

/// Context for encoding and decoding.
///
/// This is currently empty. We keep it around to ease the implementation of
/// context-dependent behavior for future migrations.
///
/// WARNING: Do not construct this directly unless you know what you're doing.
/// FIDL uses `Context` to coordinate soft migrations, so improper uses of it
/// could result in ABI breakage.
#[derive(Clone, Copy, Debug)]
pub struct Context {}

impl Context {
    /// Returns the header flags to set when encoding with this context.
    fn header_flags(&self) -> HeaderFlags {
        HeaderFlags::UNIONS_USE_XUNION_FORMAT
    }
}

/// Encoding state
#[derive(Debug)]
pub struct Encoder<'a> {
    /// Buffer to write output data into.
    ///
    /// New chunks of out-of-line data should be appended to the end of the `Vec`.
    /// `buf` should be resized to be large enough for any new data *prior* to encoding the inline
    /// portion of that data.
    buf: &'a mut Vec<u8>,

    /// Buffer to write output handles into.
    handles: &'a mut Vec<Handle>,

    /// Encoding context.
    context: &'a Context,
}

/// The default context for encoding.
/// During migrations, this controls the default write path.
fn default_encode_context() -> Context {
    Context {}
}

impl<'a> Encoder<'a> {
    /// FIDL2-encodes `x` into the provided data and handle buffers.
    pub fn encode<T: Encodable + ?Sized>(
        buf: &'a mut Vec<u8>,
        handles: &'a mut Vec<Handle>,
        x: &mut T,
    ) -> Result<()> {
        let context = default_encode_context();
        Self::encode_with_context(&context, buf, handles, x)
    }

    /// FIDL2-encodes `x` into the provided data and handle buffers, using the
    /// specified encoding context.
    ///
    /// WARNING: Do not call this directly unless you know what you're doing.
    /// FIDL uses `Context` to coordinate soft migrations, so improper uses of
    /// this function could result in ABI breakage.
    pub fn encode_with_context<T: Encodable + ?Sized>(
        context: &Context,
        buf: &'a mut Vec<u8>,
        handles: &'a mut Vec<Handle>,
        x: &mut T,
    ) -> Result<()> {
        fn prepare_for_encoding<'a>(
            context: &'a Context,
            buf: &'a mut Vec<u8>,
            handles: &'a mut Vec<Handle>,
            ty_inline_size: usize,
        ) -> Encoder<'a> {
            let aligned_inline_size = round_up_to_align(ty_inline_size, 8);
            // Safety: The uninitialized elements are assigned in prepare_for_encoding and
            // x.encode.
            unsafe {
                resize_vec_no_zeroing(buf, aligned_inline_size);
            }
            handles.truncate(0);
            let mut encoder = Encoder { buf, handles, context };
            encoder.padding(ty_inline_size, aligned_inline_size - ty_inline_size);
            encoder
        }
        let mut encoder = prepare_for_encoding(context, buf, handles, x.inline_size(context));
        x.encode(&mut encoder, 0, 0)
    }

    /// Returns the inline alignment of an object of type `Target` for this encoder.
    pub fn inline_align_of<Target: Encodable>(&self) -> usize {
        <Target as Layout>::inline_align(&self.context)
    }

    /// Returns the inline size of the given object for this encoder.
    pub fn inline_size_of<Target: Encodable>(&self) -> usize {
        <Target as Layout>::inline_size(&self.context)
    }

    /// Extends buf by `len` bytes and calls the provided closure to write
    /// out-of-line data, with `offset` set to the start of the new region.
    pub fn write_out_of_line<F>(&mut self, len: usize, recursion_depth: usize, f: F) -> Result<()>
    where
        F: FnOnce(&mut Encoder<'_>, usize, usize) -> Result<()>,
    {
        let new_offset = self.buf.len();
        let new_depth = recursion_depth + 1;
        Self::check_recursion_depth(new_depth)?;
        let padded_len = round_up_to_align(len, 8);
        // Safety: The uninitialized elements are assigned in self.padding and f.
        unsafe {
            resize_vec_no_zeroing(self.buf, self.buf.len() + padded_len);
        }
        self.padding(new_offset + len, padded_len - len);
        f(self, new_offset, new_depth)
    }

    /// Validate that the recursion depth is within the limit.
    pub fn check_recursion_depth(recursion_depth: usize) -> Result<()> {
        if recursion_depth > MAX_RECURSION {
            return Err(Error::MaxRecursionDepth);
        }
        Ok(())
    }

    /// Append bytes to the very end (out-of-line) of the buffer.
    pub fn append_bytes(&mut self, bytes: &[u8]) {
        self.buf.extend_from_slice(bytes);
        let new_len = round_up_to_align(self.buf.len(), 8);
        self.buf.resize(new_len, 0);
    }

    /// Append handles to the buffer.
    pub fn append_handles(&mut self, handles: &mut [Handle]) {
        self.handles.reserve(handles.len());
        for handle in handles {
            self.handles.push(take_handle(handle));
        }
    }

    /// Returns the encoder's context.
    ///
    /// This is needed for accessing the context in macros during migrations.
    pub fn context(&self) -> &Context {
        self.context
    }

    /// Write padding at the specified offset.
    #[inline(always)]
    pub fn padding(&mut self, offset: usize, len: usize) {
        if len == 0 {
            return;
        }
        // In practice, this assertion should never fail because we ensure that
        // padding is within an already allocated block outside of this
        // function.
        assert!(offset + len <= self.buf.len());
        // Safety:
        // - The pointer is valid for this range, as tested by the assertion above.
        // - All u8 pointers are properly aligned.
        unsafe {
            std::ptr::write_bytes(self.buf.as_mut_ptr().offset(offset as isize), 0, len);
        }
    }
}

/// Decoding state
#[derive(Debug)]
pub struct Decoder<'a> {
    /// The out of line depth.
    depth: usize,

    /// The the next offset to read from in buf.
    offset: usize,

    /// The end of the current inline block in buf.
    end_block: usize,

    /// Next out of line block in buf.
    next_out_of_line: usize,

    /// Buffer from which to read data.
    buf: &'a [u8],

    /// Buffer from which to read handles.
    handles: &'a mut [Handle],

    /// Decoding context.
    context: &'a Context,
}

impl<'a> Decoder<'a> {
    /// FIDL2-decodes a value of type `T` from the provided data and handle
    /// buffers. Assumes the buffers came from inside a transaction message
    /// wrapped by `header`.
    pub fn decode_into<T: Decodable>(
        header: &TransactionHeader,
        buf: &'a [u8],
        handles: &'a mut [Handle],
        value: &mut T,
    ) -> Result<()> {
        Self::decode_with_context(&header.decoding_context(), buf, handles, value)
    }

    /// FIDL2-decodes a value of type `T` from the provided data and handle
    /// buffers, using the specified context.
    ///
    /// WARNING: Do not call this directly unless you know what you're doing.
    /// FIDL uses `Context` to coordinate soft migrations, so improper uses of
    /// this function could result in ABI breakage.
    pub fn decode_with_context<T: Decodable>(
        context: &Context,
        buf: &'a [u8],
        handles: &'a mut [Handle],
        value: &mut T,
    ) -> Result<()> {
        let inline_size = T::inline_size(context);
        let next_out_of_line = round_up_to_align(inline_size, 8);
        if next_out_of_line > buf.len() {
            return Err(Error::OutOfRange);
        }
        let mut decoder = Decoder {
            depth: 0,
            offset: 0,
            end_block: next_out_of_line,
            next_out_of_line: next_out_of_line,
            buf,
            handles,
            context,
        };
        value.decode(&mut decoder)?;
        debug_assert!(
            decoder.offset == inline_size,
            "Inline part of the buffer was not completely consumed. Most likely, this indicates a \
             bug in the FIDL decoders.\n\
             Offset: {}\n\
             Block end offset: {}\n\
             Buffer: {:X?}",
            decoder.offset,
            inline_size,
            decoder.buf,
        );

        // Put this in a non-polymorphic helper function to reduce binary bloat.
        fn post_decoding(decoder: &Decoder, next_out_of_line: usize) -> Result<()> {
            if decoder.next_out_of_line < decoder.buf.len() {
                return Err(Error::ExtraBytes);
            }
            if decoder.handles.len() != 0 {
                return Err(Error::ExtraHandles);
            }
            for i in decoder.offset..next_out_of_line {
                if decoder.buf[i] != 0 {
                    return Err(Error::NonZeroPadding {
                        padding_start: decoder.offset,
                        non_zero_pos: i,
                    });
                }
            }
            Ok(())
        }

        post_decoding(&decoder, next_out_of_line)
    }

    /// Returns the next offset for reading and increases `offset` by `len`.
    pub fn next_offset(&mut self, len: usize) -> usize {
        let cur_offset = self.offset;
        self.offset += len;
        cur_offset
    }

    /// Take the next handle from the `handles` list and shift the list down by one element.
    pub fn take_handle(&mut self) -> Result<Handle> {
        split_off_first_mut(&mut self.handles).map(take_handle)
    }

    /// Runs the provided closure inside an decoder modified
    /// to read out-of-line data.
    pub fn read_out_of_line<F, R>(&mut self, len: usize, f: F) -> Result<R>
    where
        F: FnOnce(&mut Decoder<'_>) -> Result<R>,
    {
        // Save current state.
        let old_offset = self.offset;
        let old_end_block = self.end_block;
        let old_next_out_of_line = self.next_out_of_line;

        // Compute offsets for out of line block.
        self.offset = self.next_out_of_line;
        self.next_out_of_line = self.next_out_of_line + round_up_to_align(len, 8);
        self.end_block = self.next_out_of_line;
        if self.next_out_of_line > self.buf.len() {
            return Err(Error::OutOfRange);
        }

        // Descend into block.
        self.depth += 1;
        if self.depth > MAX_RECURSION {
            return Err(Error::MaxRecursionDepth);
        }
        let res = f(self)?;
        self.depth -= 1;

        // Ensure all bytes are consumed.
        debug_assert!(
            self.offset == old_next_out_of_line + len,
            "Out of line block was not completely consumed. Most likely, this indicates a \
             bug in the FIDL decoders.\n\
             Offset: {}\n\
             Block end offset: {}\n\
             Buffer: {:X?}",
            self.offset,
            old_next_out_of_line + len,
            self.buf,
        );

        // Validate padding bytes at the end of the block.
        for i in self.offset..self.end_block {
            if self.buf[i] != 0 {
                return Err(Error::NonZeroPadding { padding_start: self.offset, non_zero_pos: i });
            }
        }

        // Restore saved state.
        self.offset = old_offset;
        self.end_block = old_end_block;

        // Return.
        Ok(res)
    }

    /// Whether or not the current section of inline bytes has been fully read.
    pub fn is_empty(&self) -> bool {
        self.offset >= self.end_block
    }

    /// The number of handles that have not yet been consumed.
    pub fn remaining_handles(&self) -> usize {
        self.handles.len()
    }

    /// A convenience method to skip over the specified number of zero bytes used for padding, also
    /// checking that all those bytes are in fact zeroes.
    pub fn skip_padding(&mut self, len: usize) -> Result<()> {
        if len == 0 {
            // Skip body (so it can be optimized out).
            return Ok(());
        }
        for i in self.offset..self.offset + len {
            if self.buf[i] != 0 {
                return Err(Error::NonZeroPadding { padding_start: self.offset, non_zero_pos: i });
            }
        }
        self.offset += len;
        Ok(())
    }

    /// Returns the inline alignment of an object of type `Target` for this decoder.
    pub fn inline_align_of<Target: Decodable>(&self) -> usize {
        Target::inline_align(&self.context)
    }

    /// Returns the inline size of an object of type `Target` for this decoder.
    pub fn inline_size_of<Target: Decodable>(&self) -> usize {
        Target::inline_size(&self.context)
    }

    /// Returns the decoder's context.
    ///
    /// This is needed for accessing the context in macros during migrations.
    pub fn context(&self) -> &Context {
        self.context
    }

    /// The position of the next out of line block and the end of the current
    /// blocks.
    pub fn next_out_of_line(&self) -> usize {
        self.next_out_of_line
    }

    /// The buffer holding the message to be decoded.
    pub fn buffer(&self) -> &[u8] {
        self.buf
    }
}

/// A trait for specifying the inline layout of an encoded object.
pub trait Layout {
    /// Returns the minimum required alignment of the inline portion of the
    /// encoded object. It must be a (nonzero) power of two.
    fn inline_align(context: &Context) -> usize
    where
        Self: Sized;

    /// Returns the size of the inline portion of the encoded object, including
    /// padding for the type's minimum alignment.
    fn inline_size(context: &Context) -> usize
    where
        Self: Sized;

    /// Returns `slice` viewed as bytes for types that support encoding and
    /// decoding by simple copy. For all other types, returns `None`.
    ///
    /// Simple copying only works for types when (1) the Rust data layout
    /// matches the FIDL wire format, and (2) no validation is required. This is
    /// the case for (arrays of) primitive integer types, because both FIDL and
    /// Rust (we assume) use little-endian byte order, two's complement integer
    /// representation, and arrays with no padding.
    ///
    /// For more information:
    /// https://doc.rust-lang.org/reference/type-layout.html#primitive-data-layout
    /// https://doc.rust-lang.org/reference/types/numeric.html
    fn slice_as_bytes(_slice: &mut [Self]) -> Option<&mut [u8]>
    where
        Self: Sized,
    {
        None
    }
}

/// An object-safe extension of the `Layout` trait.
///
/// This trait should not be implemented directly. Instead, types should
/// implement `Layout` and rely on the automatic implementation of this one.
///
/// The purpose of this trait is to provide access to inline size and alignment
/// values through `dyn Encodable` trait objects, including generic contexts
/// where they are allowed such as `T: Encodable + ?Sized`.
pub trait LayoutObject: Layout {
    /// See `Layout::inline_align`.
    fn inline_align(&self, context: &Context) -> usize;

    /// See `Layout::inline_size`.
    fn inline_size(&self, context: &Context) -> usize;
}

assert_obj_safe!(LayoutObject);

impl<T: Layout> LayoutObject for T {
    fn inline_align(&self, context: &Context) -> usize {
        <T as Layout>::inline_align(context)
    }

    fn inline_size(&self, context: &Context) -> usize {
        <T as Layout>::inline_size(context)
    }
}

/// A type which can be FIDL2-encoded into a buffer.
///
/// Often an `Encodable` type should also be `Decodable`, but this is not always
/// the case. For example, both `String` and `&str` are encodable, but `&str` is
/// not decodable since it does not own any memory to store the string.
///
/// This trait is object-safe, meaning it is possible to create `dyn Encodable`
/// trait objects. Using them instead of generic `T: Encodable` types can help
/// reduce binary bloat. However, they can only be encoded directly: there are
/// no implementations of `Encodable` for enclosing types such as
/// `Vec<&dyn Encodable>`, and similarly for references, arrays, tuples, etc.
pub trait Encodable: LayoutObject {
    /// Encode the object into the buffer. Any handles stored in the object are
    /// swapped for `Handle::INVALID`. Callers should ensure that `offset` is a
    /// multiple of `Layout::inline_align`, and that `encoder.buf` has room for
    /// writing `Layout::inline_size` bytes at `offset`.
    ///
    /// Implementations that encode out-of-line objects should pass
    /// `recursion_depth` to `Encoder::write_out_of_line`, or manually call
    /// `Encoder::check_recursion_depth(recursion_depth + 1)`.
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()>;
}

assert_obj_safe!(Encodable);

/// A type which can be FIDL2-decoded from a buffer.
///
/// This trait is not object-safe, since `new_empty` returns `Self`. This is not
/// really a problem: there are not many use cases for `dyn Decodable`.
pub trait Decodable: Layout {
    /// Creates a new value of this type with an "empty" representation.
    fn new_empty() -> Self;

    /// Decodes an object of this type from the provided buffer and list of handles.
    /// On success, returns `Self`, as well as the yet-unused tails of the data and handle buffers.
    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()>;
}

macro_rules! impl_layout {
    ($ty:ty, align: $align:expr, size: $size:expr) => {
        impl Layout for $ty {
            fn inline_size(_context: &Context) -> usize {
                $size
            }
            fn inline_align(_context: &Context) -> usize {
                $align
            }
        }
    };
}

macro_rules! impl_layout_forall_T {
    ($ty:ty, align: $align:expr, size: $size:expr) => {
        impl<T: Layout> Layout for $ty {
            fn inline_size(_context: &Context) -> usize {
                $size
            }
            fn inline_align(_context: &Context) -> usize {
                $align
            }
        }
    };
}

// Implements `Layout` for a primitive integer type, overriding `slice_as_bytes`
// to enable encoding and decoding by simple copy.
macro_rules! impl_layout_int {
    ($int_ty:ty) => {
        impl Layout for $int_ty {
            fn inline_size(_context: &Context) -> usize {
                mem::size_of::<$int_ty>()
            }

            fn inline_align(_context: &Context) -> usize {
                mem::size_of::<$int_ty>()
            }

            fn slice_as_bytes(slice: &mut [Self]) -> Option<&mut [u8]> {
                Some(zerocopy::AsBytes::as_bytes_mut(slice))
            }
        }
    };
}

// This macro implements Encodable and Decodable for primitive integer types T.
// It ensures that T, [T; N], and Vec<T> are encoded/decoded by simple copy (via
// impl_layout_int), and that &[T] is encoded by simple copy (via
// impl_slice_encoding_by_copy).
//
// Some background on why we have the &[T] implementation: the FIDL type
// vector<T> becomes &mut dyn ExactSizeIterator<Item = T> (borrowed) or Vec<T>
// (owned) for most types. The former is a poor fit for vectors of primitives:
// we cannot optimize encoding from an iterator. For this reason, vectors of
// primitives are special-cased in fidlgen to use &[T] as the borrowed type.
//
// Caveat: bool uses &mut dyn ExactSizeIterator<Item = bool> because it cannot
// be optimized. Floats f32 and f64, though they cannot be optimized either, use
// &[f32] and &[f64].
// TODO(fxb/54368): Resolve this inconsistency.
macro_rules! impl_codable_int { ($($int_ty:ty,)*) => { $(
    impl_layout_int!($int_ty);

    impl Encodable for $int_ty {
        fn encode(&mut self, encoder: &mut Encoder<'_>, offset: usize, _recursion_depth: usize) -> Result<()> {
            encoder.buf[offset..offset+mem::size_of::<Self>()].copy_from_slice(&self.to_le_bytes());
            Ok(())
        }
    }

    impl Decodable for $int_ty {
        fn new_empty() -> Self { 0 as $int_ty }
        fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
            const SIZE: usize = mem::size_of::<$int_ty>();
            let offset = decoder.next_offset(SIZE);
            match <[u8; SIZE]>::try_from(&decoder.buf[offset .. offset+SIZE]) {
                Ok(array) => {
                    *self = Self::from_le_bytes(array);
                    Ok(())
                }
                Err(_) => Err(Error::OutOfRange),
            }
        }
    }

    impl_slice_encoding_by_copy!($int_ty);
)* } }

// This is separate from impl_codable_int because floats will require validation
// in the future (FTP-055), so we can't encode/decode by simple copy.
macro_rules! impl_codable_float { ($($float_ty:ty,)*) => { $(
    impl Layout for $float_ty {
        fn inline_size(_context: &Context) -> usize { mem::size_of::<$float_ty>() }
        fn inline_align(_context: &Context) -> usize { mem::size_of::<$float_ty>() }
    }

    impl Encodable for $float_ty {
        fn encode(&mut self, encoder: &mut Encoder<'_>, offset: usize, _recursion_depth: usize) -> Result<()> {
            encoder.buf[offset..offset+mem::size_of::<Self>()].copy_from_slice(&self.to_le_bytes());
            Ok(())
        }
    }

    impl Decodable for $float_ty {
        fn new_empty() -> Self { 0 as $float_ty }
        fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
            const SIZE: usize = mem::size_of::<$float_ty>();
            let offset = decoder.next_offset(SIZE);
            match <[u8; SIZE]>::try_from(&decoder.buf[offset .. offset+SIZE]) {
                Ok(array) => {
                    *self = Self::from_le_bytes(array);
                    Ok(())
                }
                Err(_) => Err(Error::OutOfRange),
            }
        }
    }

    impl_slice_encoding_by_iter!($float_ty);
)* } }

// Common code used by impl_slice_encoding_by_{iter,copy}.
macro_rules! impl_slice_encoding_base {
    ($prim_ty:ty) => {
        impl Layout for &[$prim_ty] {
            fn inline_size(_context: &Context) -> usize {
                16
            }
            fn inline_align(_context: &Context) -> usize {
                8
            }
        }

        impl Layout for Option<&[$prim_ty]> {
            fn inline_size(_context: &Context) -> usize {
                16
            }
            fn inline_align(_context: &Context) -> usize {
                8
            }
        }

        impl Encodable for Option<&[$prim_ty]> {
            fn encode(
                &mut self,
                encoder: &mut Encoder<'_>,
                offset: usize,
                recursion_depth: usize,
            ) -> Result<()> {
                match self {
                    None => encode_absent_vector(encoder, offset, recursion_depth),
                    Some(slice) => slice.encode(encoder, offset, recursion_depth),
                }
            }
        }
    };
}

// Encodes &[T] as a FIDL vector by encoding items one at a time.
macro_rules! impl_slice_encoding_by_iter {
    ($prim_ty:ty) => {
        impl_slice_encoding_base!($prim_ty);

        impl Encodable for &[$prim_ty] {
            fn encode(
                &mut self,
                encoder: &mut Encoder<'_>,
                offset: usize,
                recursion_depth: usize,
            ) -> Result<()> {
                encode_vector_from_iter(
                    encoder,
                    offset,
                    recursion_depth,
                    Some(self.iter().copied()),
                )
            }
        }
    };
}

// Encodes &[T] as a FIDL vector by simple copy.
macro_rules! impl_slice_encoding_by_copy {
    ($prim_ty:ty) => {
        impl_slice_encoding_base!($prim_ty);

        impl Encodable for &[$prim_ty] {
            fn encode(
                &mut self,
                encoder: &mut Encoder<'_>,
                offset: usize,
                recursion_depth: usize,
            ) -> Result<()> {
                (self.len() as u64).encode(encoder, offset, recursion_depth)?;
                ALLOC_PRESENT_U64.encode(encoder, offset + 8, recursion_depth)?;
                Encoder::check_recursion_depth(recursion_depth + 1)?;
                if self.len() == 0 {
                    return Ok(());
                }
                // Encode by simple copy. See Layout::slice_as_bytes for more info.
                let bytes = zerocopy::AsBytes::as_bytes(*self);
                encoder.append_bytes(bytes);
                Ok(())
            }
        }
    };
}

impl_codable_int!(u16, u32, u64, i16, i32, i64,);
impl_codable_float!(f32, f64,);

impl_layout!(bool, align: 1, size: 1);

impl Encodable for bool {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        _recursion_depth: usize,
    ) -> Result<()> {
        encoder.buf[offset] = if *self { 1 } else { 0 };
        Ok(())
    }
}

impl Decodable for bool {
    fn new_empty() -> Self {
        false
    }
    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        let offset = decoder.next_offset(1);
        *self = match decoder.buf[offset] {
            0 => false,
            1 => true,
            _ => return Err(Error::Invalid),
        };
        Ok(())
    }
}

impl_layout_int!(u8);
impl_slice_encoding_by_copy!(u8);

impl Encodable for u8 {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        _recursion_depth: usize,
    ) -> Result<()> {
        encoder.buf[offset] = *self;
        Ok(())
    }
}

impl Decodable for u8 {
    fn new_empty() -> Self {
        0
    }

    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        let offset = decoder.next_offset(1);
        *self = decoder.buf[offset];
        Ok(())
    }
}

impl_layout_int!(i8);
impl_slice_encoding_by_copy!(i8);

impl Encodable for i8 {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        _recursion_depth: usize,
    ) -> Result<()> {
        encoder.buf[offset] = *self as u8;
        Ok(())
    }
}

impl Decodable for i8 {
    fn new_empty() -> Self {
        0
    }

    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        let offset = decoder.next_offset(1);
        *self = decoder.buf[offset] as i8;
        Ok(())
    }
}

/// Encodes `slice` as a FIDL array.
fn encode_array<T: Encodable>(
    slice: &mut [T],
    encoder: &mut Encoder<'_>,
    offset: usize,
    recursion_depth: usize,
) -> Result<()> {
    match T::slice_as_bytes(slice) {
        Some(bytes) => {
            // Encode by simple copy. See Layout::slice_as_bytes for more info.
            encoder.buf[offset..offset + bytes.len()].copy_from_slice(bytes);
        }
        None => {
            let stride = encoder.inline_size_of::<T>();
            for (i, item) in slice.iter_mut().enumerate() {
                item.encode(encoder, offset + i * stride, recursion_depth)?;
            }
        }
    }
    Ok(())
}

/// Decodes a FIDL array into `slice`.
fn decode_array<T: Decodable>(slice: &mut [T], decoder: &mut Decoder<'_>) -> Result<()> {
    match T::slice_as_bytes(slice) {
        Some(bytes) => {
            // Decode by simple copy. See Layout::slice_as_bytes for more info.
            let size = bytes.len();
            let offset = decoder.next_offset(size);
            bytes.copy_from_slice(&decoder.buf[offset..offset + size]);
        }
        None => {
            for item in slice {
                item.decode(decoder)?;
            }
        }
    }
    Ok(())
}

macro_rules! impl_codable_for_fixed_array { ($($len:expr,)*) => { $(
    impl<T: Layout> Layout for [T; $len] {
        fn inline_align(context: &Context) -> usize { T::inline_align(context) }
        fn inline_size(context: &Context) -> usize { T::inline_size(context) * $len }
    }

    impl<T: Encodable> Encodable for [T; $len] {
        fn encode(&mut self, encoder: &mut Encoder<'_>, offset: usize, recursion_depth: usize) -> Result<()> {
            encode_array(self, encoder, offset, recursion_depth)
        }
    }

    impl<T: Decodable> Decodable for [T; $len] {
        fn new_empty() -> Self {
            let mut arr = mem::MaybeUninit::<[T; $len]>::uninit();
            unsafe {
                let arr_ptr = arr.as_mut_ptr() as *mut T;
                for i in 0..$len {
                    ptr::write(arr_ptr.offset(i as isize), T::new_empty());
                }
                arr.assume_init()
            }
        }

        fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
            decode_array(self, decoder)
        }
    }
)* } }

// Unfortunately, we cannot be generic over the length of a fixed array
// even though its part of the type (this will hopefully be added in the
// future) so for now we implement encodable for only the first 33 fixed
// size array types.
#[rustfmt::skip]
impl_codable_for_fixed_array!( 0,  1,  2,  3,  4,  5,  6,  7,
                               8,  9, 10, 11, 12, 13, 14, 15,
                              16, 17, 18, 19, 20, 21, 22, 23,
                              24, 25, 26, 27, 28, 29, 30, 31,
                              32,);
// Hack for FIDL library fuchsia.sysmem
impl_codable_for_fixed_array!(64,);
// Hack for FIDL library fuchsia.net
impl_codable_for_fixed_array!(256,);

/// Encode an optional vector-like component.
pub fn encode_vector<T: Encodable>(
    encoder: &mut Encoder<'_>,
    offset: usize,
    recursion_depth: usize,
    slice_opt: Option<&mut [T]>,
) -> Result<()> {
    match slice_opt {
        None => encode_absent_vector(encoder, offset, recursion_depth),
        Some(slice) => {
            // Two u64: (len, present)
            (slice.len() as u64).encode(encoder, offset, recursion_depth)?;
            ALLOC_PRESENT_U64.encode(encoder, offset + 8, recursion_depth)?;
            if slice.len() == 0 {
                return Ok(());
            }
            let bytes_len = slice.len() * encoder.inline_size_of::<T>();
            encoder.write_out_of_line(
                bytes_len,
                recursion_depth,
                |encoder, offset, recursion_depth| {
                    encode_array(slice, encoder, offset, recursion_depth)
                },
            )
        }
    }
}

/// Encode an missing vector-like component.
pub fn encode_absent_vector(
    encoder: &mut Encoder<'_>,
    offset: usize,
    recursion_depth: usize,
) -> Result<()> {
    0u64.encode(encoder, offset, recursion_depth)?;
    ALLOC_ABSENT_U64.encode(encoder, offset + 8, recursion_depth)
}

/// Like `encode_vector`, but optimized for `&[u8]`.
fn encode_vector_from_bytes(
    encoder: &mut Encoder<'_>,
    offset: usize,
    recursion_depth: usize,
    slice_opt: Option<&[u8]>,
) -> Result<()> {
    match slice_opt {
        None => encode_absent_vector(encoder, offset, recursion_depth),
        Some(slice) => {
            // Two u64: (len, present)
            (slice.len() as u64).encode(encoder, offset, recursion_depth)?;
            ALLOC_PRESENT_U64.encode(encoder, offset + 8, recursion_depth)?;
            Encoder::check_recursion_depth(recursion_depth + 1)?;
            encoder.append_bytes(slice);
            Ok(())
        }
    }
}

/// Like `encode_vector`, but encodes from an iterator.
pub fn encode_vector_from_iter<Iter, T>(
    encoder: &mut Encoder<'_>,
    offset: usize,
    recursion_depth: usize,
    iter_opt: Option<Iter>,
) -> Result<()>
where
    Iter: ExactSizeIterator<Item = T>,
    T: Encodable,
{
    match iter_opt {
        None => encode_absent_vector(encoder, offset, recursion_depth),
        Some(iter) => {
            // Two u64: (len, present)
            (iter.len() as u64).encode(encoder, offset, recursion_depth)?;
            ALLOC_PRESENT_U64.encode(encoder, offset + 8, recursion_depth)?;
            if iter.len() == 0 {
                return Ok(());
            }
            let bytes_len = iter.len() * encoder.inline_size_of::<T>();
            encoder.write_out_of_line(
                bytes_len,
                recursion_depth,
                |encoder, offset, recursion_depth| {
                    let stride = encoder.inline_size_of::<T>();
                    for (i, mut item) in iter.enumerate() {
                        item.encode(encoder, offset + stride * i, recursion_depth)?;
                    }
                    Ok(())
                },
            )
        }
    }
}

/// Attempts to decode a string into `string`, returning a `bool`
/// indicating whether or not a string was present.
fn decode_string(decoder: &mut Decoder<'_>, string: &mut String) -> Result<bool> {
    let mut len: u64 = 0;
    len.decode(decoder)?;

    let mut present: u64 = 0;
    present.decode(decoder)?;

    match present {
        ALLOC_ABSENT_U64 => {
            return if len == 0 { Ok(false) } else { Err(Error::UnexpectedNullRef) }
        }
        ALLOC_PRESENT_U64 => {}
        _ => return Err(Error::Invalid),
    };
    let len = len as usize;
    decoder.read_out_of_line(len, |decoder| {
        let offset = decoder.next_offset(len);
        string.truncate(0);
        let bytes = &decoder.buf[offset..offset + len];
        string.push_str(str::from_utf8(bytes).map_err(|_| Error::Utf8Error)?);
        Ok(true)
    })
}

/// Attempts to decode a FIDL vector into `vec`, returning a `bool` indicating
/// whether the vector was present.
fn decode_vector<T: Decodable>(decoder: &mut Decoder<'_>, vec: &mut Vec<T>) -> Result<bool> {
    let mut len: u64 = 0;
    len.decode(decoder)?;

    let mut present: u64 = 0;
    present.decode(decoder)?;

    match present {
        ALLOC_ABSENT_U64 => {
            return if len == 0 { Ok(false) } else { Err(Error::UnexpectedNullRef) }
        }
        ALLOC_PRESENT_U64 => {}
        _ => return Err(Error::Invalid),
    }

    let len = len as usize;
    let bytes_len = len * decoder.inline_size_of::<T>();
    decoder.read_out_of_line(bytes_len, |decoder| {
        if T::slice_as_bytes(vec).is_some() {
            // Safety: The uninitalized elements are immediately written by
            // `decode_array`, which always succeeds in the simple copy case.
            unsafe {
                resize_vec_no_zeroing(vec, len);
            }
        } else {
            vec.resize_with(len, T::new_empty);
        }
        decode_array(vec, decoder)?;
        Ok(true)
    })
}

impl_layout!(&str, align: 8, size: 16);

impl Encodable for &str {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        encode_vector_from_bytes(encoder, offset, recursion_depth, Some(self.as_bytes()))
    }
}

impl_layout!(String, align: 8, size: 16);

impl Encodable for String {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        encode_vector_from_bytes(encoder, offset, recursion_depth, Some(self.as_bytes()))
    }
}

impl Decodable for String {
    fn new_empty() -> Self {
        String::new()
    }

    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        if decode_string(decoder, self)? {
            Ok(())
        } else {
            Err(Error::NotNullable)
        }
    }
}

impl_layout!(Option<&str>, align: 8, size: 16);

impl Encodable for Option<&str> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        encode_vector_from_bytes(
            encoder,
            offset,
            recursion_depth,
            self.as_ref().map(|x| x.as_bytes()),
        )
    }
}

impl_layout!(Option<String>, align: 8, size: 16);

impl Encodable for Option<String> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        encode_vector_from_bytes(
            encoder,
            offset,
            recursion_depth,
            self.as_ref().map(|x| x.as_bytes()),
        )
    }
}

impl Decodable for Option<String> {
    fn new_empty() -> Self {
        None
    }

    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        let was_some;
        {
            let string = self.get_or_insert(String::new());
            was_some = decode_string(decoder, string)?;
        }
        if !was_some {
            *self = None
        }
        Ok(())
    }
}

impl_layout_forall_T!(&mut dyn ExactSizeIterator<Item = T>, align: 8, size: 16);

impl<T: Encodable> Encodable for &mut dyn ExactSizeIterator<Item = T> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        encode_vector_from_iter(encoder, offset, recursion_depth, Some(self))
    }
}

impl_layout_forall_T!(Vec<T>, align: 8, size: 16);

impl<T: Encodable> Encodable for Vec<T> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        encode_vector(encoder, offset, recursion_depth, Some(self))
    }
}

impl<T: Decodable> Decodable for Vec<T> {
    fn new_empty() -> Self {
        Vec::new()
    }

    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        if decode_vector(decoder, self)? {
            Ok(())
        } else {
            Err(Error::NotNullable)
        }
    }
}

impl_layout_forall_T!(Option<&mut dyn ExactSizeIterator<Item = T>>, align: 8, size: 16);

impl<T: Encodable> Encodable for Option<&mut dyn ExactSizeIterator<Item = T>> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        encode_vector_from_iter(encoder, offset, recursion_depth, self.as_mut().map(|x| &mut **x))
    }
}

impl_layout_forall_T!(Option<Vec<T>>, align: 8, size: 16);

impl<T: Encodable> Encodable for Option<Vec<T>> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        encode_vector(encoder, offset, recursion_depth, self.as_deref_mut())
    }
}

impl<T: Decodable> Decodable for Option<Vec<T>> {
    fn new_empty() -> Self {
        None
    }

    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        let was_some;
        {
            let vec = self.get_or_insert(Vec::new());
            was_some = decode_vector(decoder, vec)?;
        }
        if !was_some {
            *self = None
        }
        Ok(())
    }
}

/// An shorthand macro for calling `Encodable::encode()` from generated code
/// with full parameters, without importing the `Encodable` trait.
/// This is intended to be used only by generated code.
#[doc(hidden)]
#[macro_export]
macro_rules! fidl_encode {
    ($val:expr, $encoder:expr, $offset:expr, $recursion_depth:expr) => {
        $crate::encoding::Encodable::encode($val, $encoder, $offset, $recursion_depth)
    };
}

/// A shorthand macro for calling `Decodable::decode()` on a type
/// without importing the `Decodable` trait.
/// This is intended to be used only by generated code.
#[doc(hidden)]
#[macro_export]
macro_rules! fidl_decode {
    ($val:expr, $decoder:expr) => {
        $crate::encoding::Decodable::decode($val, $decoder)
    };
}

/// A shorthand macro for calling `Decodable::new_empty()` on a type
/// without importing the `Decodable` trait.
#[macro_export]
macro_rules! fidl_new_empty {
    ($type:ty) => {
        <$type as $crate::encoding::Decodable>::new_empty()
    };
}

/// Declare a bits type and implement the FIDL coding traits for it.
///
/// Example:
///
/// ```rust
/// fidl_bits!(MyBits (u32) { BAR = 5, BAZ = 6, });
///
/// // expands to:
///
///  bitflags! {
///    struct MyBits: u32 {
///      const BAR = 5;
///      const BAZ = 6;
///    }
///  }
///
///  impl Encodable for MyBits { ... }
///  impl Decodable for MyBits { ... }
/// ```
#[macro_export]
macro_rules! fidl_bits {
    ($name:ident ($prim_ty:ident) { $($key:ident = $value:expr,)* }) => {
        $crate::bitflags! {
            pub struct $name: $prim_ty {
                $(
                    const $key = $value;
                )*
            }
        }

        impl $crate::encoding::Layout for $name {
            fn inline_align(context: &$crate::encoding::Context) -> usize {
                <$prim_ty as $crate::encoding::Layout>::inline_align(context)
            }

            fn inline_size(context: &$crate::encoding::Context) -> usize {
                <$prim_ty as $crate::encoding::Layout>::inline_size(context)
            }
        }

        impl $crate::encoding::Encodable for $name {
            fn encode(&mut self, encoder: &mut $crate::encoding::Encoder<'_>, offset: usize, recursion_depth: usize)
                -> ::std::result::Result<(), $crate::Error>
            {
                $crate::fidl_encode!(&mut self.bits, encoder, offset, recursion_depth)
            }
        }

        impl $crate::encoding::Decodable for $name {
            fn new_empty() -> Self {
                Self::empty()
            }

            fn decode(&mut self, decoder: &mut $crate::encoding::Decoder<'_>)
                -> ::std::result::Result<(), $crate::Error>
            {
                let mut prim = $crate::fidl_new_empty!($prim_ty);
                $crate::fidl_decode!(&mut prim, decoder)?;
                *self = Self::from_bits(prim).ok_or($crate::Error::Invalid)?;
                Ok(())
            }
        }
    }
}

/// Declare an enum type and implement the FIDL coding traits for it.
///
/// Example:
///
/// ```rust
/// fidl_enum!(MyEnum (u32) { BAR = 5, BAZ = 6, });
///
/// // expands to:
///
///  #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
///  #[repr($prim_ty)]
///  pub enum MyEnum {
///     BAR = 5,
///     BAZ = 6,
///  }
///
///  impl MyEnum {
///     pub fn from_primitive(prim: u32) -> Option<Self> { ... }
///     pub fn into_primitive(self) -> u32 { ... }
///  }
///
///  impl Encodable for MyEnum { ... }
///  impl Decodable for MyEnum { ... }
/// ```
#[macro_export]
macro_rules! fidl_enum {
    ($name:ident ($prim_ty:ident) { $($key:ident = $value:expr,)* }) => {
        #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
        #[repr($prim_ty)]
        pub enum $name {
            $(
                $key = $value,
            )*
        }

        impl $name {
            pub fn from_primitive(prim: $prim_ty) -> Option<Self> {
                match prim {
                    $(
                        $value => Some($name::$key),
                    )*
                    _ => None,
                }
            }

            pub fn into_primitive(self) -> $prim_ty {
                self as $prim_ty
            }
        }

        impl $crate::encoding::Layout for $name {
            fn inline_align(context: &$crate::encoding::Context) -> usize {
                <$prim_ty as $crate::encoding::Layout>::inline_align(context)
            }

            fn inline_size(context: &$crate::encoding::Context) -> usize {
                <$prim_ty as $crate::encoding::Layout>::inline_size(context)
            }
        }

        impl $crate::encoding::Encodable for $name {
            fn encode(&mut self, encoder: &mut $crate::encoding::Encoder<'_>, offset: usize, recursion_depth: usize)
                -> ::std::result::Result<(), $crate::Error>
            {
                $crate::fidl_encode!(&mut (*self as $prim_ty), encoder, offset, recursion_depth)
            }
        }

        impl $crate::encoding::Decodable for $name {
            fn new_empty() -> Self {
                // Returns the first declared variant
                #![allow(unreachable_code)]
                $(
                    return $name::$key;
                )*
                panic!("new_empty called on enum with no variants")
            }

            fn decode(&mut self, decoder: &mut $crate::encoding::Decoder<'_>)
                -> ::std::result::Result<(), $crate::Error>
            {
                let mut prim = $crate::fidl_new_empty!($prim_ty);
                $crate::fidl_decode!(&mut prim, decoder)?;
                *self = Self::from_primitive(prim).ok_or($crate::Error::Invalid)?;
                Ok(())
            }
        }
    }
}

impl_layout!(Handle, align: 4, size: 4);

impl Encodable for Handle {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        ALLOC_PRESENT_U32.encode(encoder, offset, recursion_depth)?;
        let handle = take_handle(self);
        encoder.handles.push(handle);
        Ok(())
    }
}

impl Decodable for Handle {
    fn new_empty() -> Self {
        Handle::invalid()
    }
    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        let mut present: u32 = 0;
        present.decode(decoder)?;
        match present {
            ALLOC_ABSENT_U32 => return Err(Error::NotNullable),
            ALLOC_PRESENT_U32 => {}
            _ => return Err(Error::Invalid),
        }
        *self = decoder.take_handle()?;
        Ok(())
    }
}

impl_layout!(Option<Handle>, align: 4, size: 4);

impl Encodable for Option<Handle> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        match self {
            Some(handle) => handle.encode(encoder, offset, recursion_depth),
            None => ALLOC_ABSENT_U32.encode(encoder, offset, recursion_depth),
        }
    }
}

impl Decodable for Option<Handle> {
    fn new_empty() -> Self {
        None
    }
    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        let mut present: u32 = 0;
        present.decode(decoder)?;
        match present {
            ALLOC_ABSENT_U32 => {
                *self = None;
                Ok(())
            }
            ALLOC_PRESENT_U32 => {
                *self = Some(decoder.take_handle()?);
                Ok(())
            }
            _ => Err(Error::Invalid),
        }
    }
}

/// A macro for implementing the `Encodable` and `Decodable` traits for a type
/// which implements the `fuchsia_zircon::HandleBased` trait.
// TODO(cramertj) replace when specialization is stable
#[macro_export]
macro_rules! handle_based_codable {
    ($($ty:ident$(:- <$($generic:ident,)*>)*, )*) => { $(
        impl<$($($generic,)*)*> $crate::encoding::Layout for $ty<$($($generic,)*)*> {
            fn inline_align(_context: &$crate::encoding::Context) -> usize { 4 }
            fn inline_size(_context: &$crate::encoding::Context) -> usize { 4 }
        }

        impl<$($($generic,)*)*> $crate::encoding::Encodable for $ty<$($($generic,)*)*> {
            fn encode(&mut self, encoder: &mut $crate::encoding::Encoder<'_>, offset: usize, recursion_depth: usize)
                -> $crate::Result<()>
            {
                let mut handle = $crate::encoding::take_handle(self);
                $crate::fidl_encode!(&mut handle, encoder, offset, recursion_depth)
            }
        }

        impl<$($($generic,)*)*> $crate::encoding::Decodable for $ty<$($($generic,)*)*> {
            fn new_empty() -> Self {
                <$ty<$($($generic,)*)*> as $crate::handle::HandleBased>::from_handle($crate::handle::Handle::invalid())
            }
            fn decode(&mut self, decoder: &mut $crate::encoding::Decoder<'_>)
                -> $crate::Result<()>
            {
                let mut handle = $crate::handle::Handle::invalid();
                $crate::fidl_decode!(&mut handle, decoder)?;
                *self = <$ty<$($($generic,)*)*> as $crate::handle::HandleBased>::from_handle(handle);
                Ok(())
            }
        }

        impl<$($($generic,)*)*> $crate::encoding::Layout for Option<$ty<$($($generic,)*)*>> {
            fn inline_align(_context: &$crate::encoding::Context) -> usize { 4 }
            fn inline_size(_context: &$crate::encoding::Context) -> usize { 4 }
        }

        impl<$($($generic,)*)*> $crate::encoding::Encodable for Option<$ty<$($($generic,)*)*>> {
            fn encode(&mut self, encoder: &mut $crate::encoding::Encoder<'_>, offset: usize, recursion_depth: usize)
                -> $crate::Result<()>
            {
                match self {
                    Some(handle) => $crate::fidl_encode!(handle, encoder, offset, recursion_depth),
                    None => $crate::fidl_encode!(&mut $crate::encoding::ALLOC_ABSENT_U32, encoder, offset, recursion_depth),
                }
            }
        }

        impl<$($($generic,)*)*> $crate::encoding::Decodable for Option<$ty<$($($generic,)*)*>> {
            fn new_empty() -> Self { None }
            fn decode(&mut self, decoder: &mut $crate::encoding::Decoder<'_>) -> $crate::Result<()> {
                let mut handle: Option<$crate::handle::Handle> = None;
                $crate::fidl_decode!(&mut handle, decoder)?;
                *self = handle.map(Into::into);
                Ok(())
            }
        }
    )* }
}

impl Layout for zx_status::Status {
    fn inline_size(_context: &Context) -> usize {
        mem::size_of::<zx_status::zx_status_t>()
    }
    fn inline_align(_context: &Context) -> usize {
        mem::size_of::<zx_status::zx_status_t>()
    }
}

impl Encodable for zx_status::Status {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        _recursion_depth: usize,
    ) -> Result<()> {
        type Raw = zx_status::zx_status_t;
        encoder.buf[offset..offset + mem::size_of::<Raw>()]
            .copy_from_slice(&self.into_raw().to_le_bytes());
        Ok(())
    }
}

impl Decodable for zx_status::Status {
    fn new_empty() -> Self {
        Self::from_raw(0)
    }
    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        type Raw = zx_status::zx_status_t;
        const SIZE: usize = mem::size_of::<Raw>();
        let offset = decoder.next_offset(SIZE);
        match <[u8; SIZE]>::try_from(&decoder.buf[offset..offset + SIZE]) {
            Ok(array) => {
                *self = Self::from_raw(Raw::from_le_bytes(array));
                Ok(())
            }
            Err(_) => Err(Error::OutOfRange),
        }
    }
}

/// The body of a FIDL Epitaph
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct EpitaphBody {
    /// The error status
    pub error: zx_status::Status,
}

impl Layout for EpitaphBody {
    fn inline_align(context: &Context) -> usize {
        <zx_status::Status as Layout>::inline_align(context)
    }
    fn inline_size(context: &Context) -> usize {
        <zx_status::Status as Layout>::inline_size(context)
    }
}

impl Encodable for EpitaphBody {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        self.error.encode(encoder, offset, recursion_depth)
    }
}

impl Decodable for EpitaphBody {
    fn new_empty() -> Self {
        Self { error: zx_status::Status::new_empty() }
    }
    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        self.error.decode(decoder)
    }
}

macro_rules! handle_encoding {
    ($x:tt, $availability:ident) => {
        type $x = crate::handle::$x;
        handle_based_codable![$x,];
    };
}
invoke_for_handle_types!(handle_encoding);

/// A trait that provides automatic support for nullable types.
///
/// Types that implement this trait will automatically receive `Encodable` and
/// `Decodable` implementations for `Option<Box<Self>>` (nullable owned type),
/// and `Encodable` for `Option<&mut Self>` (nullable borrowed type).
pub trait Autonull: Encodable + Decodable {
    /// Returns true if the type is naturally able to be nullable.
    ///
    /// Types that return true (e.g., xunions) encode `Some(x)` the same as `x`,
    /// and `None` as a full bout of inline zeros. Types that return false
    /// (e.g., structs) encode `Some(x)` as `ALLOC_PRESENT_U64` with an
    /// out-of-line payload, and `None` as `ALLOC_ABSENT_U64`.
    fn naturally_nullable(context: &Context) -> bool;
}

impl<T: Autonull> Layout for Option<&mut T> {
    fn inline_align(context: &Context) -> usize {
        if T::naturally_nullable(context) {
            <T as Layout>::inline_align(context)
        } else {
            8
        }
    }
    fn inline_size(context: &Context) -> usize {
        if T::naturally_nullable(context) {
            <T as Layout>::inline_size(context)
        } else {
            8
        }
    }
}

impl<T: Autonull> Encodable for Option<&mut T> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        if T::naturally_nullable(encoder.context) {
            match self {
                Some(x) => x.encode(encoder, offset, recursion_depth),
                None => {
                    // This is an empty xunion.
                    encoder.padding(offset, 24);
                    Ok(())
                }
            }
        } else {
            match self {
                Some(x) => {
                    ALLOC_PRESENT_U64.encode(encoder, offset, recursion_depth)?;
                    encoder.write_out_of_line(
                        encoder.inline_size_of::<T>(),
                        recursion_depth,
                        |encoder, offset, recursion_depth| {
                            x.encode(encoder, offset, recursion_depth)
                        },
                    )
                }
                None => ALLOC_ABSENT_U64.encode(encoder, offset, recursion_depth),
            }
        }
    }
}

impl<T: Autonull> Layout for Option<Box<T>> {
    fn inline_align(context: &Context) -> usize {
        <Option<&mut T> as Layout>::inline_align(context)
    }
    fn inline_size(context: &Context) -> usize {
        <Option<&mut T> as Layout>::inline_size(context)
    }
}

impl<T: Autonull> Encodable for Option<Box<T>> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        // Call Option<&mut T>'s encode method.
        self.as_deref_mut().encode(encoder, offset, recursion_depth)
    }
}

// Presence indicators always include at least one non-zero byte,
// while absence indicators should always be entirely zeros.
fn check_for_presence(decoder: &mut Decoder<'_>, inline_size: usize) -> Result<bool> {
    Ok(decoder.buf[decoder.offset..decoder.offset + inline_size].iter().any(|byte| *byte != 0))
}

impl<T: Autonull> Decodable for Option<Box<T>> {
    fn new_empty() -> Self {
        None
    }
    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        if T::naturally_nullable(decoder.context) {
            let inline_size = decoder.inline_size_of::<T>();
            let present = check_for_presence(decoder, inline_size)?;
            if present {
                self.get_or_insert_with(|| Box::new(T::new_empty())).decode(decoder)
            } else {
                *self = None;
                // Eat the full `inline_size` bytes including the
                // ALLOC_ABSENT that we only peeked at before
                decoder.skip_padding(inline_size)?;
                Ok(())
            }
        } else {
            let mut present: u64 = 0;
            present.decode(decoder)?;
            match present {
                ALLOC_PRESENT_U64 => decoder
                    .read_out_of_line(decoder.inline_size_of::<T>(), |decoder| {
                        self.get_or_insert_with(|| Box::new(T::new_empty())).decode(decoder)
                    }),
                ALLOC_ABSENT_U64 => {
                    *self = None;
                    Ok(())
                }
                _ => Err(Error::Invalid),
            }
        }
    }
}

/// A macro which implements the FIDL `Encodable` and `Decodable` traits
/// for an existing struct.
#[macro_export]
macro_rules! fidl_struct {
    (
        name: $name:ty,
        members: [$(
            $member_name:ident {
                ty: $member_ty:ty,
                offset_v1: $member_offset_v1:expr,
            },
        )*],
        size_v1: $size_v1:expr,
        align_v1: $align_v1:expr,
    ) => {
        impl $crate::encoding::Layout for $name {
            fn inline_align(_context: &$crate::encoding::Context) -> usize {
                $align_v1
            }

            fn inline_size(_context: &$crate::encoding::Context) -> usize {
                $size_v1
            }
        }

        impl $crate::encoding::Encodable for $name {
            fn encode(&mut self, encoder: &mut $crate::encoding::Encoder<'_>, offset: usize, recursion_depth: usize) -> $crate::Result<()> {
                let mut padding_start = 0;
                $(
                    encoder.padding(offset + padding_start, $member_offset_v1 - padding_start);
                    $crate::fidl_encode!(&mut self.$member_name, encoder, offset + $member_offset_v1, recursion_depth)?;
                    padding_start = $member_offset_v1 + encoder.inline_size_of::<$member_ty>();
                )*
                encoder.padding(offset + padding_start, encoder.inline_size_of::<Self>() - padding_start);
                Ok(())
            }
        }

        impl $crate::encoding::Decodable for $name {
            fn new_empty() -> Self {
                Self {
                    $(
                        $member_name: $crate::fidl_new_empty!($member_ty),
                    )*
                }
            }

            fn decode(&mut self, decoder: &mut $crate::encoding::Decoder<'_>) -> $crate::Result<()> {
                let mut cur_offset = 0;
                $(
                    // Skip to the start of the next field
                    let member_offset = $member_offset_v1;
                    decoder.skip_padding(member_offset - cur_offset)?;
                    cur_offset = member_offset;
                    $crate::fidl_decode!(&mut self.$member_name, decoder)?;
                    cur_offset += decoder.inline_size_of::<$member_ty>();
                )*
                // Skip to the end of the struct's size
                decoder.skip_padding(decoder.inline_size_of::<Self>() - cur_offset)?;
                Ok(())
            }
        }

        impl $crate::encoding::Autonull for $name {
            fn naturally_nullable(_context: &$crate::encoding::Context) -> bool {
                false
            }
        }
    }
}

/// A macro which implements the FIDL `Encodable` and `Decodable` traits
/// for an existing struct by doing a direct copy using zerocopy::AsBytes.
#[macro_export]
macro_rules! fidl_struct_copy {
    (
        name: $name:ty,
        members: [$(
            $member_name:ident {
                ty: $member_ty:ty,
                offset_v1: $member_offset_v1:expr,
            },
        )*],
        size_v1: $size_v1:expr,
        align_v1: $align_v1:expr,
    ) => {
        impl $crate::encoding::Layout for $name {
            fn inline_align(_context: &$crate::encoding::Context) -> usize {
                $align_v1
            }

            fn inline_size(_context: &$crate::encoding::Context) -> usize {
                $size_v1
            }
            
            fn slice_as_bytes(slice: &mut [Self]) -> Option<&mut [u8]> {
                Some(zerocopy::AsBytes::as_bytes_mut(slice))
            }
        }

        impl $crate::encoding::Encodable for $name {
            fn encode(&mut self, encoder: &mut $crate::encoding::Encoder<'_>, offset: usize, _recursion_depth: usize) -> $crate::Result<()> {
                let bytes = zerocopy::AsBytes::as_bytes(self);
                encoder.buf[offset..offset + bytes.len()].copy_from_slice(bytes);
                Ok(())
            }
        }

        impl $crate::encoding::Decodable for $name {
            fn new_empty() -> Self {
                Self {
                    $(
                        $member_name: $crate::fidl_new_empty!($member_ty),
                    )*
                }
            }

            fn decode(&mut self, decoder: &mut $crate::encoding::Decoder<'_>) -> $crate::Result<()> {
                let bytes: &mut [u8] = zerocopy::AsBytes::as_bytes_mut(self);
                let size = bytes.len();
                let offset = decoder.next_offset(size);
                bytes.copy_from_slice(&decoder.buf[offset..offset + size]);
                Ok(())
            }
        }

        impl $crate::encoding::Autonull for $name {
            fn naturally_nullable(_context: &$crate::encoding::Context) -> bool {
                false
            }
        }
    }
}

/// A macro which creates an empty struct and implements the FIDL `Encodable` and `Decodable`
/// traits for it.
#[macro_export]
macro_rules! fidl_empty_struct {
    ($(#[$attrs:meta])* $name:ident) => {
        $(#[$attrs])*
        #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
        pub struct $name;

        impl $crate::encoding::Layout for $name {
          fn inline_align(_context: &$crate::encoding::Context) -> usize { 1 }
          fn inline_size(_context: &$crate::encoding::Context) -> usize { 1 }
        }

        impl $crate::encoding::Encodable for $name {
          fn encode(&mut self, encoder: &mut $crate::encoding::Encoder<'_>, offset: usize, recursion_depth: usize) -> $crate::Result<()> {
              $crate::fidl_encode!(&mut 0u8, encoder, offset, recursion_depth)
          }
        }

        impl $crate::encoding::Decodable for $name {
          fn new_empty() -> Self { $name }
          fn decode(&mut self, decoder: &mut $crate::encoding::Decoder<'_>) -> $crate::Result<()> {
            let mut x = 0u8;
             $crate::fidl_decode!(&mut x, decoder)?;
            if x == 0 {
                 Ok(())
            } else {
                 Err($crate::Error::Invalid)
            }
          }
        }

        impl $crate::encoding::Autonull for $name {
            fn naturally_nullable(_context: &$crate::encoding::Context) -> bool {
                false
            }
        }
    }
}

/// Encode the provided value behind a FIDL "envelope".
pub fn encode_in_envelope(
    val: &mut Option<&mut dyn Encodable>,
    encoder: &mut Encoder<'_>,
    offset: usize,
    recursion_depth: usize,
) -> Result<()> {
    // u32 num_bytes
    // u32 num_handles
    // 64-bit presence indicator

    match val {
        Some(x) => {
            // Start at offset 8 because we write the first 8 bytes (number of bytes and number
            // number of handles, both u32) at the end.
            ALLOC_PRESENT_U64.encode(encoder, offset + 8, recursion_depth)?;
            let bytes_before = encoder.buf.len();
            let handles_before = encoder.handles.len();
            encoder.write_out_of_line(
                x.inline_size(encoder.context),
                recursion_depth,
                |e, offset, recursion_depth| x.encode(e, offset, recursion_depth),
            )?;
            let mut bytes_written = (encoder.buf.len() - bytes_before) as u32;
            let mut handles_written = (encoder.handles.len() - handles_before) as u32;
            bytes_written.encode(encoder, offset, recursion_depth)?;
            handles_written.encode(encoder, offset + 4, recursion_depth)?;
        }
        None => {
            0u32.encode(encoder, offset, recursion_depth)?; // num_bytes
            0u32.encode(encoder, offset + 4, recursion_depth)?; // num_handles
            ALLOC_ABSENT_U64.encode(encoder, offset + 8, recursion_depth)?;
        }
    }
    Ok(())
}

/// Decodes an unknown field in a table. If it is non-empty, also skips over the
/// unknown out-of-line payload.
pub fn decode_unknown_table_field(decoder: &mut Decoder<'_>) -> Result<()> {
    let mut num_bytes: u32 = 0;
    num_bytes.decode(decoder)?;
    let mut num_handles: u32 = 0;
    num_handles.decode(decoder)?;
    let mut present: u64 = 0;
    present.decode(decoder)?;

    match present {
        ALLOC_PRESENT_U64 => decoder.read_out_of_line(num_bytes as usize, |decoder| {
            decoder.next_offset(num_bytes as usize);
            for _ in 0..num_handles {
                decoder.take_handle()?;
            }
            Ok(())
        }),
        ALLOC_ABSENT_U64 => {
            if num_bytes != 0 {
                Err(Error::UnexpectedNullRef)
            } else {
                Ok(())
            }
        }
        _ => Err(Error::Invalid),
    }
}

/// A macro which implements the table empty constructor and the FIDL `Encodable` and `Decodable`
/// traits for an existing struct whose fields are all `Option`s and may or may not appear in the
/// wire-format representation.
#[macro_export]
macro_rules! fidl_table {
    (
        name: $name:ty,
        members: {$(
            // NOTE: members must be in order from lowest to highest ordinal
            $member_name:ident {
                ty: $member_ty:ty,
                ordinal: $ordinal:expr,
            },
        )*},
    ) => {
        impl $name {
            /// Generates an empty table, with every field set to `None`.
            pub fn empty() -> Self {
                Self {$(
                        $member_name: None,
                )*}
            }
        }

        impl $crate::encoding::Layout for $name {
            fn inline_align(_context: &$crate::encoding::Context) -> usize { 8 }
            fn inline_size(_context: &$crate::encoding::Context) -> usize { 16 }
        }

        impl $crate::encoding::Encodable for $name {
            fn encode(&mut self, encoder: &mut $crate::encoding::Encoder<'_>, offset: usize, recursion_depth: usize) -> $crate::Result<()> {
                let members: &mut [(u64, Option<&mut dyn $crate::encoding::Encodable>)] = &mut [$(
                    ($ordinal, self.$member_name.as_mut().map(|x| x as &mut dyn $crate::encoding::Encodable)),
                )*];

                // Cut off the `None` elements at the tail of the table
                let last_some_index = members.iter().rposition(|x| x.1.is_some());

                let members = if let Some(i) = last_some_index {
                    &mut members[..(i + 1)]
                } else {
                    &mut []
                };

                // Vector header
                let max_ordinal = members.last().map(|v| v.0).unwrap_or(0);
                (max_ordinal as u64).encode(encoder, offset, recursion_depth)?;
                $crate::encoding::ALLOC_PRESENT_U64.encode(encoder, offset + 8, recursion_depth)?;
                let bytes_len = (max_ordinal as usize) * 16;
                encoder.write_out_of_line(bytes_len, recursion_depth, |encoder, offset, recursion_depth| {
                    let mut prev_end_offset: usize = 0;
                    for (ref ordinal, encodable) in members.iter_mut() {
                        // Write at offset+(ordinal-1)*16, since ordinals are one-based and envelopes are 16 bytes.
                        let cur_offset = (*ordinal as usize - 1) * 16;

                        // Zero reserved fields.
                        encoder.padding(offset + prev_end_offset, cur_offset - prev_end_offset);

                        // Encode present field.
                        $crate::encoding::encode_in_envelope(encodable, encoder, offset + cur_offset, recursion_depth)?;

                        prev_end_offset = cur_offset + 16;
                    }
                    Ok(())
                })
            }
        }

        impl $crate::encoding::Decodable for $name {
            fn new_empty() -> Self {
                Self::empty()
            }
            fn decode(&mut self, decoder: &mut $crate::encoding::Decoder<'_>) -> $crate::Result<()> {
                // Decode envelope vector header
                let mut len: u64 = 0;
                $crate::fidl_decode!(&mut len, decoder)?;

                let mut present: u64 = 0;
                $crate::fidl_decode!(&mut present, decoder)?;

                if present != $crate::encoding::ALLOC_PRESENT_U64 {
                    return Err($crate::Error::Invalid);
                }

                let len = len as usize;
                let bytes_len = len * 16; // envelope inline_size is 16
                decoder.read_out_of_line(bytes_len, |decoder| {
                    // Decode the envelope for each type.
                    // u32 num_bytes
                    // u32_num_handles
                    // 64-bit presence indicator
                    let mut _next_ordinal_to_read = 0;
                    $(
                        _next_ordinal_to_read += 1;
                        if decoder.is_empty() {
                            // The remaining fields have been omitted, so set them to None
                            self.$member_name = None;
                        } else {
                            // Decode unknown envelopes for gaps in ordinals.
                            while _next_ordinal_to_read < $ordinal {
                                $crate::encoding::decode_unknown_table_field(decoder)?;
                                _next_ordinal_to_read += 1;
                            }
                            let mut num_bytes: u32 = 0;
                            $crate::fidl_decode!(&mut num_bytes, decoder)?;
                            let mut num_handles: u32 = 0;
                            $crate::fidl_decode!(&mut num_handles, decoder)?;
                            let mut present: u64 = 0;
                            $crate::fidl_decode!(&mut present, decoder)?;
                            let next_out_of_line = decoder.next_out_of_line();
                            let handles_before = decoder.remaining_handles();
                            match present {
                                $crate::encoding::ALLOC_PRESENT_U64 => {
                                    decoder.read_out_of_line(
                                        decoder.inline_size_of::<$member_ty>(),
                                        |d| {
                                            let val_ref =
                                               self.$member_name.get_or_insert_with(
                                                    || $crate::fidl_new_empty!($member_ty));
                                            $crate::fidl_decode!(val_ref, d)?;
                                            Ok(())
                                        },
                                    )?;
                                }
                                $crate::encoding::ALLOC_ABSENT_U64 => {
                                    if num_bytes != 0 {
                                        return Err($crate::Error::UnexpectedNullRef);
                                    }
                                    self.$member_name = None;
                                }
                                _ => return Err($crate::Error::Invalid),
                            }
                            if decoder.next_out_of_line() != (next_out_of_line + (num_bytes as usize)) {
                                return Err($crate::Error::Invalid);
                            }
                            if handles_before != (decoder.remaining_handles() + (num_handles as usize)) {
                                return Err($crate::Error::Invalid);
                            }
                        }
                    )*

                    // Decode the remaining unknown envelopes.
                    while !decoder.is_empty() {
                        $crate::encoding::decode_unknown_table_field(decoder)?;
                    }

                    Ok(())
                })
            }
        }
    }
}

/// Decodes the inline portion of a xunion. Returns (ordinal, num_bytes, num_handles).
pub fn decode_xunion_inline_portion(decoder: &mut Decoder) -> Result<(u64, u32, u32)> {
    let mut ordinal: u64 = 0;
    ordinal.decode(decoder)?;

    let mut num_bytes: u32 = 0;
    num_bytes.decode(decoder)?;

    let mut num_handles: u32 = 0;
    num_handles.decode(decoder)?;

    let mut present: u64 = 0;
    present.decode(decoder)?;
    if present != ALLOC_PRESENT_U64 {
        return Err(Error::Invalid);
    }

    Ok((ordinal, num_bytes, num_handles))
}

impl<O, E> Layout for std::result::Result<O, E>
where
    O: Layout,
    E: Layout,
{
    fn inline_align(_context: &Context) -> usize {
        8
    }
    fn inline_size(_context: &Context) -> usize {
        24
    }
}

impl<O, E> Encodable for std::result::Result<O, E>
where
    O: Encodable,
    E: Encodable,
{
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        match self {
            Ok(val) => {
                // Encode success ordinal
                1u64.encode(encoder, offset, recursion_depth)?;
                // If the inline size is 0, meaning the type is (),
                // encode a zero byte instead because () in this context
                // means an empty struct, not an absent payload.
                if encoder.inline_size_of::<O>() == 0 {
                    encode_in_envelope(&mut Some(&mut 0u8), encoder, offset + 8, recursion_depth)
                } else {
                    encode_in_envelope(&mut Some(val), encoder, offset + 8, recursion_depth)
                }
            }
            Err(val) => {
                // Encode error ordinal
                2u64.encode(encoder, offset, recursion_depth)?;
                encode_in_envelope(&mut Some(val), encoder, offset + 8, recursion_depth)
            }
        }
    }
}

impl<O, E> Decodable for std::result::Result<O, E>
where
    O: Decodable,
    E: Decodable,
{
    fn new_empty() -> Self {
        Ok(<O as Decodable>::new_empty())
    }

    fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
        let (ordinal, _, _) = decode_xunion_inline_portion(decoder)?;
        let member_inline_size = match ordinal {
            1 => {
                // If the inline size is 0, meaning the type is (), use an inline
                // size of 1 instead because () in this context means an empty
                // struct, not an absent payload.
                cmp::max(1, decoder.inline_size_of::<O>())
            }
            2 => decoder.inline_size_of::<E>(),
            _ => return Err(Error::UnknownUnionTag),
        };
        decoder.read_out_of_line(member_inline_size, |decoder| {
            match ordinal {
                1 => {
                    if let Ok(_) = self {
                        // Do nothing, read the value into the object
                    } else {
                        // Initialize `self` to the right variant
                        *self = Ok(fidl_new_empty!(O));
                    }
                    if let Ok(val) = self {
                        // If the inline size is 0, then the type is ().
                        // () has a different wire-format representation in
                        // a result vs outside of a result, so special case
                        // decode.
                        if decoder.inline_size_of::<O>() == 0 {
                            decoder.skip_padding(1)
                        } else {
                            val.decode(decoder)
                        }
                    } else {
                        unreachable!()
                    }
                }
                2 => {
                    if let Err(_) = self {
                        // Do nothing, read the value into the object
                    } else {
                        // Initialize `self` to the right variant
                        *self = Err(fidl_new_empty!(E));
                    }
                    if let Err(val) = self {
                        val.decode(decoder)
                    } else {
                        unreachable!()
                    }
                }
                // Should be unreachable, since we already checked above.
                ordinal => panic!("unexpected ordinal {:?}", ordinal),
            }
        })
    }
}

/// A macro which declares a new FIDL xunion as a Rust enum and implements the
/// FIDL encoding and decoding traits for it.
#[macro_export]
macro_rules! fidl_xunion {
    (
        $(#[$attrs:meta])*
        name: $name:ident,
        members: [$(
            $(#[$member_docs:meta])*
            $member_name:ident {
                ty: $member_ty:ty,
                ordinal: $member_ordinal:expr,
            },
        )*],
        // Flexible xunions only: name of the unknown variant.
        $( unknown_member: $unknown_name:ident, )?
    ) => {
        $( #[$attrs] )*
        pub enum $name {
            $(
                $(#[$member_docs])*
                $member_name ( $member_ty ),
            )*
            $(
                #[doc(hidden)]
                $unknown_name {
                    ordinal: u64,
                    bytes: Vec<u8>,
                    handles: Vec<$crate::handle::Handle>,
                },
            )?
        }

        impl $name {
            fn ordinal(&self) -> u64 {
                match *self {
                    $(
                        $name::$member_name(_) => $member_ordinal,
                    )*
                    $(
                        $name::$unknown_name { ordinal, .. } => ordinal,
                    )?
                }
            }
        }

        impl $crate::encoding::Layout for $name {
            fn inline_align(_context: &$crate::encoding::Context) -> usize { 8 }
            fn inline_size(_context: &$crate::encoding::Context) -> usize { 24 }
        }

        impl $crate::encoding::Encodable for $name {
            fn encode(&mut self, encoder: &mut $crate::encoding::Encoder<'_>, offset: usize, recursion_depth: usize) -> $crate::Result<()> {
                let mut ordinal = self.ordinal();
                // Encode ordinal
                $crate::fidl_encode!(&mut ordinal, encoder, offset, recursion_depth)?;
                match self {
                    $(
                        $name::$member_name ( val ) => $crate::encoding::encode_in_envelope(&mut Some(val), encoder, offset+8, recursion_depth),
                    )*
                    $(
                        $name::$unknown_name { ordinal: _, bytes, handles } => {
                            // Throw the raw data from the unrecognized variant
                            // back onto the wire. This will allow correct proxies even in
                            // the event that they don't yet recognize this union variant.
                            $crate::fidl_encode!(&mut (bytes.len() as u32), encoder, offset + 8, recursion_depth)?;
                            $crate::fidl_encode!(&mut (handles.len() as u32), encoder, offset + 12, recursion_depth)?;
                            $crate::fidl_encode!(
                                &mut $crate::encoding::ALLOC_PRESENT_U64, encoder, offset + 16, recursion_depth
                            )?;
                            $crate::encoding::Encoder::check_recursion_depth(recursion_depth + 1)?;
                            encoder.append_bytes(bytes);
                            encoder.append_handles(handles);
                            Ok(())
                        },
                    )?
                }
            }
        }

        impl $crate::encoding::Decodable for $name {
            fn new_empty() -> Self {
                #![allow(unreachable_code)]
                $(
                    return $name::$member_name($crate::fidl_new_empty!($member_ty));
                )*
                $(
                    $name::$unknown_name { ordinal: 0, bytes: vec![], handles: vec![] }
                )?
            }

            fn decode(&mut self, decoder: &mut $crate::encoding::Decoder<'_>) -> $crate::Result<()> {
                #![allow(irrefutable_let_patterns, unused)]
                let (ordinal, num_bytes, num_handles) = $crate::encoding::decode_xunion_inline_portion(decoder)?;
                let member_inline_size = match ordinal {
                    $(
                        $member_ordinal => decoder.inline_size_of::<$member_ty>(),
                    )*
                    $(
                        _ => {
                            // We need the expansion to refer to $unknown_name,
                            // so just create and discard it as a string.
                            stringify!($unknown_name);
                            // Flexible xunion: unknown payloads are considered
                            // a wholly-inline string of bytes.
                            num_bytes as usize
                        }
                    )?
                    // Strict xunion: reject unknown ordinals.
                    _ => return Err($crate::Error::UnknownUnionTag),
                };

                decoder.read_out_of_line(member_inline_size, |decoder| {
                        match ordinal {
                            $(
                                $member_ordinal => {
                                    if let $name::$member_name(_) = self {
                                        // Do nothing, read the value into the object
                                    } else {
                                        // Initialize `self` to the right variant
                                        *self = $name::$member_name(
                                            $crate::fidl_new_empty!($member_ty)
                                        );
                                    }
                                    if let $name::$member_name(val) = self {
                                        $crate::fidl_decode!(val, decoder)?;
                                    } else {
                                        unreachable!()
                                    }
                                }
                            )*
                            $(
                                ordinal => {
                                    let offset = decoder.next_offset(num_bytes as usize);
                                    let bytes = decoder.buffer()[offset.. offset+(num_bytes as usize)].to_vec();
                                    let mut handles = Vec::with_capacity(num_handles as usize);
                                    for _ in 0..num_handles {
                                        handles.push(decoder.take_handle()?);
                                    }
                                    *self = $name::$unknown_name { ordinal, bytes, handles };
                                }
                            )?
                            // This should be unreachable, since we already
                            // checked for unknown ordinals above and returned
                            // an error in the strict case.
                            ordinal => panic!("unexpected ordinal {:?}", ordinal)
                        }
                        Ok(())
                })
            }
        }

        impl $crate::encoding::Autonull for $name {
            fn naturally_nullable(_context: &$crate::encoding::Context) -> bool {
                true
            }
        }
    }
}

/// Header for transactional FIDL messages
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct TransactionHeader {
    /// Transaction ID which identifies a request-response pair
    tx_id: u32,
    /// Flags set for this message. MUST NOT be validated by bindings
    flags: [u8; 3],
    /// Magic number indicating the message's wire format. Two sides with
    /// different magic numbers are incompatible with each other.
    magic_number: u8,
    /// Ordinal which identifies the FIDL method
    ordinal: u64,
}

impl TransactionHeader {
    /// Returns whether the message containing this TransactionHeader is in a
    /// compatible wire format
    pub fn is_compatible(&self) -> bool {
        self.magic_number == MAGIC_NUMBER_INITIAL
    }
}

fidl_struct! {
    name: TransactionHeader,
    members: [
        tx_id {
            ty: u32,
            offset_v1: 0,
        },
        flags {
            ty: [u8; 3],
            offset_v1: 4,
        },
        magic_number {
            ty: u8,
            offset_v1: 7,
        },
        ordinal {
            ty: u64,
            offset_v1: 8,
        },
    ],
    size_v1: 16,
    align_v1: 8,
}

bitflags! {
    /// Bitflags type for transaction header flags.
    pub struct HeaderFlags: u32 {
        /// Indicates that unions in the transaction message body are encoded
        /// using the xunion format.
        const UNIONS_USE_XUNION_FORMAT = 1 << 0;
    }
}

impl Into<[u8; 3]> for HeaderFlags {
    fn into(self) -> [u8; 3] {
        let bytes = self.bits.to_le_bytes();
        [bytes[0], bytes[1], bytes[2]]
    }
}

impl TransactionHeader {
    /// Creates a new transaction header with the default encode context and magic number.
    pub fn new(tx_id: u32, ordinal: u64) -> Self {
        TransactionHeader::new_full(tx_id, ordinal, &default_encode_context(), MAGIC_NUMBER_INITIAL)
    }
    /// Creates a new transaction header with a specific context and magic number.
    pub fn new_full(tx_id: u32, ordinal: u64, context: &Context, magic_number: u8) -> Self {
        TransactionHeader { tx_id, flags: context.header_flags().into(), magic_number, ordinal }
    }
    /// Returns the header's transaction id.
    pub fn tx_id(&self) -> u32 {
        self.tx_id
    }
    /// Returns the header's message ordinal.
    pub fn ordinal(&self) -> u64 {
        self.ordinal
    }
    /// Returns true if the header is for an epitaph message.
    pub fn is_epitaph(&self) -> bool {
        self.ordinal == EPITAPH_ORDINAL
    }

    /// Returns the magic number.
    pub fn magic_number(&self) -> u8 {
        self.magic_number
    }

    /// Returns the header's flags as a `HeaderFlags` value.
    pub fn flags(&self) -> HeaderFlags {
        let bytes = [self.flags[0], self.flags[1], self.flags[2], 0];
        HeaderFlags::from_bits_truncate(u32::from_le_bytes(bytes))
    }

    /// Returns the context to use for decoding the message body associated with
    /// this header. During migrations, this is dependent on `self.flags()` and
    /// controls dynamic behavior in the read path.
    pub fn decoding_context(&self) -> Context {
        Context {}
    }
}

/// Transactional FIDL message
pub struct TransactionMessage<'a, T> {
    /// Header of the message
    pub header: TransactionHeader,
    /// Body of the message
    pub body: &'a mut T,
}

impl<T: Layout> Layout for TransactionMessage<'_, T> {
    fn inline_align(context: &Context) -> usize {
        cmp::max(<TransactionHeader as Layout>::inline_align(context), T::inline_align(context))
    }
    fn inline_size(context: &Context) -> usize {
        <TransactionHeader as Layout>::inline_size(context) + T::inline_size(context)
    }
}

impl<T: Encodable> Encodable for TransactionMessage<'_, T> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        self.header.encode(encoder, offset, recursion_depth)?;
        (*self.body).encode(
            encoder,
            offset + encoder.inline_size_of::<TransactionHeader>(),
            recursion_depth,
        )?;
        Ok(())
    }
}

// To decode TransactionMessage<MyObject>, use this pattern:
//
//     let (header, body_bytes) = decode_transaction_header(bytes)?;
//     let mut my_object = MyObject::new_empty();
//     Decoder::decode_into(&header, body_bytes, handles, &mut my_object)?;
//
// We _could_ implement Decodable for TransactionMessage<T>, but it would only
// work when you know the type T upfront, which is often not the case (for
// example, it might depend on the ordinal). To avoid having two code paths that
// could get out of sync, we simply do not implement Decodable.
assert_not_impl_any!(TransactionMessage<()>: Decodable);

/// Decodes the transaction header from a message.
/// Returns the header and a reference to the tail of the message.
pub fn decode_transaction_header(bytes: &[u8]) -> Result<(TransactionHeader, &[u8])> {
    let mut header = TransactionHeader::new_empty();
    let context = Context {};
    let header_len = <TransactionHeader as Layout>::inline_size(&context);
    if bytes.len() < header_len {
        return Err(Error::OutOfRange);
    }
    let (header_bytes, body_bytes) = bytes.split_at(header_len);
    let handles = &mut [];
    Decoder::decode_with_context(&context, header_bytes, handles, &mut header)?;
    Ok((header, body_bytes))
}

/// Header for persistently stored FIDL messages
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct PersistentHeader {
    /// Flags set for this message. MUST NOT be validated by bindings
    flags: [u8; 3],
    /// Magic number indicating the message's wire format. Two sides with
    /// different magic numbers are incompatible with each other.
    magic_number: u8,
}

fidl_struct! {
    name: PersistentHeader,
    members: [
        flags {
            ty: [u8; 3],
            offset_v1: 4,
        },
        magic_number {
            ty: u8,
            offset_v1: 7,
        },
    ],
    size_v1: 16,
    align_v1: 8,
}

impl PersistentHeader {
    /// Creates a new `PersistentHeader` with the default encode context and magic number.
    pub fn new() -> Self {
        PersistentHeader::new_full(&default_encode_context(), MAGIC_NUMBER_INITIAL)
    }
    /// Creates a new `PersistentHeader` with a specific context and magic number.
    pub fn new_full(context: &Context, magic_number: u8) -> Self {
        PersistentHeader { flags: context.header_flags().into(), magic_number }
    }
    /// Returns the magic number.
    pub fn magic_number(&self) -> u8 {
        self.magic_number
    }
    /// Returns the header's flags as a `HeaderFlags` value.
    pub fn flags(&self) -> HeaderFlags {
        let bytes = [self.flags[0], self.flags[1], self.flags[2], 0];
        HeaderFlags::from_bits_truncate(u32::from_le_bytes(bytes))
    }
    /// Returns the context to use for decoding the message body associated with
    /// this header. During migrations, this is dependent on `self.flags()` and
    /// controls dynamic behavior in the read path.
    pub fn decoding_context(&self) -> Context {
        Context {}
    }
    /// Returns whether the message containing this `PersistentHeader` is in a
    /// compatible wire format.
    pub fn is_compatible(&self) -> bool {
        self.magic_number == MAGIC_NUMBER_INITIAL
    }
}

/// Persistently stored FIDL message
pub struct PersistentMessage<'a, T> {
    /// Header of the message
    pub header: PersistentHeader,
    /// Body of the message
    pub body: &'a mut T,
}

impl<T: Layout> Layout for PersistentMessage<'_, T> {
    fn inline_align(context: &Context) -> usize {
        cmp::max(<PersistentHeader as Layout>::inline_align(context), T::inline_align(context))
    }
    fn inline_size(context: &Context) -> usize {
        <PersistentHeader as Layout>::inline_size(context) + T::inline_size(context)
    }
}

impl<T: Encodable> Encodable for PersistentMessage<'_, T> {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        self.header.encode(encoder, offset, recursion_depth)?;
        (*self.body).encode(
            encoder,
            offset + encoder.inline_size_of::<PersistentHeader>(),
            recursion_depth,
        )?;
        Ok(())
    }
}

/// Encode the referred parameter into persistent binary form.
/// Generates and adds message header to the returned bytes.
pub fn encode_persistent<T: Encodable>(body: &mut T) -> Result<Vec<u8>> {
    let msg = &mut PersistentMessage { header: PersistentHeader::new(), body };
    let mut combined_bytes = Vec::<u8>::new();
    let mut handles = Vec::<Handle>::new();
    Encoder::encode(&mut combined_bytes, &mut handles, msg)?;
    debug_assert!(handles.is_empty(), "Persistent message contains handles");
    Ok(combined_bytes)
}

/// Creates persistent header to encode it and the message body separately.
pub fn create_persistent_header() -> PersistentHeader {
    PersistentHeader::new()
}

/// Encode PersistentHeader to persistent binary form.
pub fn encode_persistent_header(header: &mut PersistentHeader) -> Result<Vec<u8>> {
    let mut header_bytes = Vec::<u8>::new();
    Encoder::encode(&mut header_bytes, &mut Vec::new(), header)?;
    Ok(header_bytes)
}

/// Encode the message body to to persistent binary form.
pub fn encode_persistent_body<T: Encodable>(
    body: &mut T,
    header: &PersistentHeader,
) -> Result<Vec<u8>> {
    let mut combined_bytes = Vec::<u8>::new();
    let mut handles = Vec::<Handle>::new();
    Encoder::encode_with_context(
        &header.decoding_context(),
        &mut combined_bytes,
        &mut handles,
        body,
    )?;
    debug_assert!(handles.is_empty(), "Persistent message contains handles");
    Ok(combined_bytes)
}

/// Decode the type expected from the persistent binary form.
pub fn decode_persistent<T: Decodable>(bytes: &[u8]) -> Result<T> {
    let context = Context {};
    let header_len = <PersistentHeader as Layout>::inline_size(&context);
    if bytes.len() < header_len {
        return Err(Error::OutOfRange);
    }
    let (header_bytes, body_bytes) = bytes.split_at(header_len);
    let header = decode_persistent_header(header_bytes)?;
    decode_persistent_body(body_bytes, &header)
}

/// Decodes the persistently stored header from a message.
/// Returns the header and a reference to the tail of the message.
pub fn decode_persistent_header(bytes: &[u8]) -> Result<PersistentHeader> {
    let mut header = PersistentHeader::new_empty();
    Decoder::decode_with_context(&header.decoding_context(), bytes, &mut [], &mut header)?;
    Ok(header)
}

/// Decodes the persistently stored header from a message.
/// Returns the header and a reference to the tail of the message.
pub fn decode_persistent_body<T: Decodable>(bytes: &[u8], header: &PersistentHeader) -> Result<T> {
    let mut output = T::new_empty();
    Decoder::decode_with_context(&header.decoding_context(), bytes, &mut [], &mut output)?;
    Ok(output)
}

// Implementations of Encodable for (&mut Head, ...Tail) and Decodable for (Head, ...Tail)
macro_rules! tuple_impls {
    () => {};

    (($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )*) => {
        /*
         * Invoke recursive reversal of list that ends in the macro expansion implementation
         * of the reversed list
        */
        tuple_impls!([($idx, $typ);] $( ($nidx => $ntyp), )*);
        tuple_impls!($( ($nidx => $ntyp), )*); // invoke macro on tail
    };

    /*
     * ([accumulatedList], listToReverse); recursively calls tuple_impls until the list to reverse
     + is empty (see next pattern)
    */
    ([$(($accIdx:tt, $accTyp:ident);)+]
        ($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )*) => {
      tuple_impls!([($idx, $typ); $(($accIdx, $accTyp); )*] $( ($nidx => $ntyp), ) *);
    };

    // Finally expand into the implementation
    ([($idx:tt, $typ:ident); $( ($nidx:tt, $ntyp:ident); )*]) => {
        impl<$typ, $( $ntyp ),*> Layout for ($typ, $( $ntyp, )*)
            where $typ: Layout,
                  $( $ntyp: Layout, )*
        {
            fn inline_align(context: &Context) -> usize {
                let mut max = 0;
                if max < $typ::inline_align(context) {
                    max = $typ::inline_align(context);
                }
                $(
                    if max < $ntyp::inline_align(context) {
                        max = $ntyp::inline_align(context);
                    }
                )*
                max
            }

            fn inline_size(context: &Context) -> usize {
                let mut offset = 0;
                offset += $typ::inline_size(context);
                $(
                    offset = round_up_to_align(offset, $ntyp::inline_align(context));
                    offset += $ntyp::inline_size(context);
                )*
                offset
            }
        }

        impl<$typ, $( $ntyp ,)*> Encodable for ($typ, $( $ntyp ,)*)
            where $typ: Encodable,
                  $( $ntyp: Encodable,)*
        {
            fn encode(&mut self, encoder: &mut Encoder<'_>, offset: usize, recursion_depth: usize) -> Result<()> {
                // Tuples are encoded like structs.
                // $idx is always 0 for the first element.
                self.$idx.encode(encoder, offset, recursion_depth)?;
                let mut cur_offset = 0;
                cur_offset += encoder.inline_size_of::<$typ>();
                $(
                    // Skip to the start of the next field
                    let member_offset =
                        round_up_to_align(cur_offset, encoder.inline_align_of::<$ntyp>());
                    encoder.padding(offset + cur_offset, member_offset - cur_offset);
                    self.$nidx.encode(encoder, offset + member_offset, recursion_depth)?;
                    cur_offset = member_offset + encoder.inline_size_of::<$ntyp>();
                )*
                encoder.padding(offset + cur_offset, encoder.inline_size_of::<Self>() - cur_offset);
                Ok(())
            }
        }

        impl<$typ, $( $ntyp ),*> Decodable for ($typ, $( $ntyp, )*)
            where $typ: Decodable,
                  $( $ntyp: Decodable, )*
        {
            fn new_empty() -> Self {
                (
                    $typ::new_empty(),
                    $(
                        $ntyp::new_empty(),
                    )*
                )
            }

            fn decode(&mut self, decoder: &mut Decoder<'_>) -> Result<()> {
                let mut cur_offset = 0;
                self.$idx.decode(decoder)?;
                cur_offset += decoder.inline_size_of::<$typ>();
                $(
                    // Skip to the start of the next field
                    let member_offset =
                        round_up_to_align(cur_offset, decoder.inline_align_of::<$ntyp>());
                    decoder.skip_padding(member_offset - cur_offset)?;
                    cur_offset = member_offset;
                    self.$nidx.decode(decoder)?;
                    cur_offset += decoder.inline_size_of::<$ntyp>();
                )*
                // Skip to the end of the struct's size
                decoder.skip_padding(decoder.inline_size_of::<Self>() - cur_offset)?;
                Ok(())
            }
        }
    }
}

tuple_impls!(
    (10 => K),
    (9 => J),
    (8 => I),
    (7 => H),
    (6 => G),
    (5 => F),
    (4 => E),
    (3 => D),
    (2 => C),
    (1 => B),
    (0 => A),
);

// The unit type has 0 size because it represents the absent payload after the
// transaction header in the reponse of a two-way FIDL method such as this one:
//
//     Method() -> ();
//
// However, the unit type is also used in the following situation:
//
//    MethodWithError() -> () error int32;
//
// In this case the response type is std::result::Result<(), i32>, but the ()
// represents an empty struct, which has size 1. To accommodate this, the encode
// and decode methods on std::result::Result handle the () case specially.
impl_layout!((), align: 1, size: 0);

impl Encodable for () {
    fn encode(
        &mut self,
        _: &mut Encoder<'_>,
        _offset: usize,
        _recursion_depth: usize,
    ) -> Result<()> {
        Ok(())
    }
}

impl Decodable for () {
    fn new_empty() -> Self {
        ()
    }
    fn decode(&mut self, _: &mut Decoder<'_>) -> Result<()> {
        Ok(())
    }
}

impl<T: Layout> Layout for &mut T {
    fn inline_align(context: &Context) -> usize {
        T::inline_align(context)
    }
    fn inline_size(context: &Context) -> usize {
        T::inline_size(context)
    }
}

impl<T: Encodable> Encodable for &mut T {
    fn encode(
        &mut self,
        encoder: &mut Encoder<'_>,
        offset: usize,
        recursion_depth: usize,
    ) -> Result<()> {
        (&mut **self).encode(encoder, offset, recursion_depth)
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use matches::assert_matches;
    use std::{f32, f64, fmt, i64, u64};

    pub const CONTEXTS: &[&Context] = &[&Context {}];

    pub fn encode_decode<T: Encodable + Decodable>(ctx: &Context, start: &mut T) -> T {
        let buf = &mut Vec::new();
        let handle_buf = &mut Vec::new();
        Encoder::encode_with_context(ctx, buf, handle_buf, start).expect("Encoding failed");
        let mut out = T::new_empty();
        Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");
        out
    }

    fn encode_assert_bytes<T: Encodable>(ctx: &Context, mut data: T, encoded_bytes: &[u8]) {
        let buf = &mut Vec::new();
        let handle_buf = &mut Vec::new();
        Encoder::encode_with_context(ctx, buf, handle_buf, &mut data).expect("Encoding failed");
        assert_eq!(&**buf, encoded_bytes);
    }

    fn assert_identity<T>(mut x: T, cloned: T)
    where
        T: Encodable + Decodable + PartialEq + fmt::Debug,
    {
        for ctx in CONTEXTS {
            assert_eq!(cloned, encode_decode(ctx, &mut x));
        }
    }

    macro_rules! identities { ($($x:expr,)*) => { $(
        assert_identity($x, $x);
    )* } }

    #[test]
    fn encode_decode_byte() {
        identities![0u8, 57u8, 255u8, 0i8, -57i8, 12i8,];
    }

    #[test]
    #[rustfmt::skip]
    fn encode_decode_multibyte() {
        identities![
            0u64, 1u64, u64::MAX, u64::MIN,
            0i64, 1i64, i64::MAX, i64::MIN,
            0f32, 1f32, f32::MAX, f32::MIN,
            0f64, 1f64, f64::MAX, f64::MIN,
        ];
    }

    #[test]
    fn encode_decode_nan() {
        for ctx in CONTEXTS {
            let nan32 = encode_decode(ctx, &mut f32::NAN);
            assert!(nan32.is_nan());

            let nan64 = encode_decode(ctx, &mut f64::NAN);
            assert!(nan64.is_nan());
        }
    }

    #[test]
    fn encode_decode_out_of_line() {
        identities![
            Vec::<i32>::new(),
            vec![1, 2, 3],
            None::<Vec<i32>>,
            Some(Vec::<i32>::new()),
            Some(vec![1, 2, 3]),
            Some(vec![vec![1, 2, 3]]),
            Some(vec![Some(vec![1, 2, 3])]),
            "".to_string(),
            "foo".to_string(),
            None::<String>,
            Some("".to_string()),
            Some("foo".to_string()),
            Some(vec![None, Some("foo".to_string())]),
            vec!["foo".to_string(), "bar".to_string()],
        ];
    }

    pub fn assert_identity_slice<'a, T>(ctx: &Context, mut start: &'a [T])
    where
        &'a [T]: Encodable,
        Vec<T>: Decodable,
        T: PartialEq + fmt::Debug,
    {
        let buf = &mut Vec::new();
        let handle_buf = &mut Vec::new();
        Encoder::encode_with_context(ctx, buf, handle_buf, &mut start).expect("Encoding failed");
        let mut out = Vec::<T>::new_empty();
        Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");
        assert_eq!(start, &out[..]);
    }

    #[test]
    fn encode_slices_of_primitives() {
        for ctx in CONTEXTS {
            assert_identity_slice(ctx, &[] as &[u8]);
            assert_identity_slice(ctx, &[0u8]);
            assert_identity_slice(ctx, &[1u8, 2, 3, 4, 5, 255]);

            assert_identity_slice(ctx, &[] as &[i8]);
            assert_identity_slice(ctx, &[0i8]);
            assert_identity_slice(ctx, &[1i8, 2, 3, 4, 5, -128, 127]);

            assert_identity_slice(ctx, &[] as &[u64]);
            assert_identity_slice(ctx, &[0u64]);
            assert_identity_slice(ctx, &[1u64, 2, 3, 4, 5, u64::MAX]);

            assert_identity_slice(ctx, &[] as &[f32]);
            assert_identity_slice(ctx, &[0.0f32]);
            assert_identity_slice(ctx, &[1.0f32, 2.0, 3.0, 4.0, 5.0, f32::MIN, f32::MAX]);

            assert_identity_slice(ctx, &[] as &[f64]);
            assert_identity_slice(ctx, &[0.0f64]);
            assert_identity_slice(ctx, &[1.0f64, 2.0, 3.0, 4.0, 5.0, f64::MIN, f64::MAX]);
        }
    }

    #[test]
    fn encode_decode_bits() {
        fidl_bits!(Buttons(u32) {
            PLAY = 1,
            PAUSE = 2,
            STOP = 4,
        });

        assert_eq!(Buttons::from_bits(1), Some(Buttons::PLAY));
        assert_eq!(Buttons::from_bits(12), None);
        assert_eq!(Buttons::STOP.bits(), 4);

        identities![
            Buttons::PLAY,
            Buttons::PAUSE,
            Buttons::STOP,
            Buttons::from_bits(1).expect("should be Play"),
            Buttons::from_bits(Buttons::PAUSE.bits()).expect("should be Pause"),
        ];
    }

    #[test]
    fn encode_decode_enum() {
        fidl_enum!(Animal(i32) {
            Dog = 0,
            Cat = 1,
            Frog = 2,
        });

        assert_eq!(Animal::from_primitive(0), Some(Animal::Dog));
        assert_eq!(Animal::from_primitive(3), None);
        assert_eq!(Animal::Cat.into_primitive(), 1);

        identities![
            Animal::Dog,
            Animal::Cat,
            Animal::Frog,
            Animal::from_primitive(0).expect("should be dog"),
            Animal::from_primitive(Animal::Cat.into_primitive()).expect("should be cat"),
        ];
    }

    #[test]
    fn result_encode_empty_ok_value() {
        identities![(), Ok::<(), i32>(()),];
        for ctx in CONTEXTS {
            // An empty response is represented by () and has zero size.
            encode_assert_bytes(ctx, (), &[]);
            // But in the context of an error result type Result<(), ErrorType>, the
            // () in Ok(()) is treated as an empty struct (with size 1).
            encode_assert_bytes(
                ctx,
                Ok::<(), i32>(()),
                &[
                    0x01, 0x00, 0x00, 0x00, // success ordinal
                    0x00, 0x00, 0x00, 0x00, // success ordinal [cont.]
                    0x08, 0x00, 0x00, 0x00, // 8 bytes (rounded up from 1)
                    0x00, 0x00, 0x00, 0x00, // 0 handles
                    0xff, 0xff, 0xff, 0xff, // present
                    0xff, 0xff, 0xff, 0xff, // present [cont.]
                    0x00, 0x00, 0x00, 0x00, // empty struct + 3 bytes padding
                    0x00, 0x00, 0x00, 0x00, // padding
                ],
            );
        }
    }

    #[test]
    fn result_with_size_non_multiple_of_align() {
        type Res = std::result::Result<(Vec<u8>, bool), u32>;

        identities![
            Res::Ok((vec![], true)),
            Res::Ok((vec![], false)),
            Res::Ok((vec![1, 2, 3, 4, 5], true)),
            Res::Err(7u32),
        ];
    }

    #[test]
    fn result_and_xunion_compat() {
        fidl_xunion! {
            #[derive(Debug, Copy, Clone, Eq, PartialEq)]
            name: OkayOrError,
            members: [
                Okay {
                    ty: u64,
                    ordinal: 1,
                },
                Error {
                    ty: u32,
                    ordinal: 2,
                },
            ],
        };

        for ctx in CONTEXTS {
            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            let mut out: std::result::Result<u64, u32> = Decodable::new_empty();

            Encoder::encode_with_context(ctx, buf, handle_buf, &mut OkayOrError::Okay(42u64))
                .expect("Encoding failed");
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");
            assert_eq!(out, Ok(42));

            Encoder::encode_with_context(ctx, buf, handle_buf, &mut OkayOrError::Error(3u32))
                .expect("Encoding failed");
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");
            assert_eq!(out, Err(3));
        }
    }

    #[test]
    fn result_and_xunion_compat_smaller() {
        fidl_empty_struct!(Empty);
        fidl_xunion! {
            #[derive(Debug, Copy, Clone, Eq, PartialEq)]
            name: OkayOrError,
            members: [
                Okay {
                    ty: Empty,
                    ordinal: 1,
                },
                Error {
                    ty: i32,
                    ordinal: 2,
                },
            ],
        };

        for ctx in CONTEXTS {
            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();

            // result to xunion
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut Ok::<(), i32>(()))
                .expect("Encoding failed");
            let mut out = OkayOrError::new_empty();
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");
            assert_eq!(out, OkayOrError::Okay(Empty {}));

            Encoder::encode_with_context(ctx, buf, handle_buf, &mut Err::<(), i32>(5))
                .expect("Encoding failed");
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");
            assert_eq!(out, OkayOrError::Error(5));

            // xunion to result
            let mut out: std::result::Result<(), i32> = Decodable::new_empty();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut OkayOrError::Okay(Empty {}))
                .expect("Encoding failed");
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");
            assert_eq!(out, Ok(()));

            Encoder::encode_with_context(ctx, buf, handle_buf, &mut OkayOrError::Error(3i32))
                .expect("Encoding failed");
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");
            assert_eq!(out, Err(3));
        }
    }

    #[test]
    fn encode_decode_result() {
        for ctx in CONTEXTS {
            let mut test_result: std::result::Result<String, u32> = Ok("fuchsia".to_string());
            let mut test_result_err: std::result::Result<String, u32> = Err(5);

            match encode_decode(ctx, &mut test_result) {
                Ok(ref out_str) if "fuchsia".to_string() == *out_str => {}
                x => panic!("unexpected decoded value {:?}", x),
            }

            match &encode_decode(ctx, &mut test_result_err) {
                Err(err_code) if *err_code == 5 => {}
                x => panic!("unexpected decoded value {:?}", x),
            }
        }
    }

    #[test]
    fn encode_decode_result_array() {
        use std::result::Result;

        for ctx in CONTEXTS {
            {
                let mut input: [Result<_, u32>; 2] = [Ok("a".to_string()), Ok("bcd".to_string())];
                match encode_decode(ctx, &mut input) {
                    [Ok(ref ok1), Ok(ref ok2)]
                        if *ok1 == "a".to_string() && *ok2 == "bcd".to_string() => {}
                    x => panic!("unexpected decoded value {:?}", x),
                }
            }

            {
                let mut input: [Result<String, u32>; 2] = [Err(7), Err(42)];
                match encode_decode(ctx, &mut input) {
                    [Err(ref err1), Err(ref err2)] if *err1 == 7 && *err2 == 42 => {}
                    x => panic!("unexpected decoded value {:?}", x),
                }
            }

            {
                let mut input = [Ok("abc".to_string()), Err(42)];
                match encode_decode(ctx, &mut input) {
                    [Ok(ref ok1), Err(ref err2)] if *ok1 == "abc".to_string() && *err2 == 42 => {}
                    x => panic!("unexpected decoded value {:?}", x),
                }
            }
        }
    }

    struct Foo {
        byte: u8,
        bignum: u64,
        string: String,
    }

    fidl_struct! {
        name: Foo,
        members: [
            byte {
                ty: u8,
                offset_v1: 0,
            },
            bignum {
                ty: u64,
                offset_v1: 8,
            },
            string {
                ty: String,
                offset_v1: 16,
            },
        ],
        size_v1: 32,
        align_v1: 8,
    }

    #[test]
    fn encode_decode_struct() {
        for ctx in CONTEXTS {
            let out_foo = encode_decode(
                ctx,
                &mut Some(Box::new(Foo { byte: 5, bignum: 22, string: "hello world".to_string() })),
            )
            .expect("should be some");

            assert_eq!(out_foo.byte, 5);
            assert_eq!(out_foo.bignum, 22);
            assert_eq!(out_foo.string, "hello world");

            let out_foo: Option<Box<Foo>> = encode_decode(ctx, &mut Box::new(None));
            assert!(out_foo.is_none());
        }
    }

    #[test]
    fn decode_struct_with_invalid_padding_fails() {
        for ctx in CONTEXTS {
            let foo = &mut Foo { byte: 0, bignum: 0, string: String::new() };
            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, foo).expect("Encoding failed");

            buf[1] = 42;
            let out = &mut Foo::new_empty();
            let result = Decoder::decode_with_context(ctx, buf, handle_buf, out);
            assert_matches!(
                result,
                Err(Error::NonZeroPadding { padding_start: 1, non_zero_pos: 1 })
            );
        }
    }

    #[test]
    fn encode_decode_tuple() {
        for ctx in CONTEXTS {
            let mut start: (&mut u8, &mut u64, &mut String) =
                (&mut 5, &mut 10, &mut "foo".to_string());
            let mut out: (u8, u64, String) = Decodable::new_empty();

            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut start)
                .expect("Encoding failed");
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");

            assert_eq!(*start.0, out.0);
            assert_eq!(*start.1, out.1);
            assert_eq!(*start.2, out.2);
        }
    }

    #[test]
    fn encode_decode_struct_as_tuple() {
        for ctx in CONTEXTS {
            let mut start = Foo { byte: 5, bignum: 10, string: "foo".to_string() };
            let mut out: (u8, u64, String) = Decodable::new_empty();

            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut start)
                .expect("Encoding failed");
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");

            assert_eq!(start.byte, out.0);
            assert_eq!(start.bignum, out.1);
            assert_eq!(start.string, out.2);
        }
    }

    #[test]
    fn encode_decode_tuple_as_struct() {
        for ctx in CONTEXTS {
            let mut start = (&mut 5u8, &mut 10u64, &mut "foo".to_string());
            let mut out: Foo = Decodable::new_empty();

            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut start)
                .expect("Encoding failed");
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut out).expect("Decoding failed");

            assert_eq!(*start.0, out.byte);
            assert_eq!(*start.1, out.bignum);
            assert_eq!(*start.2, out.string);
        }
    }

    #[test]
    fn encode_decode_tuple_msg() {
        for ctx in CONTEXTS {
            let mut body_start = (&mut "foo".to_string(), &mut 5);
            let mut body_out: (String, u8) = Decodable::new_empty();

            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut body_start).unwrap();
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut body_out).unwrap();

            assert_eq!(body_start.0, &mut body_out.0);
            assert_eq!(body_start.1, &mut body_out.1);
        }
    }

    pub struct MyTable {
        pub num: Option<i32>,
        pub num_none: Option<i32>,
        pub string: Option<String>,
        pub handle: Option<Handle>,
    }

    fidl_table! {
        name: MyTable,
        members: {
            num {
                ty: i32,
                ordinal: 1,
            },
            num_none {
                ty: i32,
                ordinal: 2,
            },
            string {
                ty: String,
                ordinal: 3,
            },
            handle {
                ty: Handle,
                ordinal: 4,
            },
        },
    }

    #[allow(unused)]
    struct EmptyTableCompiles {}
    fidl_table! {
        name: EmptyTableCompiles,
        members: {},
    }

    struct TablePrefix {
        num: Option<i32>,
        num_none: Option<i32>,
    }

    fidl_table! {
        name: TablePrefix,
        members: {
            num {
                ty: i32,
                ordinal: 1,
            },
            num_none {
                ty: i32,
                ordinal: 2,
            },
        },
    }

    #[test]
    fn empty_table() {
        let mut table: MyTable = MyTable::empty();
        assert_eq!(None, table.num);
        table = MyTable { num: Some(32), ..MyTable::empty() };
        assert_eq!(Some(32), table.num);
        assert_eq!(None, table.string);
    }

    #[test]
    fn table_encode_prefix_decode_full() {
        for ctx in CONTEXTS {
            let mut table_prefix_in = TablePrefix { num: Some(5), num_none: None };
            let mut table_out: MyTable = Decodable::new_empty();

            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut table_prefix_in).unwrap();
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut table_out).unwrap();

            assert_eq!(table_out.num, Some(5));
            assert_eq!(table_out.num_none, None);
            assert_eq!(table_out.string, None);
            assert_eq!(table_out.handle, None);
        }
    }

    #[test]
    fn table_encode_omits_none_tail() {
        for ctx in CONTEXTS {
            // "None" fields at the tail of a table shouldn't be encoded at all.
            let mut table_in = MyTable {
                num: Some(5),
                // These fields should all be omitted in the encoded repr,
                // allowing decoding of the prefix to succeed.
                num_none: None,
                string: None,
                handle: None,
            };
            let mut table_prefix_out: TablePrefix = Decodable::new_empty();

            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut table_in).unwrap();
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut table_prefix_out).unwrap();

            assert_eq!(table_prefix_out.num, Some(5));
            assert_eq!(table_prefix_out.num_none, None);
        }
    }

    #[test]
    fn table_decode_ignores_unrecognized_tail() {
        for ctx in CONTEXTS {
            let mut table_in = MyTable {
                num: Some(5),
                num_none: None,
                string: Some("foo".to_string()),
                handle: None,
            };
            let mut table_prefix_out: TablePrefix = Decodable::new_empty();

            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut table_in).unwrap();
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut table_prefix_out).unwrap();
            assert_eq!(table_prefix_out.num, Some(5));
            assert_eq!(table_prefix_out.num_none, None);
        }
    }

    #[derive(Debug, PartialEq)]
    pub struct SimpleTable {
        x: Option<i64>,
        y: Option<i64>,
    }

    fidl_table! {
        name: SimpleTable,
        members: {
            x {
                ty: i64,
                ordinal: 1,
            },
            y {
                ty: i64,
                ordinal: 5,
            },
        },
    }

    #[derive(Debug, PartialEq)]
    pub struct TableWithStringAndVector {
        foo: Option<String>,
        bar: Option<i32>,
        baz: Option<Vec<u8>>,
    }

    fidl_table! {
        name: TableWithStringAndVector,
        members: {
            foo {
                ty: String,
                ordinal: 1,
            },
            bar {
                ty: i32,
                ordinal: 2,
            },
            baz {
                ty: Vec<u8>,
                ordinal: 3,
            },
        },
    }

    #[test]
    fn table_golden_simple_table_with_xy() {
        let simple_table_with_xy: &[u8] = &[
            5, 0, 0, 0, 0, 0, 0, 0, // max ordinal
            255, 255, 255, 255, 255, 255, 255, 255, // alloc present
            8, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
            255, 255, 255, 255, 255, 255, 255, 255, // alloc present
            0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
            0, 0, 0, 0, 0, 0, 0, 0, // no alloc
            0, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
            0, 0, 0, 0, 0, 0, 0, 0, // no alloc
            0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
            0, 0, 0, 0, 0, 0, 0, 0, // no alloc
            8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
            255, 255, 255, 255, 255, 255, 255, 255, // alloc present
            42, 0, 0, 0, 0, 0, 0, 0, // field X
            67, 0, 0, 0, 0, 0, 0, 0, // field Y
        ];
        for ctx in CONTEXTS {
            encode_assert_bytes(
                ctx,
                SimpleTable { x: Some(42), y: Some(67) },
                simple_table_with_xy,
            );
        }
    }

    #[test]
    fn table_golden_simple_table_with_y() {
        let simple_table_with_y: &[u8] = &[
            5, 0, 0, 0, 0, 0, 0, 0, // max ordinal
            255, 255, 255, 255, 255, 255, 255, 255, // alloc present
            0, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
            0, 0, 0, 0, 0, 0, 0, 0, // no alloc
            0, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
            0, 0, 0, 0, 0, 0, 0, 0, // no alloc
            0, 0, 0, 0, 0, 0, 0, 0, // envelope 3: num bytes / num handles
            0, 0, 0, 0, 0, 0, 0, 0, // no alloc
            0, 0, 0, 0, 0, 0, 0, 0, // envelope 4: num bytes / num handles
            0, 0, 0, 0, 0, 0, 0, 0, // no alloc
            8, 0, 0, 0, 0, 0, 0, 0, // envelope 5: num bytes / num handles
            255, 255, 255, 255, 255, 255, 255, 255, // alloc present
            67, 0, 0, 0, 0, 0, 0, 0, // field Y
        ];
        for ctx in CONTEXTS {
            encode_assert_bytes(ctx, SimpleTable { x: None, y: Some(67) }, simple_table_with_y);
        }
    }

    #[test]
    fn table_golden_string_and_vector_hello_27() {
        let table_with_string_and_vector_hello_27: &[u8] = &[
            2, 0, 0, 0, 0, 0, 0, 0, // max ordinal
            255, 255, 255, 255, 255, 255, 255, 255, // alloc present
            24, 0, 0, 0, 0, 0, 0, 0, // envelope 1: num bytes / num handles
            255, 255, 255, 255, 255, 255, 255, 255, // envelope 1: alloc present
            8, 0, 0, 0, 0, 0, 0, 0, // envelope 2: num bytes / num handles
            255, 255, 255, 255, 255, 255, 255, 255, // envelope 2: alloc present
            5, 0, 0, 0, 0, 0, 0, 0, // element 1: length
            255, 255, 255, 255, 255, 255, 255, 255, // element 1: alloc present
            104, 101, 108, 108, 111, 0, 0, 0, // element 1: hello
            27, 0, 0, 0, 0, 0, 0, 0, // element 2: value
        ];
        for ctx in CONTEXTS {
            encode_assert_bytes(
                ctx,
                TableWithStringAndVector {
                    foo: Some("hello".to_string()),
                    bar: Some(27),
                    baz: None,
                },
                table_with_string_and_vector_hello_27,
            );
        }
    }

    #[test]
    fn table_golden_empty_table() {
        let empty_table: &[u8] = &[
            0, 0, 0, 0, 0, 0, 0, 0, // max ordinal
            255, 255, 255, 255, 255, 255, 255, 255, // alloc present
        ];

        for ctx in CONTEXTS {
            encode_assert_bytes(ctx, SimpleTable { x: None, y: None }, empty_table);
        }
    }

    #[derive(Debug)]
    struct TableWithGaps {
        second: Option<i32>,
        fourth: Option<i32>,
    }

    fidl_table! {
        name: TableWithGaps,
        members: {
            second {
                ty: i32,
                ordinal: 2,
            },
            fourth {
                ty: i32,
                ordinal: 4,
            },
        },
    }

    #[test]
    fn encode_decode_table_with_gaps() {
        for ctx in CONTEXTS {
            let mut table = TableWithGaps { second: Some(1), fourth: Some(2) };
            let table_out = encode_decode(ctx, &mut table);
            assert_eq!(table_out.second, Some(1));
            assert_eq!(table_out.fourth, Some(2));
        }
    }

    #[test]
    fn encode_empty_envelopes_for_reserved_table_fields() {
        for ctx in CONTEXTS {
            let mut table = TableWithGaps { second: Some(1), fourth: Some(2) };
            let buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, &mut Vec::new(), &mut table).unwrap();

            // Expected layout:
            //     0x00 table header
            //     0x10 envelope 1 (reserved)
            //     0x20 envelope 2 (second)
            //     0x30 envelope 3 (reserved)
            //     0x40 envelope 4 (fourth)
            assert_eq!(&buf[0x10..0x20], &[0; 16]);
            assert_eq!(&buf[0x30..0x40], &[0; 16]);
        }
    }

    #[test]
    fn decode_table_missing_gaps() {
        struct TableWithoutGaps {
            first: Option<i32>,
            second: Option<i32>,
        }
        fidl_table! {
            name: TableWithoutGaps,
            members: {
                first {
                    ty: i32,
                    ordinal: 1,
                },
                second {
                    ty: i32,
                    ordinal: 2,
                },
            },
        }

        for ctx in CONTEXTS {
            // This test shows what would happen when decoding a TableWithGaps
            // that was incorrectly encoded _without_ gaps.
            //
            //     Ordinal:  #1     #2      #3     #4
            //     Encoded:  first second
            //     Decoding: _____ second  _____ fourth
            //
            // Field #1 is assumed to be a new field in a reserved slot (i.e.
            // the sender is newer than us), so it is ignored. Fields #3 and #4
            // are assumed to be None because the tail is omitted.
            let mut table = TableWithoutGaps { first: Some(1), second: Some(2) };
            let buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, &mut Vec::new(), &mut table).unwrap();

            let mut out = TableWithGaps::new_empty();
            Decoder::decode_with_context(ctx, buf, &mut Vec::new(), &mut out).unwrap();
            assert_eq!(out.second, Some(2));
            assert_eq!(out.fourth, None);
        }
    }

    #[derive(Debug, PartialEq, zerocopy::AsBytes, zerocopy::FromBytes)]
    #[repr(C)]
    pub struct DirectCopyStruct {
        a: u64,
        b: u32,
        c: u16,
        d: u16,
    }
    fidl_struct_copy! {
        name: DirectCopyStruct,
        members: [
            a {
                ty: u64,
                offset_v1: 0,
            },
            b {
                ty: u32,
                offset_v1: 8,
            },
            c {
                ty: u16,
                offset_v1: 12,
            },
            d {
                ty: u16,
                offset_v1: 14,
            },
        ],
        size_v1: 16,
        align_v1: 8,
    }

    #[test]
    fn direct_copy_struct_encode() {
        let bytes = &[
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, //
            0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, //
        ];
        let mut obj =
            DirectCopyStruct { a: 0x0807060504030201, b: 0x0c0b0a09, c: 0x0e0d, d: 0x100f };

        for ctx in CONTEXTS {
            encode_assert_bytes(ctx, &mut obj, bytes);
        }
    }

    #[test]
    fn direct_copy_struct_decode() {
        let bytes = &[
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, //
            0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, //
        ];
        let obj = DirectCopyStruct { a: 0x0807060504030201, b: 0x0c0b0a09, c: 0x0e0d, d: 0x100f };

        for ctx in CONTEXTS {
            let mut out = DirectCopyStruct::new_empty();
            Decoder::decode_with_context(ctx, bytes, &mut [], &mut out).expect("Decoding failed");
            assert_eq!(out, obj);
        }
    }

    #[derive(Debug, PartialEq)]
    pub struct Int64Struct {
        x: u64,
    }
    fidl_struct! {
        name: Int64Struct,
        members: [
            x {
                ty: u64,
                offset_v1: 0,
            },
        ],
        size_v1: 8,
        align_v1: 8,
    }
    // Ensure single-variant xunion compiles (no irrefutable pattern errors).
    fidl_xunion! {
        #[derive(Debug, PartialEq)]
        name: SingleVariantXUnion,
        members: [
            B {
                ty: bool,
                ordinal: 1,
            },
        ],
    }

    fidl_xunion! {
        #[derive(Debug, PartialEq)]
        name: TestSampleXUnion,
        members: [
            U {
                ty: u32,
                ordinal: 0x29df47a5,
            },
            St {
                ty: SimpleTable,
                ordinal: 0x6f317664,
            },
        ],
        unknown_member: __UnknownVariant,
    }

    fidl_xunion! {
        #[derive(Debug, PartialEq)]
        name: TestSampleXUnionStrict,
        members: [
            U {
                ty: u32,
                ordinal: 0x29df47a5,
            },
            St {
                ty: SimpleTable,
                ordinal: 0x6f317664,
            },
        ],
    }

    fidl_xunion! {
        #[derive(Debug, PartialEq)]
        name: TestSampleXUnionExpanded,
        members: [
            SomethinElse {
                ty: Handle,
                ordinal: 55,
            },
        ],
        unknown_member: __UnknownVariant,
    }

    #[test]
    fn xunion_golden_u() {
        let xunion_u_bytes = &[
            0xa5, 0x47, 0xdf, 0x29, 0x00, 0x00, 0x00, 0x00, // xunion discriminator + padding
            0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // num bytes + num handles
            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // presence indicator
            0xef, 0xbe, 0xad, 0xde, 0x00, 0x00, 0x00, 0x00, // content + padding
        ];

        for ctx in CONTEXTS {
            encode_assert_bytes(ctx, TestSampleXUnion::U(0xdeadbeef), xunion_u_bytes);
            encode_assert_bytes(ctx, TestSampleXUnionStrict::U(0xdeadbeef), xunion_u_bytes);

            // The nullable representation Option<Box<T>> has the same layout.
            encode_assert_bytes(
                ctx,
                Some(Box::new(TestSampleXUnion::U(0xdeadbeef))),
                xunion_u_bytes,
            );
            encode_assert_bytes(
                ctx,
                Some(Box::new(TestSampleXUnionStrict::U(0xdeadbeef))),
                xunion_u_bytes,
            );
        }
    }

    #[test]
    fn xunion_golden_null() {
        for ctx in CONTEXTS {
            encode_assert_bytes(ctx, None::<Box<TestSampleXUnion>>, &[0; 24]);
            encode_assert_bytes(ctx, None::<Box<TestSampleXUnionStrict>>, &[0; 24]);
        }
    }

    #[test]
    fn encode_decode_transaction_msg() {
        for ctx in CONTEXTS {
            let header = TransactionHeader { tx_id: 4, ordinal: 6, flags: [0; 3], magic_number: 1 };
            let body = "hello".to_string();

            let start = &mut TransactionMessage { header, body: &mut body.clone() };

            let (buf, handles) = (&mut vec![], &mut vec![]);
            Encoder::encode_with_context(ctx, buf, handles, start).expect("Encoding failed");

            let (out_header, out_buf) =
                decode_transaction_header(&**buf).expect("Decoding header failed");
            assert_eq!(header, out_header);

            let mut body_out = String::new();
            Decoder::decode_into(&header, out_buf, handles, &mut body_out)
                .expect("Decoding body failed");
            assert_eq!(body, body_out);
        }
    }

    #[test]
    fn encode_decode_persistent_combined() {
        let mut body = "hello".to_string();

        let buf = encode_persistent(&mut body).expect("Encoding failed");
        let body_out = decode_persistent::<String>(&buf).expect("Decoding failed");

        assert_eq!(body, body_out);
    }

    #[test]
    fn encode_decode_persistent_separate() {
        let mut body = "hello".to_string();
        let mut another_body = "world".to_string();

        let mut header = create_persistent_header();
        let buf_header = encode_persistent_header(&mut header).expect("Header encoding failed");
        let buf_body = encode_persistent_body(&mut body, &header).expect("Body encoding failed");
        let buf_another_body =
            encode_persistent_body(&mut another_body, &header).expect("Body encoding failed");

        let header_out = decode_persistent_header(&buf_header).expect("Header decoding failed");
        assert_eq!(header, header_out);
        let body_out =
            decode_persistent_body::<String>(&buf_body, &header).expect("Body decoding failed");
        assert_eq!(body, body_out);
        let another_body_out = decode_persistent_body::<String>(&buf_another_body, &header)
            .expect("Another body decoding failed");
        assert_eq!(another_body, another_body_out);
    }

    #[test]
    fn array_of_arrays() {
        for ctx in CONTEXTS {
            let mut input = &mut [&mut [1u32, 2, 3, 4, 5], &mut [5, 4, 3, 2, 1]];
            let (bytes, handles) = (&mut vec![], &mut vec![]);
            assert!(Encoder::encode_with_context(ctx, bytes, handles, &mut input).is_ok());

            let mut output = <[[u32; 5]; 2]>::new_empty();
            Decoder::decode_with_context(ctx, bytes, handles, &mut output).expect(
                format!(
                    "Array decoding failed\n\
                     bytes: {:X?}",
                    bytes
                )
                .as_str(),
            );

            assert_eq!(
                input,
                output.iter_mut().map(|v| v.as_mut()).collect::<Vec<_>>().as_mut_slice()
            );
        }
    }

    #[test]
    fn xunion_with_out_of_line_data() {
        fidl_xunion! {
            #[derive(Debug, PartialEq)]
            name: XUnion,
            members: [
                Variant {
                    ty: Vec<u8>,
                    ordinal: 1,
                },
            ],
            unknown_member: __UnknownVariant,
        }

        identities![
            XUnion::Variant(vec![1, 2, 3]),
            Some(Box::new(XUnion::Variant(vec![1, 2, 3]))),
            None::<Box<XUnion>>,
        ];
    }

    #[test]
    fn strict_xunion_rejects_unknown_ordinal() {
        fidl_xunion! {
            #[derive(Debug, PartialEq)]
            name: StrictBoolXUnion,
            members: [
                B {
                    ty: bool,
                    ordinal: 12345,
                },
            ],
        }

        for ctx in CONTEXTS {
            let mut input = TestSampleXUnion::U(1);
            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut input).unwrap();

            let mut strict_xunion = StrictBoolXUnion::new_empty();
            let result = Decoder::decode_with_context(ctx, buf, handle_buf, &mut strict_xunion);
            assert_matches!(result, Err(Error::UnknownUnionTag));
        }
    }

    #[test]
    fn xunion_with_64_bit_ordinal() {
        fidl_xunion! {
            #[derive(Debug, Copy, Clone, Eq, PartialEq)]
            name: BigOrdinal,
            members: [
                X {
                    ty: u64,
                    ordinal: 0xffffffffu64,
                },
            ],
        };

        for ctx in CONTEXTS {
            let mut x = BigOrdinal::X(0);
            assert_eq!(x.ordinal(), 0xffffffffu64);
            assert_eq!(encode_decode(ctx, &mut x).ordinal(), 0xffffffffu64);
        }
    }

    #[test]
    fn extra_data_is_disallowed() {
        for ctx in CONTEXTS {
            let mut output = ();
            assert_matches!(
                Decoder::decode_with_context(ctx, &[0], &mut [], &mut output),
                Err(Error::ExtraBytes)
            );
            assert_matches!(
                Decoder::decode_with_context(ctx, &[], &mut [Handle::invalid()], &mut output),
                Err(Error::ExtraHandles)
            );
        }
    }

    #[test]
    fn encode_default_context() {
        let buf = &mut Vec::new();
        Encoder::encode(buf, &mut Vec::new(), &mut 1u8).expect("Encoding failed");
        assert_eq!(&**buf, &[1u8, 0, 0, 0, 0, 0, 0, 0]);
    }
}

#[cfg(target_os = "fuchsia")]
#[cfg(test)]
mod zx_test {
    use super::test::*;
    use super::*;
    use crate::handle::AsHandleRef;
    use fuchsia_zircon as zx;

    #[test]
    fn encode_handle() {
        for ctx in CONTEXTS {
            let mut handle = Handle::from(zx::Port::create().expect("Port creation failed"));
            let raw_handle = handle.raw_handle();

            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut handle)
                .expect("Encoding failed");

            assert!(handle.is_invalid());

            let mut handle_out = Handle::new_empty();
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut handle_out)
                .expect("Decoding failed");

            assert_eq!(raw_handle, handle_out.raw_handle());
        }
    }

    #[test]
    fn encode_decode_table() {
        for ctx in CONTEXTS {
            // create a random handle to encode and then decode.
            let handle = zx::Vmo::create(1024).expect("vmo creation failed");
            let raw_handle = handle.raw_handle();
            let mut starting_table = MyTable {
                num: Some(5),
                num_none: None,
                string: Some("foo".to_string()),
                handle: Some(handle.into_handle()),
            };
            let table_out = encode_decode(ctx, &mut starting_table);
            assert_eq!(table_out.num, Some(5));
            assert_eq!(table_out.num_none, None);
            assert_eq!(table_out.string, Some("foo".to_string()));
            assert_eq!(table_out.handle.unwrap().raw_handle(), raw_handle);
        }
    }

    #[test]
    fn flexible_xunion_unknown_variant_transparent_passthrough() {
        for ctx in CONTEXTS {
            let handle = Handle::from(zx::Port::create().expect("Port creation failed"));
            let raw_handle = handle.raw_handle();

            let mut input = TestSampleXUnionExpanded::SomethinElse(handle);
            // encode expanded and decode as xunion w/ missing variant
            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut input)
                .expect("Encoding TestSampleXUnionExpanded failed");

            let mut intermediate_missing_variant = TestSampleXUnion::new_empty();
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut intermediate_missing_variant)
                .expect("Decoding TestSampleXUnion failed");

            // Ensure we've recorded the unknown variant
            if let TestSampleXUnion::__UnknownVariant { .. } = intermediate_missing_variant {
                // ok
            } else {
                panic!("unexpected variant")
            }

            let buf = &mut Vec::new();
            let handle_buf = &mut Vec::new();
            Encoder::encode_with_context(ctx, buf, handle_buf, &mut intermediate_missing_variant)
                .expect("encoding unknown variant failed");

            let mut out = TestSampleXUnionExpanded::new_empty();
            Decoder::decode_with_context(ctx, buf, handle_buf, &mut out)
                .expect("Decoding final output failed");

            if let TestSampleXUnionExpanded::SomethinElse(handle_out) = out {
                assert_eq!(raw_handle, handle_out.raw_handle());
            } else {
                panic!("wrong final variant")
            }
        }
    }

    #[test]
    fn encode_epitaph() {
        for ctx in CONTEXTS {
            assert_eq!(
                EpitaphBody { error: zx::Status::UNAVAILABLE },
                encode_decode(ctx, &mut EpitaphBody { error: zx::Status::UNAVAILABLE })
            );
        }
    }
}
