//! Conversions from `wasmparser` to `wasm-encoder` to [`Reencode`] parsed wasm.
//!
//! The [`RoundtripReencoder`] allows encoding identical wasm to the parsed
//! input.

use crate::CoreTypeEncoder;
use std::convert::Infallible;

#[cfg(feature = "component-model")]
mod component;

#[cfg(feature = "component-model")]
pub use self::component::*;

#[allow(missing_docs)] // FIXME
pub trait Reencode {
    type Error;

    fn data_index(&mut self, data: u32) -> u32 {
        utils::data_index(self, data)
    }

    fn element_index(&mut self, element: u32) -> u32 {
        utils::element_index(self, element)
    }

    fn function_index(&mut self, func: u32) -> u32 {
        utils::function_index(self, func)
    }

    fn global_index(&mut self, global: u32) -> u32 {
        utils::global_index(self, global)
    }

    fn memory_index(&mut self, memory: u32) -> u32 {
        utils::memory_index(self, memory)
    }

    fn table_index(&mut self, table: u32) -> u32 {
        utils::table_index(self, table)
    }

    fn tag_index(&mut self, tag: u32) -> u32 {
        utils::tag_index(self, tag)
    }

    fn type_index(&mut self, ty: u32) -> u32 {
        utils::type_index(self, ty)
    }

    fn type_index_unpacked(
        &mut self,
        ty: wasmparser::UnpackedIndex,
    ) -> Result<u32, Error<Self::Error>> {
        utils::type_index_unpacked(self, ty)
    }

    fn external_index(&mut self, kind: wasmparser::ExternalKind, index: u32) -> u32 {
        match kind {
            wasmparser::ExternalKind::Func => self.function_index(index),
            wasmparser::ExternalKind::Table => self.table_index(index),
            wasmparser::ExternalKind::Memory => self.memory_index(index),
            wasmparser::ExternalKind::Global => self.global_index(index),
            wasmparser::ExternalKind::Tag => self.tag_index(index),
        }
    }

    fn abstract_heap_type(
        &mut self,
        value: wasmparser::AbstractHeapType,
    ) -> crate::AbstractHeapType {
        utils::abstract_heap_type(self, value)
    }

    fn array_type(
        &mut self,
        array_ty: wasmparser::ArrayType,
    ) -> Result<crate::ArrayType, Error<Self::Error>> {
        utils::array_type(self, array_ty)
    }

    fn block_type(
        &mut self,
        arg: wasmparser::BlockType,
    ) -> Result<crate::BlockType, Error<Self::Error>> {
        utils::block_type(self, arg)
    }

    fn const_expr(
        &mut self,
        const_expr: wasmparser::ConstExpr,
    ) -> Result<crate::ConstExpr, Error<Self::Error>> {
        utils::const_expr(self, const_expr)
    }

    fn catch(&mut self, arg: wasmparser::Catch) -> crate::Catch {
        utils::catch(self, arg)
    }

    fn composite_type(
        &mut self,
        composite_ty: wasmparser::CompositeType,
    ) -> Result<crate::CompositeType, Error<Self::Error>> {
        utils::composite_type(self, composite_ty)
    }

    fn entity_type(
        &mut self,
        type_ref: wasmparser::TypeRef,
    ) -> Result<crate::EntityType, Error<Self::Error>> {
        utils::entity_type(self, type_ref)
    }

    fn export_kind(&mut self, external_kind: wasmparser::ExternalKind) -> crate::ExportKind {
        utils::export_kind(self, external_kind)
    }

    fn field_type(
        &mut self,
        field_ty: wasmparser::FieldType,
    ) -> Result<crate::FieldType, Error<Self::Error>> {
        utils::field_type(self, field_ty)
    }

    fn func_type(
        &mut self,
        func_ty: wasmparser::FuncType,
    ) -> Result<crate::FuncType, Error<Self::Error>> {
        utils::func_type(self, func_ty)
    }

    fn cont_type(
        &mut self,
        cont_ty: wasmparser::ContType,
    ) -> Result<crate::ContType, Error<Self::Error>> {
        utils::cont_type(self, cont_ty)
    }

    fn global_type(
        &mut self,
        global_ty: wasmparser::GlobalType,
    ) -> Result<crate::GlobalType, Error<Self::Error>> {
        utils::global_type(self, global_ty)
    }

    fn handle(&mut self, on: wasmparser::Handle) -> crate::Handle {
        utils::handle(self, on)
    }

    fn heap_type(
        &mut self,
        heap_type: wasmparser::HeapType,
    ) -> Result<crate::HeapType, Error<Self::Error>> {
        utils::heap_type(self, heap_type)
    }

    fn instruction<'a>(
        &mut self,
        arg: wasmparser::Operator<'a>,
    ) -> Result<crate::Instruction<'a>, Error<Self::Error>> {
        utils::instruction(self, arg)
    }

    fn memory_type(&mut self, memory_ty: wasmparser::MemoryType) -> crate::MemoryType {
        utils::memory_type(self, memory_ty)
    }

    fn mem_arg(&mut self, arg: wasmparser::MemArg) -> crate::MemArg {
        utils::mem_arg(self, arg)
    }

    fn ordering(&mut self, arg: wasmparser::Ordering) -> crate::Ordering {
        utils::ordering(self, arg)
    }

    fn ref_type(
        &mut self,
        ref_type: wasmparser::RefType,
    ) -> Result<crate::RefType, Error<Self::Error>> {
        utils::ref_type(self, ref_type)
    }

    fn storage_type(
        &mut self,
        storage_ty: wasmparser::StorageType,
    ) -> Result<crate::StorageType, Error<Self::Error>> {
        utils::storage_type(self, storage_ty)
    }

    fn struct_type(
        &mut self,
        struct_ty: wasmparser::StructType,
    ) -> Result<crate::StructType, Error<Self::Error>> {
        utils::struct_type(self, struct_ty)
    }

    fn sub_type(
        &mut self,
        sub_ty: wasmparser::SubType,
    ) -> Result<crate::SubType, Error<Self::Error>> {
        utils::sub_type(self, sub_ty)
    }

    fn table_type(
        &mut self,
        table_ty: wasmparser::TableType,
    ) -> Result<crate::TableType, Error<Self::Error>> {
        utils::table_type(self, table_ty)
    }

    fn tag_kind(&mut self, kind: wasmparser::TagKind) -> crate::TagKind {
        utils::tag_kind(self, kind)
    }

    fn tag_type(&mut self, tag_ty: wasmparser::TagType) -> crate::TagType {
        utils::tag_type(self, tag_ty)
    }

    fn val_type(
        &mut self,
        val_ty: wasmparser::ValType,
    ) -> Result<crate::ValType, Error<Self::Error>> {
        utils::val_type(self, val_ty)
    }

    /// Parses the input `section` given from the `wasmparser` crate and
    /// adds the custom section to the `module`.
    fn parse_custom_section(
        &mut self,
        module: &mut crate::Module,
        section: wasmparser::CustomSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_custom_section(self, module, section)
    }

    /// Converts the input `section` given from the `wasmparser` crate into an
    /// encoded custom section.
    fn custom_section<'a>(
        &mut self,
        section: wasmparser::CustomSectionReader<'a>,
    ) -> crate::CustomSection<'a> {
        utils::custom_section(self, section)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the code to the `code` section.
    fn parse_code_section(
        &mut self,
        code: &mut crate::CodeSection,
        section: wasmparser::CodeSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_code_section(self, code, section)
    }

    /// Parses a single [`wasmparser::FunctionBody`] and adds it to the `code` section.
    fn parse_function_body(
        &mut self,
        code: &mut crate::CodeSection,
        func: wasmparser::FunctionBody<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_function_body(self, code, func)
    }

    /// Create a new [`crate::Function`] by parsing the locals declarations from the
    /// provided [`wasmparser::FunctionBody`].
    fn new_function_with_parsed_locals(
        &mut self,
        func: &wasmparser::FunctionBody<'_>,
    ) -> Result<crate::Function, Error<Self::Error>> {
        utils::new_function_with_parsed_locals(self, func)
    }

    /// Parses a single instruction from `reader` and adds it to `function`.
    fn parse_instruction<'a>(
        &mut self,
        reader: &mut wasmparser::OperatorsReader<'a>,
    ) -> Result<crate::Instruction<'a>, Error<Self::Error>> {
        utils::parse_instruction(self, reader)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the data to the `data` section.
    fn parse_data_section(
        &mut self,
        data: &mut crate::DataSection,
        section: wasmparser::DataSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_data_section(self, data, section)
    }

    /// Parses a single [`wasmparser::Data`] and adds it to the `data` section.
    fn parse_data(
        &mut self,
        data: &mut crate::DataSection,
        datum: wasmparser::Data<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_data(self, data, datum)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the elements to the `element` section.
    fn parse_element_section(
        &mut self,
        elements: &mut crate::ElementSection,
        section: wasmparser::ElementSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_element_section(self, elements, section)
    }

    /// Parses the single [`wasmparser::Element`] provided and adds it to the
    /// `element` section.
    fn parse_element(
        &mut self,
        elements: &mut crate::ElementSection,
        element: wasmparser::Element<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_element(self, elements, element)
    }

    fn element_items<'a>(
        &mut self,
        items: wasmparser::ElementItems<'a>,
    ) -> Result<crate::Elements<'a>, Error<Self::Error>> {
        utils::element_items(self, items)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the exports to the `exports` section.
    fn parse_export_section(
        &mut self,
        exports: &mut crate::ExportSection,
        section: wasmparser::ExportSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_export_section(self, exports, section)
    }

    /// Parses the single [`wasmparser::Export`] provided and adds it to the
    /// `exports` section.
    fn parse_export(&mut self, exports: &mut crate::ExportSection, export: wasmparser::Export<'_>) {
        utils::parse_export(self, exports, export)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the functions to the `functions` section.
    fn parse_function_section(
        &mut self,
        functions: &mut crate::FunctionSection,
        section: wasmparser::FunctionSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_function_section(self, functions, section)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the globals to the `globals` section.
    fn parse_global_section(
        &mut self,
        globals: &mut crate::GlobalSection,
        section: wasmparser::GlobalSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_global_section(self, globals, section)
    }

    /// Parses the single [`wasmparser::Global`] provided and adds it to the
    /// `globals` section.
    fn parse_global(
        &mut self,
        globals: &mut crate::GlobalSection,
        global: wasmparser::Global<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_global(self, globals, global)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the imports to the `import` section.
    fn parse_import_section(
        &mut self,
        imports: &mut crate::ImportSection,
        section: wasmparser::ImportSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_import_section(self, imports, section)
    }

    /// Parses the single [`wasmparser::Import`] provided and adds it to the
    /// `import` section.
    fn parse_import(
        &mut self,
        imports: &mut crate::ImportSection,
        import: wasmparser::Import<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_import(self, imports, import)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the memories to the `memories` section.
    fn parse_memory_section(
        &mut self,
        memories: &mut crate::MemorySection,
        section: wasmparser::MemorySectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_memory_section(self, memories, section)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the tables to the `tables` section.
    fn parse_table_section(
        &mut self,
        tables: &mut crate::TableSection,
        section: wasmparser::TableSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_table_section(self, tables, section)
    }

    /// Parses a single [`wasmparser::Table`] and adds it to the `tables` section.
    fn parse_table(
        &mut self,
        tables: &mut crate::TableSection,
        table: wasmparser::Table<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_table(self, tables, table)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the tags to the `tags` section.
    fn parse_tag_section(
        &mut self,
        tags: &mut crate::TagSection,
        section: wasmparser::TagSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_tag_section(self, tags, section)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the types to the `types` section.
    fn parse_type_section(
        &mut self,
        types: &mut crate::TypeSection,
        section: wasmparser::TypeSectionReader<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_type_section(self, types, section)
    }

    /// Parses a single [`wasmparser::RecGroup`] and adds it to the `types` section.
    fn parse_recursive_type_group(
        &mut self,
        encoder: CoreTypeEncoder,
        rec_group: wasmparser::RecGroup,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_recursive_type_group(self, encoder, rec_group)
    }

    fn parse_unknown_section(
        &mut self,
        module: &mut crate::Module,
        id: u8,
        contents: &[u8],
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_unknown_section(self, module, id, contents)
    }

    /// A hook method that is called inside [`Reencode::parse_core_module`]
    /// before and after every non-custom core wasm section.
    ///
    /// This method can be used to insert new custom sections in between those
    /// sections, or to detect when a non-custom section is missing and insert
    /// it in the [proper order].
    ///
    /// The `after` parameter is `None` iff the hook is called before the first
    /// non-custom section, and `Some(s)` afterwards, where `s` is the
    /// [`SectionId`] of the previous non-custom section.
    ///
    /// The `before` parameter is `None` iff the hook is called after the last
    /// non-custom section, and `Some(s)` beforehand, where `s` is the
    /// [`SectionId`] of the following non-custom section.
    ///
    /// [proper order]: https://webassembly.github.io/spec/core/binary/modules.html#binary-module
    /// [`SectionId`]: crate::SectionId
    fn intersperse_section_hook(
        &mut self,
        module: &mut crate::Module,
        after: Option<crate::SectionId>,
        before: Option<crate::SectionId>,
    ) -> Result<(), Error<Self::Error>> {
        utils::intersperse_section_hook(self, module, after, before)
    }

    fn parse_core_module(
        &mut self,
        module: &mut crate::Module,
        parser: wasmparser::Parser,
        data: &[u8],
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_core_module(self, module, parser, data)
    }

    fn custom_name_section(
        &mut self,
        section: wasmparser::NameSectionReader<'_>,
    ) -> Result<crate::NameSection, Error<Self::Error>> {
        utils::custom_name_section(self, section)
    }

    fn parse_custom_name_subsection(
        &mut self,
        names: &mut crate::NameSection,
        section: wasmparser::Name<'_>,
    ) -> Result<(), Error<Self::Error>> {
        utils::parse_custom_name_subsection(self, names, section)
    }

    fn data_count(&mut self, count: u32) -> u32 {
        count
    }

    fn start_section(&mut self, start: u32) -> u32 {
        self.function_index(start)
    }
}

/// An error when re-encoding from `wasmparser` to `wasm-encoder`.
#[derive(Debug)]
pub enum Error<E = Infallible> {
    /// There was a type reference that was canonicalized and no longer
    /// references an index into a module's types space, so we cannot encode it
    /// into a Wasm binary again.
    CanonicalizedHeapTypeReference,
    /// The const expression is invalid: not actually constant or something like
    /// that.
    InvalidConstExpr,
    /// The code section size listed was not valid for the wasm binary provided.
    InvalidCodeSectionSize,
    /// There was a section that does not belong into a core wasm module.
    UnexpectedNonCoreModuleSection,
    /// There was a section that does not belong into a compoennt module.
    UnexpectedNonComponentSection,
    /// A core type definition was found in a component that's not supported.
    UnsupportedCoreTypeInComponent,
    /// There was an error when parsing.
    ParseError(wasmparser::BinaryReaderError),
    /// There was a user-defined error when re-encoding.
    UserError(E),
}

impl<E> From<wasmparser::BinaryReaderError> for Error<E> {
    fn from(err: wasmparser::BinaryReaderError) -> Self {
        Self::ParseError(err)
    }
}

impl<E: std::fmt::Display> std::fmt::Display for Error<E> {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            Self::ParseError(_e) => {
                write!(fmt, "There was an error when parsing")
            }
            Self::UserError(e) => write!(fmt, "{e}"),
            Self::InvalidConstExpr => write!(fmt, "The const expression was invalid"),
            Self::UnexpectedNonCoreModuleSection => write!(
                fmt,
                "There was a section that does not belong into a core wasm module"
            ),
            Self::UnexpectedNonComponentSection => write!(
                fmt,
                "There was a section that does not belong into a component"
            ),
            Self::CanonicalizedHeapTypeReference => write!(
                fmt,
                "There was a canonicalized heap type reference without type index information"
            ),
            Self::UnsupportedCoreTypeInComponent => {
                fmt.write_str("unsupported core type in a component")
            }
            Self::InvalidCodeSectionSize => fmt.write_str("invalid code section size"),
        }
    }
}

impl<E: 'static + std::error::Error> std::error::Error for Error<E> {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            Self::ParseError(e) => Some(e),
            Self::UserError(e) => Some(e),
            Self::InvalidConstExpr
            | Self::CanonicalizedHeapTypeReference
            | Self::UnexpectedNonCoreModuleSection
            | Self::UnexpectedNonComponentSection
            | Self::UnsupportedCoreTypeInComponent
            | Self::InvalidCodeSectionSize => None,
        }
    }
}

/// Reencodes `wasmparser` into `wasm-encoder` so that the encoded wasm is
/// identical to the input and can be parsed and encoded again.
#[derive(Debug)]
pub struct RoundtripReencoder;

impl Reencode for RoundtripReencoder {
    type Error = Infallible;
}

#[allow(missing_docs)] // FIXME
pub mod utils {
    use super::{Error, Reencode};
    use crate::{CoreTypeEncoder, Encode};
    use std::ops::Range;

    pub fn parse_core_module<T: ?Sized + Reencode>(
        reencoder: &mut T,
        module: &mut crate::Module,
        parser: wasmparser::Parser,
        data: &[u8],
    ) -> Result<(), Error<T::Error>> {
        fn handle_intersperse_section_hook<T: ?Sized + Reencode>(
            reencoder: &mut T,
            module: &mut crate::Module,
            last_section: &mut Option<crate::SectionId>,
            next_section: Option<crate::SectionId>,
        ) -> Result<(), Error<T::Error>> {
            let after = std::mem::replace(last_section, next_section);
            let before = next_section;
            reencoder.intersperse_section_hook(module, after, before)
        }

        // Convert from `range` to a byte range within `data` while
        // accounting for various offsets. Then create a
        // `CodeSectionReader` (which notably the payload does not
        // give us here) and recurse with that. This means that
        // users overridding `parse_code_section` always get that
        // function called.
        let orig_offset = parser.offset() as usize;
        let get_original_section = |range: Range<usize>| {
            data.get(range.start - orig_offset..range.end - orig_offset)
                .ok_or(Error::InvalidCodeSectionSize)
        };
        let mut last_section = None;

        for section in parser.parse_all(data) {
            match section? {
                wasmparser::Payload::Version {
                    encoding: wasmparser::Encoding::Module,
                    ..
                } => (),
                wasmparser::Payload::Version { .. } => {
                    return Err(Error::UnexpectedNonCoreModuleSection)
                }
                wasmparser::Payload::TypeSection(section) => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Type),
                    )?;
                    let mut types = crate::TypeSection::new();
                    reencoder.parse_type_section(&mut types, section)?;
                    module.section(&types);
                }
                wasmparser::Payload::ImportSection(section) => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Import),
                    )?;
                    let mut imports = crate::ImportSection::new();
                    reencoder.parse_import_section(&mut imports, section)?;
                    module.section(&imports);
                }
                wasmparser::Payload::FunctionSection(section) => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Function),
                    )?;
                    let mut functions = crate::FunctionSection::new();
                    reencoder.parse_function_section(&mut functions, section)?;
                    module.section(&functions);
                }
                wasmparser::Payload::TableSection(section) => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Table),
                    )?;
                    let mut tables = crate::TableSection::new();
                    reencoder.parse_table_section(&mut tables, section)?;
                    module.section(&tables);
                }
                wasmparser::Payload::MemorySection(section) => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Memory),
                    )?;
                    let mut memories = crate::MemorySection::new();
                    reencoder.parse_memory_section(&mut memories, section)?;
                    module.section(&memories);
                }
                wasmparser::Payload::TagSection(section) => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Tag),
                    )?;
                    let mut tags = crate::TagSection::new();
                    reencoder.parse_tag_section(&mut tags, section)?;
                    module.section(&tags);
                }
                wasmparser::Payload::GlobalSection(section) => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Global),
                    )?;
                    let mut globals = crate::GlobalSection::new();
                    reencoder.parse_global_section(&mut globals, section)?;
                    module.section(&globals);
                }
                wasmparser::Payload::ExportSection(section) => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Export),
                    )?;
                    let mut exports = crate::ExportSection::new();
                    reencoder.parse_export_section(&mut exports, section)?;
                    module.section(&exports);
                }
                wasmparser::Payload::StartSection { func, .. } => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Start),
                    )?;
                    module.section(&crate::StartSection {
                        function_index: reencoder.start_section(func),
                    });
                }
                wasmparser::Payload::ElementSection(section) => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Element),
                    )?;
                    let mut elements = crate::ElementSection::new();
                    reencoder.parse_element_section(&mut elements, section)?;
                    module.section(&elements);
                }
                wasmparser::Payload::DataCountSection { count, .. } => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::DataCount),
                    )?;
                    let count = reencoder.data_count(count);
                    module.section(&crate::DataCountSection { count });
                }
                wasmparser::Payload::DataSection(section) => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Data),
                    )?;
                    let mut data = crate::DataSection::new();
                    reencoder.parse_data_section(&mut data, section)?;
                    module.section(&data);
                }
                wasmparser::Payload::CodeSectionStart { range, .. } => {
                    handle_intersperse_section_hook(
                        reencoder,
                        module,
                        &mut last_section,
                        Some(crate::SectionId::Code),
                    )?;
                    let mut codes = crate::CodeSection::new();

                    // Convert from `range` to a byte range within `data` while
                    // accounting for various offsets. Then create a
                    // `CodeSectionReader` (which notably the payload does not
                    // give us here) and recurse with that. This means that
                    // users overridding `parse_code_section` always get that
                    // function called.
                    let section = get_original_section(range.clone())?;
                    let reader = wasmparser::BinaryReader::new(section, range.start);
                    let section = wasmparser::CodeSectionReader::new(reader)?;
                    reencoder.parse_code_section(&mut codes, section)?;
                    module.section(&codes);
                }

                // Parsing of code section entries (function bodies) happens
                // above during the handling of the code section. That means
                // that we just skip all these payloads.
                wasmparser::Payload::CodeSectionEntry(_) => {}

                #[cfg(feature = "component-model")]
                wasmparser::Payload::ModuleSection { .. }
                | wasmparser::Payload::InstanceSection(_)
                | wasmparser::Payload::CoreTypeSection(_)
                | wasmparser::Payload::ComponentSection { .. }
                | wasmparser::Payload::ComponentInstanceSection(_)
                | wasmparser::Payload::ComponentAliasSection(_)
                | wasmparser::Payload::ComponentTypeSection(_)
                | wasmparser::Payload::ComponentCanonicalSection(_)
                | wasmparser::Payload::ComponentStartSection { .. }
                | wasmparser::Payload::ComponentImportSection(_)
                | wasmparser::Payload::ComponentExportSection(_) => {
                    return Err(Error::UnexpectedNonCoreModuleSection)
                }
                wasmparser::Payload::CustomSection(section) => {
                    reencoder.parse_custom_section(module, section)?;
                }
                wasmparser::Payload::End(_) => {
                    handle_intersperse_section_hook(reencoder, module, &mut last_section, None)?;
                }

                other => match other.as_section() {
                    Some((id, range)) => {
                        let section = get_original_section(range)?;
                        reencoder.parse_unknown_section(module, id, section)?;
                    }
                    None => unreachable!(),
                },
            }
        }

        Ok(())
    }

    /// A hook method that is called inside [`Reencode::parse_core_module`]
    /// before and after every non-custom core wasm section.
    ///
    /// This method can be used to insert new custom sections in between those
    /// sections, or to detect when a non-custom section is missing and insert
    /// it in the [proper order].
    ///
    /// The `after` parameter is `None` iff the hook is called before the first
    /// non-custom section, and `Some(s)` afterwards, where `s` is the
    /// [`SectionId`] of the previous non-custom section.
    ///
    /// The `before` parameter is `None` iff the hook is called after the last
    /// non-custom section, and `Some(s)` beforehand, where `s` is the
    /// [`SectionId`] of the following non-custom section.
    ///
    /// [proper order]: https://webassembly.github.io/spec/core/binary/modules.html#binary-module
    /// [`SectionId`]: crate::SectionId
    pub fn intersperse_section_hook<T: ?Sized + Reencode>(
        _reencoder: &mut T,
        _module: &mut crate::Module,
        _after: Option<crate::SectionId>,
        _before: Option<crate::SectionId>,
    ) -> Result<(), Error<T::Error>> {
        Ok(())
    }

    pub fn memory_index<T: ?Sized + Reencode>(_reencoder: &mut T, memory: u32) -> u32 {
        memory
    }

    pub fn mem_arg<T: ?Sized + Reencode>(
        reencoder: &mut T,
        arg: wasmparser::MemArg,
    ) -> crate::MemArg {
        crate::MemArg {
            offset: arg.offset,
            align: arg.align.into(),
            memory_index: reencoder.memory_index(arg.memory),
        }
    }

    pub fn ordering<T: ?Sized + Reencode>(
        _reencoder: &mut T,
        arg: wasmparser::Ordering,
    ) -> crate::Ordering {
        match arg {
            wasmparser::Ordering::SeqCst => crate::Ordering::SeqCst,
            wasmparser::Ordering::AcqRel => crate::Ordering::AcqRel,
        }
    }

    pub fn function_index<T: ?Sized + Reencode>(_reencoder: &mut T, func: u32) -> u32 {
        func
    }

    pub fn tag_index<T: ?Sized + Reencode>(_reencoder: &mut T, tag: u32) -> u32 {
        tag
    }

    pub fn catch<T: ?Sized + Reencode>(reencoder: &mut T, arg: wasmparser::Catch) -> crate::Catch {
        match arg {
            wasmparser::Catch::One { tag, label } => crate::Catch::One {
                tag: reencoder.tag_index(tag),
                label,
            },
            wasmparser::Catch::OneRef { tag, label } => crate::Catch::OneRef {
                tag: reencoder.tag_index(tag),
                label,
            },
            wasmparser::Catch::All { label } => crate::Catch::All { label },
            wasmparser::Catch::AllRef { label } => crate::Catch::AllRef { label },
        }
    }

    pub fn handle<T: ?Sized + Reencode>(
        reencoder: &mut T,
        arg: wasmparser::Handle,
    ) -> crate::Handle {
        match arg {
            wasmparser::Handle::OnLabel { tag, label } => crate::Handle::OnLabel {
                tag: reencoder.tag_index(tag),
                label,
            },
            wasmparser::Handle::OnSwitch { tag } => crate::Handle::OnSwitch {
                tag: reencoder.tag_index(tag),
            },
        }
    }

    /// Parses the input `section` given from the `wasmparser` crate and
    /// adds the custom section to the `module`.
    pub fn parse_custom_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        module: &mut crate::Module,
        section: wasmparser::CustomSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        match section.as_known() {
            wasmparser::KnownCustom::Name(name) => {
                module.section(&reencoder.custom_name_section(name)?);
            }
            _ => {
                module.section(&reencoder.custom_section(section));
            }
        }
        Ok(())
    }

    /// Converts the input `section` given from the `wasmparser` crate into an
    /// encoded custom section.
    pub fn custom_section<'a, T: ?Sized + Reencode>(
        _reencoder: &mut T,
        section: wasmparser::CustomSectionReader<'a>,
    ) -> crate::CustomSection<'a> {
        crate::CustomSection {
            data: section.data().into(),
            name: section.name().into(),
        }
    }

    pub fn export_kind<T: ?Sized + Reencode>(
        _reencoder: &mut T,
        external_kind: wasmparser::ExternalKind,
    ) -> crate::ExportKind {
        match external_kind {
            wasmparser::ExternalKind::Func => crate::ExportKind::Func,
            wasmparser::ExternalKind::Table => crate::ExportKind::Table,
            wasmparser::ExternalKind::Memory => crate::ExportKind::Memory,
            wasmparser::ExternalKind::Global => crate::ExportKind::Global,
            wasmparser::ExternalKind::Tag => crate::ExportKind::Tag,
        }
    }

    pub fn memory_type<T: ?Sized + Reencode>(
        _reencoder: &mut T,
        memory_ty: wasmparser::MemoryType,
    ) -> crate::MemoryType {
        crate::MemoryType {
            minimum: memory_ty.initial,
            maximum: memory_ty.maximum,
            memory64: memory_ty.memory64,
            shared: memory_ty.shared,
            page_size_log2: memory_ty.page_size_log2,
        }
    }

    pub fn tag_kind<T: ?Sized + Reencode>(
        _reencoder: &mut T,
        kind: wasmparser::TagKind,
    ) -> crate::TagKind {
        match kind {
            wasmparser::TagKind::Exception => crate::TagKind::Exception,
        }
    }

    pub fn type_index<T: ?Sized + Reencode>(_reencoder: &mut T, ty: u32) -> u32 {
        ty
    }

    pub fn type_index_unpacked<T: ?Sized + Reencode>(
        reencoder: &mut T,
        ty: wasmparser::UnpackedIndex,
    ) -> Result<u32, Error<T::Error>> {
        ty.as_module_index()
            .map(|ty| reencoder.type_index(ty))
            .ok_or(Error::CanonicalizedHeapTypeReference)
    }

    pub fn tag_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        tag_ty: wasmparser::TagType,
    ) -> crate::TagType {
        crate::TagType {
            kind: reencoder.tag_kind(tag_ty.kind),
            func_type_idx: reencoder.type_index(tag_ty.func_type_idx),
        }
    }

    pub fn abstract_heap_type<T: ?Sized + Reencode>(
        _reencoder: &mut T,
        value: wasmparser::AbstractHeapType,
    ) -> crate::AbstractHeapType {
        use wasmparser::AbstractHeapType::*;
        match value {
            Func => crate::AbstractHeapType::Func,
            Extern => crate::AbstractHeapType::Extern,
            Any => crate::AbstractHeapType::Any,
            None => crate::AbstractHeapType::None,
            NoExtern => crate::AbstractHeapType::NoExtern,
            NoFunc => crate::AbstractHeapType::NoFunc,
            Eq => crate::AbstractHeapType::Eq,
            Struct => crate::AbstractHeapType::Struct,
            Array => crate::AbstractHeapType::Array,
            I31 => crate::AbstractHeapType::I31,
            Exn => crate::AbstractHeapType::Exn,
            NoExn => crate::AbstractHeapType::NoExn,
            Cont => crate::AbstractHeapType::Cont,
            NoCont => crate::AbstractHeapType::NoCont,
        }
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the types to the `types` section.
    pub fn parse_type_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        types: &mut crate::TypeSection,
        section: wasmparser::TypeSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for rec_group in section {
            reencoder.parse_recursive_type_group(types.ty(), rec_group?)?;
        }
        Ok(())
    }

    /// Parses a single [`wasmparser::RecGroup`] and adds it to the `types` section.
    pub fn parse_recursive_type_group<T: ?Sized + Reencode>(
        reencoder: &mut T,
        encoder: CoreTypeEncoder,
        rec_group: wasmparser::RecGroup,
    ) -> Result<(), Error<T::Error>> {
        if rec_group.is_explicit_rec_group() {
            let subtypes = rec_group
                .into_types()
                .map(|t| reencoder.sub_type(t))
                .collect::<Result<Vec<_>, _>>()?;
            encoder.rec(subtypes);
        } else {
            let ty = rec_group.into_types().next().unwrap();
            encoder.subtype(&reencoder.sub_type(ty)?);
        }
        Ok(())
    }

    pub fn sub_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        sub_ty: wasmparser::SubType,
    ) -> Result<crate::SubType, Error<T::Error>> {
        Ok(crate::SubType {
            is_final: sub_ty.is_final,
            supertype_idx: sub_ty
                .supertype_idx
                .map(|i| reencoder.type_index_unpacked(i.unpack()))
                .transpose()?,
            composite_type: reencoder.composite_type(sub_ty.composite_type)?,
        })
    }

    pub fn composite_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        composite_ty: wasmparser::CompositeType,
    ) -> Result<crate::CompositeType, Error<T::Error>> {
        let inner = match composite_ty.inner {
            wasmparser::CompositeInnerType::Func(f) => {
                crate::CompositeInnerType::Func(reencoder.func_type(f)?)
            }
            wasmparser::CompositeInnerType::Array(a) => {
                crate::CompositeInnerType::Array(reencoder.array_type(a)?)
            }
            wasmparser::CompositeInnerType::Struct(s) => {
                crate::CompositeInnerType::Struct(reencoder.struct_type(s)?)
            }
            wasmparser::CompositeInnerType::Cont(c) => {
                crate::CompositeInnerType::Cont(reencoder.cont_type(c)?)
            }
        };
        Ok(crate::CompositeType {
            inner,
            shared: composite_ty.shared,
        })
    }

    pub fn func_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        func_ty: wasmparser::FuncType,
    ) -> Result<crate::FuncType, Error<T::Error>> {
        let mut buf = Vec::with_capacity(func_ty.params().len() + func_ty.results().len());
        for ty in func_ty.params().iter().chain(func_ty.results()).copied() {
            buf.push(reencoder.val_type(ty)?);
        }
        Ok(crate::FuncType::from_parts(
            buf.into(),
            func_ty.params().len(),
        ))
    }

    pub fn array_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        array_ty: wasmparser::ArrayType,
    ) -> Result<crate::ArrayType, Error<T::Error>> {
        Ok(crate::ArrayType(reencoder.field_type(array_ty.0)?))
    }

    pub fn struct_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        struct_ty: wasmparser::StructType,
    ) -> Result<crate::StructType, Error<T::Error>> {
        Ok(crate::StructType {
            fields: struct_ty
                .fields
                .iter()
                .map(|field_ty| reencoder.field_type(*field_ty))
                .collect::<Result<_, _>>()?,
        })
    }

    pub fn field_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        field_ty: wasmparser::FieldType,
    ) -> Result<crate::FieldType, Error<T::Error>> {
        Ok(crate::FieldType {
            element_type: reencoder.storage_type(field_ty.element_type)?,
            mutable: field_ty.mutable,
        })
    }

    pub fn storage_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        storage_ty: wasmparser::StorageType,
    ) -> Result<crate::StorageType, Error<T::Error>> {
        Ok(match storage_ty {
            wasmparser::StorageType::I8 => crate::StorageType::I8,
            wasmparser::StorageType::I16 => crate::StorageType::I16,
            wasmparser::StorageType::Val(v) => crate::StorageType::Val(reencoder.val_type(v)?),
        })
    }

    pub fn cont_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        cont_ty: wasmparser::ContType,
    ) -> Result<crate::ContType, Error<T::Error>> {
        Ok(crate::ContType(
            reencoder.type_index_unpacked(cont_ty.0.unpack())?,
        ))
    }

    pub fn val_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        val_ty: wasmparser::ValType,
    ) -> Result<crate::ValType, Error<T::Error>> {
        Ok(match val_ty {
            wasmparser::ValType::I32 => crate::ValType::I32,
            wasmparser::ValType::I64 => crate::ValType::I64,
            wasmparser::ValType::F32 => crate::ValType::F32,
            wasmparser::ValType::F64 => crate::ValType::F64,
            wasmparser::ValType::V128 => crate::ValType::V128,
            wasmparser::ValType::Ref(r) => crate::ValType::Ref(reencoder.ref_type(r)?),
        })
    }

    pub fn ref_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        ref_type: wasmparser::RefType,
    ) -> Result<crate::RefType, Error<T::Error>> {
        Ok(crate::RefType {
            nullable: ref_type.is_nullable(),
            heap_type: reencoder.heap_type(ref_type.heap_type())?,
        })
    }

    pub fn heap_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        heap_type: wasmparser::HeapType,
    ) -> Result<crate::HeapType, Error<T::Error>> {
        Ok(match heap_type {
            wasmparser::HeapType::Concrete(i) => {
                crate::HeapType::Concrete(reencoder.type_index_unpacked(i)?)
            }
            wasmparser::HeapType::Abstract { shared, ty } => crate::HeapType::Abstract {
                shared,
                ty: reencoder.abstract_heap_type(ty),
            },
        })
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the tables to the `tables` section.
    pub fn parse_table_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        tables: &mut crate::TableSection,
        section: wasmparser::TableSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for table in section {
            reencoder.parse_table(tables, table?)?;
        }
        Ok(())
    }

    /// Parses a single [`wasmparser::Table`] and adds it to the `tables` section.
    pub fn parse_table<T: ?Sized + Reencode>(
        reencoder: &mut T,
        tables: &mut crate::TableSection,
        table: wasmparser::Table<'_>,
    ) -> Result<(), Error<T::Error>> {
        let ty = reencoder.table_type(table.ty)?;
        match table.init {
            wasmparser::TableInit::RefNull => {
                tables.table(ty);
            }
            wasmparser::TableInit::Expr(e) => {
                tables.table_with_init(ty, &reencoder.const_expr(e)?);
            }
        }
        Ok(())
    }

    pub fn table_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        table_ty: wasmparser::TableType,
    ) -> Result<crate::TableType, Error<T::Error>> {
        Ok(crate::TableType {
            element_type: reencoder.ref_type(table_ty.element_type)?,
            minimum: table_ty.initial,
            maximum: table_ty.maximum,
            table64: table_ty.table64,
            shared: table_ty.shared,
        })
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the tags to the `tags` section.
    pub fn parse_tag_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        tags: &mut crate::TagSection,
        section: wasmparser::TagSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for tag in section {
            let tag = tag?;
            tags.tag(reencoder.tag_type(tag));
        }
        Ok(())
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the exports to the `exports` section.
    pub fn parse_export_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        exports: &mut crate::ExportSection,
        section: wasmparser::ExportSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for export in section {
            reencoder.parse_export(exports, export?);
        }
        Ok(())
    }

    /// Parses the single [`wasmparser::Export`] provided and adds it to the
    /// `exports` section.
    pub fn parse_export<T: ?Sized + Reencode>(
        reencoder: &mut T,
        exports: &mut crate::ExportSection,
        export: wasmparser::Export<'_>,
    ) {
        exports.export(
            export.name,
            reencoder.export_kind(export.kind),
            reencoder.external_index(export.kind, export.index),
        );
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the globals to the `globals` section.
    pub fn parse_global_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        globals: &mut crate::GlobalSection,
        section: wasmparser::GlobalSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for global in section {
            reencoder.parse_global(globals, global?)?;
        }
        Ok(())
    }

    /// Parses the single [`wasmparser::Global`] provided and adds it to the
    /// `globals` section.
    pub fn parse_global<T: ?Sized + Reencode>(
        reencoder: &mut T,
        globals: &mut crate::GlobalSection,
        global: wasmparser::Global<'_>,
    ) -> Result<(), Error<T::Error>> {
        globals.global(
            reencoder.global_type(global.ty)?,
            &reencoder.const_expr(global.init_expr)?,
        );
        Ok(())
    }

    pub fn global_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        global_ty: wasmparser::GlobalType,
    ) -> Result<crate::GlobalType, Error<T::Error>> {
        Ok(crate::GlobalType {
            val_type: reencoder.val_type(global_ty.content_type)?,
            mutable: global_ty.mutable,
            shared: global_ty.shared,
        })
    }

    pub fn entity_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        type_ref: wasmparser::TypeRef,
    ) -> Result<crate::EntityType, Error<T::Error>> {
        Ok(match type_ref {
            wasmparser::TypeRef::Func(i) => crate::EntityType::Function(reencoder.type_index(i)),
            wasmparser::TypeRef::Table(t) => crate::EntityType::Table(reencoder.table_type(t)?),
            wasmparser::TypeRef::Memory(m) => crate::EntityType::Memory(reencoder.memory_type(m)),
            wasmparser::TypeRef::Global(g) => crate::EntityType::Global(reencoder.global_type(g)?),
            wasmparser::TypeRef::Tag(t) => crate::EntityType::Tag(reencoder.tag_type(t)),
        })
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the imports to the `import` section.
    pub fn parse_import_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        imports: &mut crate::ImportSection,
        section: wasmparser::ImportSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for import in section {
            reencoder.parse_import(imports, import?)?;
        }
        Ok(())
    }

    /// Parses the single [`wasmparser::Import`] provided and adds it to the
    /// `import` section.
    pub fn parse_import<T: ?Sized + Reencode>(
        reencoder: &mut T,
        imports: &mut crate::ImportSection,
        import: wasmparser::Import<'_>,
    ) -> Result<(), Error<T::Error>> {
        imports.import(
            import.module,
            import.name,
            reencoder.entity_type(import.ty)?,
        );
        Ok(())
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the memories to the `memories` section.
    pub fn parse_memory_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        memories: &mut crate::MemorySection,
        section: wasmparser::MemorySectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for memory in section {
            let memory = memory?;
            memories.memory(reencoder.memory_type(memory));
        }
        Ok(())
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the functions to the `functions` section.
    pub fn parse_function_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        functions: &mut crate::FunctionSection,
        section: wasmparser::FunctionSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for func in section {
            functions.function(reencoder.type_index(func?));
        }
        Ok(())
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the data to the `data` section.
    pub fn parse_data_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        data: &mut crate::DataSection,
        section: wasmparser::DataSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for datum in section {
            reencoder.parse_data(data, datum?)?;
        }
        Ok(())
    }

    /// Parses a single [`wasmparser::Data`] and adds it to the `data` section.
    pub fn parse_data<T: ?Sized + Reencode>(
        reencoder: &mut T,
        data: &mut crate::DataSection,
        datum: wasmparser::Data<'_>,
    ) -> Result<(), Error<T::Error>> {
        match datum.kind {
            wasmparser::DataKind::Active {
                memory_index,
                offset_expr,
            } => data.active(
                reencoder.memory_index(memory_index),
                &reencoder.const_expr(offset_expr)?,
                datum.data.iter().copied(),
            ),
            wasmparser::DataKind::Passive => data.passive(datum.data.iter().copied()),
        };
        Ok(())
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the elements to the `element` section.
    pub fn parse_element_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        elements: &mut crate::ElementSection,
        section: wasmparser::ElementSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for element in section {
            reencoder.parse_element(elements, element?)?;
        }
        Ok(())
    }

    /// Parses the single [`wasmparser::Element`] provided and adds it to the
    /// `element` section.
    pub fn parse_element<T: ?Sized + Reencode>(
        reencoder: &mut T,
        elements: &mut crate::ElementSection,
        element: wasmparser::Element<'_>,
    ) -> Result<(), Error<T::Error>> {
        let elems = reencoder.element_items(element.items)?;
        match element.kind {
            wasmparser::ElementKind::Active {
                table_index,
                offset_expr,
            } => elements.active(
                // Inform the reencoder that a table index is being used even if
                // it's not actually present here. That helps wasm-mutate for
                // example which wants to track uses to know when it's ok to
                // remove a table.
                //
                // If the table index started at `None` and is still zero then
                // preserve this encoding and keep it at `None`. Otherwise if
                // the result is nonzero or it was previously nonzero then keep
                // that encoding too.
                match (table_index, reencoder.table_index(table_index.unwrap_or(0))) {
                    (None, 0) => None,
                    (_, n) => Some(n),
                },
                &reencoder.const_expr(offset_expr)?,
                elems,
            ),
            wasmparser::ElementKind::Passive => elements.passive(elems),
            wasmparser::ElementKind::Declared => elements.declared(elems),
        };
        Ok(())
    }

    pub fn element_items<'a, T: ?Sized + Reencode>(
        reencoder: &mut T,
        items: wasmparser::ElementItems<'a>,
    ) -> Result<crate::Elements<'a>, Error<T::Error>> {
        Ok(match items {
            wasmparser::ElementItems::Functions(f) => {
                let mut funcs = Vec::new();
                for func in f {
                    funcs.push(reencoder.function_index(func?));
                }
                crate::Elements::Functions(funcs.into())
            }
            wasmparser::ElementItems::Expressions(ty, e) => {
                let mut exprs = Vec::new();
                for expr in e {
                    exprs.push(reencoder.const_expr(expr?)?);
                }
                crate::Elements::Expressions(reencoder.ref_type(ty)?, exprs.into())
            }
        })
    }

    pub fn table_index<T: ?Sized + Reencode>(_reencoder: &mut T, table: u32) -> u32 {
        table
    }

    pub fn global_index<T: ?Sized + Reencode>(_reencoder: &mut T, global: u32) -> u32 {
        global
    }

    pub fn data_index<T: ?Sized + Reencode>(_reencoder: &mut T, data: u32) -> u32 {
        data
    }

    pub fn element_index<T: ?Sized + Reencode>(_reencoder: &mut T, element: u32) -> u32 {
        element
    }

    pub fn const_expr<T: ?Sized + Reencode>(
        reencoder: &mut T,
        const_expr: wasmparser::ConstExpr,
    ) -> Result<crate::ConstExpr, Error<T::Error>> {
        let mut ops = const_expr.get_operators_reader();
        let mut bytes = Vec::new();

        while !ops.is_end_then_eof() {
            let insn = reencoder.parse_instruction(&mut ops)?;
            insn.encode(&mut bytes);
        }

        Ok(crate::ConstExpr::raw(bytes))
    }

    pub fn block_type<T: ?Sized + Reencode>(
        reencoder: &mut T,
        arg: wasmparser::BlockType,
    ) -> Result<crate::BlockType, Error<T::Error>> {
        match arg {
            wasmparser::BlockType::Empty => Ok(crate::BlockType::Empty),
            wasmparser::BlockType::FuncType(n) => {
                Ok(crate::BlockType::FunctionType(reencoder.type_index(n)))
            }
            wasmparser::BlockType::Type(t) => Ok(crate::BlockType::Result(reencoder.val_type(t)?)),
        }
    }

    pub fn instruction<'a, T: ?Sized + Reencode>(
        reencoder: &mut T,
        arg: wasmparser::Operator<'a>,
    ) -> Result<crate::Instruction<'a>, Error<T::Error>> {
        use crate::Instruction;

        macro_rules! translate {
            ($( @$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident ($($ann:tt)*))*) => {
                Ok(match arg {
                    $(
                        wasmparser::Operator::$op $({ $($arg),* })? => {
                            $(
                                $(let $arg = translate!(map $arg $arg);)*
                            )?
                            translate!(build $op $($($arg)*)?)
                        }
                    )*
                })
            };

            // This case is used to map, based on the name of the field, from the
            // wasmparser payload type to the wasm-encoder payload type through
            // `Translator` as applicable.
            (map $arg:ident tag_index) => (reencoder.tag_index($arg));
            (map $arg:ident function_index) => (reencoder.function_index($arg));
            (map $arg:ident table) => (reencoder.table_index($arg));
            (map $arg:ident table_index) => (reencoder.table_index($arg));
            (map $arg:ident dst_table) => (reencoder.table_index($arg));
            (map $arg:ident src_table) => (reencoder.table_index($arg));
            (map $arg:ident type_index) => (reencoder.type_index($arg));
            (map $arg:ident array_type_index) => (reencoder.type_index($arg));
            (map $arg:ident array_type_index_dst) => (reencoder.type_index($arg));
            (map $arg:ident array_type_index_src) => (reencoder.type_index($arg));
            (map $arg:ident struct_type_index) => (reencoder.type_index($arg));
            (map $arg:ident global_index) => (reencoder.global_index($arg));
            (map $arg:ident mem) => (reencoder.memory_index($arg));
            (map $arg:ident src_mem) => (reencoder.memory_index($arg));
            (map $arg:ident dst_mem) => (reencoder.memory_index($arg));
            (map $arg:ident data_index) => (reencoder.data_index($arg));
            (map $arg:ident elem_index) => (reencoder.element_index($arg));
            (map $arg:ident array_data_index) => (reencoder.data_index($arg));
            (map $arg:ident array_elem_index) => (reencoder.element_index($arg));
            (map $arg:ident blockty) => (reencoder.block_type($arg)?);
            (map $arg:ident relative_depth) => ($arg);
            (map $arg:ident targets) => ((
                $arg
                    .targets()
                    .collect::<Result<Vec<_>, wasmparser::BinaryReaderError>>()?
                    .into(),
                $arg.default(),
            ));
            (map $arg:ident ty) => (reencoder.val_type($arg)?);
            (map $arg:ident hty) => (reencoder.heap_type($arg)?);
            (map $arg:ident from_ref_type) => (reencoder.ref_type($arg)?);
            (map $arg:ident to_ref_type) => (reencoder.ref_type($arg)?);
            (map $arg:ident memarg) => (reencoder.mem_arg($arg));
            (map $arg:ident ordering) => (reencoder.ordering($arg));
            (map $arg:ident local_index) => ($arg);
            (map $arg:ident value) => ($arg);
            (map $arg:ident lane) => ($arg);
            (map $arg:ident lanes) => ($arg);
            (map $arg:ident array_size) => ($arg);
            (map $arg:ident field_index) => ($arg);
            (map $arg:ident try_table) => ($arg);
            (map $arg:ident argument_index) => (reencoder.type_index($arg));
            (map $arg:ident result_index) => (reencoder.type_index($arg));
            (map $arg:ident cont_type_index) => (reencoder.type_index($arg));
            (map $arg:ident resume_table) => ((
                $arg.handlers.into_iter().map(|h| reencoder.handle(h)).collect::<Vec<_>>().into()
            ));

            // This case takes the arguments of a wasmparser instruction and creates
            // a wasm-encoder instruction. There are a few special cases for where
            // the structure of a wasmparser instruction differs from that of
            // wasm-encoder.
            (build $op:ident) => (Instruction::$op);
            (build BrTable $arg:ident) => (Instruction::BrTable($arg.0, $arg.1));
            (build I32Const $arg:ident) => (Instruction::I32Const($arg));
            (build I64Const $arg:ident) => (Instruction::I64Const($arg));
            (build F32Const $arg:ident) => (Instruction::F32Const(f32::from_bits($arg.bits())));
            (build F64Const $arg:ident) => (Instruction::F64Const(f64::from_bits($arg.bits())));
            (build V128Const $arg:ident) => (Instruction::V128Const($arg.i128()));
            (build TryTable $table:ident) => (Instruction::TryTable(reencoder.block_type($table.ty)?, {
                $table.catches.into_iter().map(|c| reencoder.catch(c)).collect::<Vec<_>>().into()
            }));
            (build $op:ident $arg:ident) => (Instruction::$op($arg));
            (build $op:ident $($arg:ident)*) => (Instruction::$op { $($arg),* });
        }

        wasmparser::for_each_operator!(translate)
    }

    /// Parses the input `section` given from the `wasmparser` crate and adds
    /// all the code to the `code` section.
    pub fn parse_code_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        code: &mut crate::CodeSection,
        section: wasmparser::CodeSectionReader<'_>,
    ) -> Result<(), Error<T::Error>> {
        for func in section {
            reencoder.parse_function_body(code, func?)?;
        }
        Ok(())
    }

    /// Parses a single [`wasmparser::FunctionBody`] and adds it to the `code` section.
    pub fn parse_function_body<T: ?Sized + Reencode>(
        reencoder: &mut T,
        code: &mut crate::CodeSection,
        func: wasmparser::FunctionBody<'_>,
    ) -> Result<(), Error<T::Error>> {
        let mut f = reencoder.new_function_with_parsed_locals(&func)?;
        let mut reader = func.get_operators_reader()?;
        while !reader.eof() {
            f.instruction(&reencoder.parse_instruction(&mut reader)?);
        }
        code.function(&f);
        Ok(())
    }

    /// Create a new [`crate::Function`] by parsing the locals declarations from the
    /// provided [`wasmparser::FunctionBody`].
    pub fn new_function_with_parsed_locals<T: ?Sized + Reencode>(
        reencoder: &mut T,
        func: &wasmparser::FunctionBody<'_>,
    ) -> Result<crate::Function, Error<T::Error>> {
        let mut locals = Vec::new();
        for pair in func.get_locals_reader()? {
            let (cnt, ty) = pair?;
            locals.push((cnt, reencoder.val_type(ty)?));
        }
        Ok(crate::Function::new(locals))
    }

    /// Parses a single instruction from `reader` and adds it to `function`.
    pub fn parse_instruction<'a, T: ?Sized + Reencode>(
        reencoder: &mut T,
        reader: &mut wasmparser::OperatorsReader<'a>,
    ) -> Result<crate::Instruction<'a>, Error<T::Error>> {
        let instruction = reencoder.instruction(reader.read()?)?;
        Ok(instruction)
    }

    pub fn parse_unknown_section<T: ?Sized + Reencode>(
        _reencoder: &mut T,
        module: &mut crate::Module,
        id: u8,
        contents: &[u8],
    ) -> Result<(), Error<T::Error>> {
        module.section(&crate::RawSection { id, data: contents });
        Ok(())
    }

    pub fn custom_name_section<T: ?Sized + Reencode>(
        reencoder: &mut T,
        section: wasmparser::NameSectionReader<'_>,
    ) -> Result<crate::NameSection, Error<T::Error>> {
        let mut ret = crate::NameSection::new();
        for subsection in section {
            reencoder.parse_custom_name_subsection(&mut ret, subsection?)?;
        }
        Ok(ret)
    }

    pub fn parse_custom_name_subsection<T: ?Sized + Reencode>(
        reencoder: &mut T,
        names: &mut crate::NameSection,
        section: wasmparser::Name<'_>,
    ) -> Result<(), Error<T::Error>> {
        match section {
            wasmparser::Name::Module { name, .. } => {
                names.module(name);
            }
            wasmparser::Name::Function(map) => {
                names.functions(&name_map(map, |i| reencoder.function_index(i))?);
            }
            wasmparser::Name::Type(map) => {
                names.types(&name_map(map, |i| reencoder.type_index(i))?);
            }
            wasmparser::Name::Local(map) => {
                names.locals(&indirect_name_map(map, |i| reencoder.function_index(i))?);
            }
            wasmparser::Name::Label(map) => {
                names.labels(&indirect_name_map(map, |i| reencoder.function_index(i))?);
            }
            wasmparser::Name::Table(map) => {
                names.tables(&name_map(map, |i| reencoder.table_index(i))?);
            }
            wasmparser::Name::Memory(map) => {
                names.memories(&name_map(map, |i| reencoder.memory_index(i))?);
            }
            wasmparser::Name::Global(map) => {
                names.globals(&name_map(map, |i| reencoder.global_index(i))?);
            }
            wasmparser::Name::Element(map) => {
                names.elements(&name_map(map, |i| reencoder.element_index(i))?);
            }
            wasmparser::Name::Data(map) => {
                names.data(&name_map(map, |i| reencoder.data_index(i))?);
            }
            wasmparser::Name::Tag(map) => {
                names.tags(&name_map(map, |i| reencoder.tag_index(i))?);
            }
            wasmparser::Name::Field(map) => {
                names.fields(&indirect_name_map(map, |i| reencoder.type_index(i))?);
            }
            wasmparser::Name::Unknown { ty, data, .. } => {
                names.raw(ty, data);
            }
        }
        Ok(())
    }

    pub fn name_map(
        map: wasmparser::NameMap<'_>,
        mut map_index: impl FnMut(u32) -> u32,
    ) -> wasmparser::Result<crate::NameMap> {
        let mut ret = crate::NameMap::new();
        for naming in map {
            let naming = naming?;
            ret.append(map_index(naming.index), naming.name);
        }
        Ok(ret)
    }

    pub fn indirect_name_map(
        map: wasmparser::IndirectNameMap<'_>,
        mut map_index: impl FnMut(u32) -> u32,
    ) -> wasmparser::Result<crate::IndirectNameMap> {
        let mut ret = crate::IndirectNameMap::new();
        for naming in map {
            let naming = naming?;
            ret.append(map_index(naming.index), &name_map(naming.names, |i| i)?);
        }
        Ok(ret)
    }
}

impl From<wasmparser::MemArg> for crate::MemArg {
    fn from(arg: wasmparser::MemArg) -> Self {
        RoundtripReencoder.mem_arg(arg)
    }
}

impl From<wasmparser::Ordering> for crate::Ordering {
    fn from(arg: wasmparser::Ordering) -> Self {
        RoundtripReencoder.ordering(arg)
    }
}

impl TryFrom<wasmparser::BlockType> for crate::BlockType {
    type Error = Error;

    fn try_from(arg: wasmparser::BlockType) -> Result<Self, Self::Error> {
        RoundtripReencoder.block_type(arg)
    }
}

impl<'a> TryFrom<wasmparser::Operator<'a>> for crate::Instruction<'a> {
    type Error = Error;

    fn try_from(arg: wasmparser::Operator<'a>) -> Result<Self, Self::Error> {
        RoundtripReencoder.instruction(arg)
    }
}

impl From<wasmparser::Catch> for crate::Catch {
    fn from(arg: wasmparser::Catch) -> Self {
        RoundtripReencoder.catch(arg)
    }
}

impl<'a> TryFrom<wasmparser::ConstExpr<'a>> for crate::ConstExpr {
    type Error = Error;

    fn try_from(const_expr: wasmparser::ConstExpr) -> Result<Self, Self::Error> {
        RoundtripReencoder.const_expr(const_expr)
    }
}

impl<'a> From<wasmparser::CustomSectionReader<'a>> for crate::CustomSection<'a> {
    fn from(section: wasmparser::CustomSectionReader<'a>) -> Self {
        RoundtripReencoder.custom_section(section)
    }
}

impl From<wasmparser::ExternalKind> for crate::ExportKind {
    fn from(external_kind: wasmparser::ExternalKind) -> Self {
        RoundtripReencoder.export_kind(external_kind)
    }
}

impl TryFrom<wasmparser::GlobalType> for crate::GlobalType {
    type Error = Error;

    fn try_from(global_ty: wasmparser::GlobalType) -> Result<Self, Self::Error> {
        RoundtripReencoder.global_type(global_ty)
    }
}

impl From<wasmparser::Handle> for crate::Handle {
    fn from(arg: wasmparser::Handle) -> Self {
        RoundtripReencoder.handle(arg)
    }
}

impl TryFrom<wasmparser::TypeRef> for crate::EntityType {
    type Error = Error;

    fn try_from(type_ref: wasmparser::TypeRef) -> Result<Self, Self::Error> {
        RoundtripReencoder.entity_type(type_ref)
    }
}

impl From<wasmparser::MemoryType> for crate::MemoryType {
    fn from(memory_ty: wasmparser::MemoryType) -> Self {
        RoundtripReencoder.memory_type(memory_ty)
    }
}

impl TryFrom<wasmparser::TableType> for crate::TableType {
    type Error = Error;

    fn try_from(table_ty: wasmparser::TableType) -> Result<Self, Self::Error> {
        RoundtripReencoder.table_type(table_ty)
    }
}

impl From<wasmparser::TagKind> for crate::TagKind {
    fn from(kind: wasmparser::TagKind) -> Self {
        RoundtripReencoder.tag_kind(kind)
    }
}

impl From<wasmparser::TagType> for crate::TagType {
    fn from(tag_ty: wasmparser::TagType) -> Self {
        RoundtripReencoder.tag_type(tag_ty)
    }
}

impl TryFrom<wasmparser::SubType> for crate::SubType {
    type Error = Error;

    fn try_from(sub_ty: wasmparser::SubType) -> Result<Self, Self::Error> {
        RoundtripReencoder.sub_type(sub_ty)
    }
}

impl TryFrom<wasmparser::CompositeType> for crate::CompositeType {
    type Error = Error;

    fn try_from(composite_ty: wasmparser::CompositeType) -> Result<Self, Self::Error> {
        RoundtripReencoder.composite_type(composite_ty)
    }
}

impl TryFrom<wasmparser::FuncType> for crate::FuncType {
    type Error = Error;

    fn try_from(func_ty: wasmparser::FuncType) -> Result<Self, Self::Error> {
        RoundtripReencoder.func_type(func_ty)
    }
}

impl TryFrom<wasmparser::ArrayType> for crate::ArrayType {
    type Error = Error;

    fn try_from(array_ty: wasmparser::ArrayType) -> Result<Self, Self::Error> {
        RoundtripReencoder.array_type(array_ty)
    }
}

impl TryFrom<wasmparser::StructType> for crate::StructType {
    type Error = Error;

    fn try_from(struct_ty: wasmparser::StructType) -> Result<Self, Self::Error> {
        RoundtripReencoder.struct_type(struct_ty)
    }
}

impl TryFrom<wasmparser::FieldType> for crate::FieldType {
    type Error = Error;

    fn try_from(field_ty: wasmparser::FieldType) -> Result<Self, Self::Error> {
        RoundtripReencoder.field_type(field_ty)
    }
}

impl TryFrom<wasmparser::StorageType> for crate::StorageType {
    type Error = Error;

    fn try_from(storage_ty: wasmparser::StorageType) -> Result<Self, Self::Error> {
        RoundtripReencoder.storage_type(storage_ty)
    }
}

impl TryFrom<wasmparser::ValType> for crate::ValType {
    type Error = Error;

    fn try_from(val_ty: wasmparser::ValType) -> Result<Self, Self::Error> {
        RoundtripReencoder.val_type(val_ty)
    }
}

impl TryFrom<wasmparser::RefType> for crate::RefType {
    type Error = Error;

    fn try_from(ref_type: wasmparser::RefType) -> Result<Self, Self::Error> {
        RoundtripReencoder.ref_type(ref_type)
    }
}

impl TryFrom<wasmparser::HeapType> for crate::HeapType {
    type Error = Error;

    fn try_from(heap_type: wasmparser::HeapType) -> Result<Self, Self::Error> {
        crate::reencode::utils::heap_type(&mut crate::reencode::RoundtripReencoder, heap_type)
    }
}

impl From<wasmparser::AbstractHeapType> for crate::AbstractHeapType {
    fn from(value: wasmparser::AbstractHeapType) -> Self {
        RoundtripReencoder.abstract_heap_type(value)
    }
}
