//* Copyright 2017 The Dawn & Tint Authors
//*
//* Redistribution and use in source and binary forms, with or without
//* modification, are permitted provided that the following conditions are met:
//*
//* 1. Redistributions of source code must retain the above copyright notice, this
//*    list of conditions and the following disclaimer.
//*
//* 2. Redistributions in binary form must reproduce the above copyright notice,
//*    this list of conditions and the following disclaimer in the documentation
//*    and/or other materials provided with the distribution.
//*
//* 3. Neither the name of the copyright holder nor the names of its
//*    contributors may be used to endorse or promote products derived from
//*    this software without specific prior written permission.
//*
//* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
//* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
//* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
//* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
//* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "dawn/wire/WireCmd_autogen.h"

#include "dawn/common/Assert.h"
#include "dawn/common/Log.h"
#include "dawn/common/Numeric.h"
#include "dawn/wire/BufferConsumer_impl.h"
#include "dawn/wire/Wire.h"

#include <algorithm>
#include <cstring>
#include <limits>

#if defined(__GNUC__) || defined(__clang__)
// error: 'offsetof' within non-standard-layout type 'wgpu::XXX' is conditionally-supported
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
#endif

//* Helper macros so that the main [de]serialization functions can be written in a generic manner.

//* Outputs an rvalue that's the number of elements a pointer member points to.
{%- macro member_length(member, record_accessor) -%}
    {%- if member.length == "constant" -%}
        {{member.constant_length}}u
    {%- else -%}
        {{record_accessor}}{{as_varName(member.length.name)}}
    {%- endif -%}
{%- endmacro -%}

//* Outputs the type that will be used on the wire for the member
{%- macro member_transfer_type(member) -%}
    {%- if member.type.category == "object" -%}
        ObjectId
    {%- elif member.type.category == "structure" -%}
        {{as_cType(member.type.name)}}Transfer
    {%- elif member.type.category == "bitmask" -%}
        {{as_cType(member.type.name)}}Flags
    {%- elif as_cType(member.type.name) == "size_t" -%}
        {{as_cType(types["uint64_t"].name)}}
    {%- else -%}
        {%- do assert(member.type.is_wire_transparent, 'wire transparent') -%}
        {{as_cType(member.type.name)}}
    {%- endif -%}
{%- endmacro -%}

//* Outputs the size of one element of the type that will be used on the wire for the member
{%- macro member_transfer_sizeof(member) -%}
    sizeof({{member_transfer_type(member)}})
{%- endmacro -%}

//* Outputs the serialization code to put `in` in `out`
{%- macro serialize_member(member, in, out) -%}
    {%- if member.type.category == "object" -%}
        {%- set Optional = "Optional" if member.optional else "" -%}
        WIRE_TRY(provider.Get{{Optional}}Id({{in}}, &{{out}}));
    {%- elif member.type.category == "structure" -%}
        //* Do not memcpy or we may serialize padding bytes which can leak information across a
        //* trusted boundary.
        {%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%}
        WIRE_TRY({{as_cType(member.type.name)}}Serialize({{in}}, &{{out}}, buffer{{Provider}}));
    {%- elif member.type.category == "function pointer" or member.type.name.get() == "void *" -%}
        //* Function pointers and explicit "void *" types (i.e. userdata) cannot be serialized.
        if ({{in}} != nullptr) return WireResult::FatalError;
    {%- else -%}
        {{out}} = {{in}};
    {%- endif -%}
{%- endmacro -%}

//* Outputs the deserialization code to put `in` in `out`
{%- macro deserialize_member(member, in, out) -%}
    {%- if member.type.category == "object" -%}
        {%- set Optional = "Optional" if member.optional else "" -%}
        WIRE_TRY(resolver.Get{{Optional}}FromId({{in}}, &{{out}}));
    {%- elif member.type.category == "structure" %}
        {% if member.type.is_wire_transparent %}
            static_assert(sizeof({{out}}) == sizeof({{in}}), "Deserialize memcpy size must match.");
                memcpy(&{{out}}, const_cast<const {{member_transfer_type(member)}}*>(&{{in}}), {{member_transfer_sizeof(member)}});
        {%- else %}
            WIRE_TRY({{as_cType(member.type.name)}}Deserialize(&{{out}}, &{{in}}, deserializeBuffer, allocator
                {%- if member.type.may_have_dawn_object -%}
                    , resolver
                {%- endif -%}
            ));
        {%- endif -%}
    {%- elif member.type.category == "function pointer" or member.type.name.get() == "void *" %}
        //* Function pointers and explicit "void *" types (i.e. userdata) cannot be deserialized.
        {{out}} = nullptr;
    {%- elif member.type.name.get() == "size_t" -%}
        //* Deserializing into size_t requires check that the uint64_t used on the wire won't narrow.
        if ({{in}} > std::numeric_limits<size_t>::max()) return WireResult::FatalError;
            {{out}} = checked_cast<size_t>({{in}});
    {%- else -%}
        static_assert(sizeof({{out}}) >= sizeof({{in}}), "Deserialize assignment may not narrow.");
            {{out}} = {{in}};
    {%- endif -%}
{%- endmacro -%}

//* The main [de]serialization macro
//* Methods are very similar to structures that have one member corresponding to each arguments.
//* This macro takes advantage of the similarity to output [de]serialization code for a record
//* that is either a structure or a method, with some special cases for each.
{%- macro write_record_serialization_helpers(record, name, members, is_cmd=False, is_return_command=False) -%}
    {%- set Return = "Return" if is_return_command else "" -%}
    {%- set Cmd = "Cmd" if is_cmd else "" -%}
    {%- set Inherits = " : CmdHeader" if is_cmd else "" %}

    //* Structure for the wire format of each of the records. Members that are values
    //* are embedded directly in the structure. Other members are assumed to be in the
    //* memory directly following the structure in the buffer.
    struct {{Return}}{{name}}Transfer{{Inherits}} {
        static_assert({{[is_cmd, record.extensible, record.chained].count(True)}} <= 1,
                      "Record must be at most one of is_cmd, extensible, and chained.");
        {% if is_cmd %}
            //* Start the transfer structure with the command ID, so that casting to WireCmd gives the ID.
            {{Return}}WireCmd commandId;
        {% elif record.extensible %}
            bool hasNextInChain;
        {% elif record.chained %}
            WGPUChainedStructTransfer chain;
        {% endif %}

        {% for member in members %}
            //* Function pointers and explicit "void *" types (i.e. userdata) do not get serialized.
            {% if member.type.category == "function pointer" or  member.type.name.get() == "void *" %}
                {% continue %}
            {% endif %}
            //* Value types are directly in the command, objects being replaced with their IDs.
            {% if member.annotation == "value" %}
                {{member_transfer_type(member)}} {{as_varName(member.name)}};
                {% continue %}
            {% endif %}
            //* Members of type "const char *" have their length embedded directly in the command.
            {% if member.length == "strlen" %}
                uint64_t {{as_varName(member.name)}}Strlen;
            {% endif %}
            //* Optional members additionally come with a boolean to indicate whether they were set.
            {% if member.optional and member.type.category != "object" %}
                bool has_{{as_varName(member.name)}};
            {% endif %}
        {% endfor %}
    };

    {% if is_cmd %}
        static_assert(offsetof({{Return}}{{name}}Transfer, commandSize) == 0);
        static_assert(offsetof({{Return}}{{name}}Transfer, commandId) == sizeof(CmdHeader));
    {% endif -%}

    {% if record.chained %}
        static_assert(offsetof({{Return}}{{name}}Transfer, chain) == 0);
    {% endif %}

    //* Returns the required transfer size for `record` in addition to the transfer structure.
    DAWN_DECLARE_UNUSED size_t {{Return}}{{name}}GetExtraRequiredSize(const {{Return}}{{name}}{{Cmd}}& record) {
        DAWN_UNUSED(record);
        size_t result = 0;

        //* Gather how much space will be needed for the extension chain.
        {% if record.extensible %}
            if (record.nextInChain != nullptr) {
                result += GetChainedStructExtraRequiredSize(record.nextInChain);
            }
        {% endif %}
        //* Gather space needed for pointer members.
        {% for member in members %}
            {%- set memberName = as_varName(member.name) -%}
            //* Skip size computation if we are skipping serialization.
            {% if member.skip_serialize %}
                {% continue %}
            {% endif %}
            //* Special handling of const char* that have their length embedded directly in the command.
            {% if member.length == "strlen" %}
                {% if member.optional %}
                    if (record.{{memberName}} != nullptr) {
                        result += Align(std::strlen(record.{{memberName}}), kWireBufferAlignment);
                    }
                {% else %}
                    DAWN_ASSERT(record.{{memberName}} != nullptr);
                    result += Align(std::strlen(record.{{memberName}}), kWireBufferAlignment);
                {% endif %}
                {% continue %}
            {% endif %}
            //* Normal handling for pointer members and structs.
            {% if member.annotation != "value" or member.type.category == "structure" %}
                {% if member.type.category != "object" and member.optional %}
                    if (record.{{as_varName(member.name)}} != nullptr) {
                {% else %}
                    {
                {% endif %}
                {% if member.annotation != "value" %}
                        {% do assert(member.annotation != "const*const*", "const*const* not valid here") %}
                        auto memberLength = {{member_length(member, "record.")}};
                        auto size = WireAlignSizeofN<{{member_transfer_type(member)}}>(memberLength);
                        DAWN_ASSERT(size);
                        result += *size;
                        //* Structures might contain more pointers so we need to add their extra size as well.
                        {% if member.type.category == "structure" %}
                            for (decltype(memberLength) i = 0; i < memberLength; ++i) {
                                {% do assert(member.annotation == "const*", "unhandled annotation: " + member.annotation) %}
                                result += {{as_cType(member.type.name)}}GetExtraRequiredSize(record.{{as_varName(member.name)}}[i]);
                            }
                        {% endif %}
                    {% elif member.type.category == "structure" %}
                        result += {{as_cType(member.type.name)}}GetExtraRequiredSize(record.{{as_varName(member.name)}});
                    {% endif %}
                }
            {% endif %}
        {% endfor %}
        return result;
    }
    // GetExtraRequiredSize isn't used for structures that are value members of other structures
    // because we assume they cannot contain pointers themselves.
    DAWN_UNUSED_FUNC({{Return}}{{name}}GetExtraRequiredSize);

    //* Serializes `record` into `transfer`, using `buffer` to get more space for pointed-to data
    //* and `provider` to serialize objects.
    DAWN_DECLARE_UNUSED WireResult {{Return}}{{name}}Serialize(
        const {{Return}}{{name}}{{Cmd}}& record,
        {{Return}}{{name}}Transfer* transfer,
        SerializeBuffer* buffer
        {%- if record.may_have_dawn_object -%}
            , const ObjectIdProvider& provider
        {%- endif -%}
    ) {
        DAWN_UNUSED(buffer);
        //* Handle special transfer members of methods.
        {% if is_cmd %}
            transfer->commandId = {{Return}}WireCmd::{{name}};
        {% endif %}

        {% if record.extensible %}
            if (record.nextInChain != nullptr) {
                transfer->hasNextInChain = true;
                WIRE_TRY(SerializeChainedStruct(record.nextInChain, buffer, provider));
            } else {
                transfer->hasNextInChain = false;
            }
        {% endif %}
        {% if record.chained %}
            //* Should be set by the root descriptor's call to SerializeChainedStruct.
            DAWN_ASSERT(transfer->chain.sType == {{as_cEnum(types["s type"].name, record.name)}});
            DAWN_ASSERT(transfer->chain.hasNext == (record.chain.next != nullptr));
        {% endif %}

        //* Iterate members, sorted in reverse on "attribute" so that "value" types are serialized first.
        //* Note this is important because some array pointer members rely on another "value" for their
        //* "length", but order is not always given.
        {% for member in members | sort(reverse=true, attribute="annotation") %}
            {% set memberName = as_varName(member.name) %}
            //* Skip serialization for custom serialized members.
            {% if member.skip_serialize %}
                {% continue %}
            {% endif %}
            //* Value types are directly in the transfer record, objects being replaced with their IDs.
            {% if member.annotation == "value" %}
                {{serialize_member(member, "record." + memberName, "transfer->" + memberName)}}
                {% continue %}
            {% endif %}
            //* Special handling of const char* that have their length embedded directly in the command.
            {% if member.length == "strlen" %}
                {% if member.optional %}
                    bool has_{{memberName}} = record.{{memberName}} != nullptr;
                    transfer->has_{{memberName}} = has_{{memberName}};
                    if (has_{{memberName}}) {
                {% else %}
                    {
                {% endif %}
                    transfer->{{memberName}}Strlen = std::strlen(record.{{memberName}});

                    char* stringInBuffer;
                    WIRE_TRY(buffer->NextN(transfer->{{memberName}}Strlen, &stringInBuffer));
                    memcpy(stringInBuffer, record.{{memberName}}, transfer->{{memberName}}Strlen);
                }
                {% continue %}
            {% endif %}
            //* Allocate space and write the non-value arguments in it.
            {% do assert(member.annotation != "const*const*") %}
            {% if member.type.category != "object" and member.optional %}
                bool has_{{memberName}} = record.{{memberName}} != nullptr;
                transfer->has_{{memberName}} = has_{{memberName}};
                if (has_{{memberName}}) {
            {% else %}
                {
            {% endif %}
                auto memberLength = {{member_length(member, "record.")}};

                {{member_transfer_type(member)}}* memberBuffer;
                WIRE_TRY(buffer->NextN(memberLength, &memberBuffer));

                {% if member.type.is_wire_transparent %}
                    memcpy(
                        memberBuffer, record.{{memberName}},
                        {{member_transfer_sizeof(member)}} * memberLength);
                {% else %}
                    //* This loop cannot overflow because it iterates up to |memberLength|. Even if
                    //* memberLength were the maximum integer value, |i| would become equal to it
                    //* just before exiting the loop, but not increment past or wrap around.
                    for (decltype(memberLength) i = 0; i < memberLength; ++i) {
                        {{serialize_member(member, "record." + memberName + "[i]", "memberBuffer[i]" )}}
                    }
                {% endif %}
            }
        {% endfor %}

        return WireResult::Success;
    }
    DAWN_UNUSED_FUNC({{Return}}{{name}}Serialize);

    //* Deserializes `transfer` into `record` getting more serialized data from `buffer` and `size`
    //* if needed, using `allocator` to store pointed-to values and `resolver` to translate object
    //* Ids to actual objects.
    DAWN_DECLARE_UNUSED WireResult {{Return}}{{name}}Deserialize(
        {{Return}}{{name}}{{Cmd}}* record,
        const volatile {{Return}}{{name}}Transfer* transfer,
        DeserializeBuffer* deserializeBuffer,
        DeserializeAllocator* allocator
        {%- if record.may_have_dawn_object -%}
            , const ObjectIdResolver& resolver
        {%- endif -%}
    ) {
        DAWN_UNUSED(allocator);

        {% if is_cmd %}
            DAWN_ASSERT(transfer->commandId == {{Return}}WireCmd::{{name}});
        {% endif %}
        {% if record.derived_method %}
            record->selfId = transfer->self;
        {% endif %}

        {% if record.extensible %}
            record->nextInChain = nullptr;
            if (transfer->hasNextInChain) {
                WIRE_TRY(DeserializeChainedStruct(&record->nextInChain, deserializeBuffer, allocator, resolver));
            }
        {% endif %}
        {% if record.chained %}
            //* Should be set by the root descriptor's call to DeserializeChainedStruct.
            //* Don't check |record->chain.next| matches because it is not set until the
            //* next iteration inside DeserializeChainedStruct.
            DAWN_ASSERT(record->chain.sType == {{as_cEnum(types["s type"].name, record.name)}});
            DAWN_ASSERT(record->chain.next == nullptr);
        {% endif %}

        //* Iterate members, sorted in reverse on "attribute" so that "value" types are serialized first.
        //* Note this is important because some array pointer members rely on another "value" for their
        //* "length", but order is not always given.
        {% for member in members | sort(reverse=true, attribute="annotation") %}
            {% set memberName = as_varName(member.name) %}
            //* Value types are directly in the transfer record, objects being replaced with their IDs.
            {% if member.annotation == "value" %}
                {{deserialize_member(member, "transfer->" + memberName, "record->" + memberName)}}
                {% continue %}
            {% endif %}
            //* Special handling of const char* that have their length embedded directly in the command.
            {% if member.length == "strlen" %}
                {% if member.optional %}
                    bool has_{{memberName}} = transfer->has_{{memberName}};
                    record->{{memberName}} = nullptr;
                    if (has_{{memberName}}) {
                {% else %}
                    {
                {% endif %}
                    uint64_t stringLength64 = transfer->{{memberName}}Strlen;
                    if (stringLength64 >= std::numeric_limits<size_t>::max()) {
                        //* Cannot allocate space for the string. It can be at most
                        //* size_t::max() - 1. We need 1 byte for the null-terminator.
                        return WireResult::FatalError;
                    }
                    size_t stringLength = static_cast<size_t>(stringLength64);

                    const volatile char* stringInBuffer;
                    WIRE_TRY(deserializeBuffer->ReadN(stringLength, &stringInBuffer));

                    char* copiedString;
                    WIRE_TRY(GetSpace(allocator, stringLength + 1, &copiedString));
                    //* We can cast away the volatile qualifier because DeserializeBuffer::ReadN already
                    //* validated that the range [stringInBuffer, stringInBuffer + stringLength) is valid.
                    //* memcpy may have an unknown access pattern, but this is fine since the string is only
                    //* data and won't affect control flow of this function.
                    memcpy(copiedString, const_cast<const char*>(stringInBuffer), stringLength);
                    copiedString[stringLength] = '\0';
                    record->{{memberName}} = copiedString;
                }
                {% continue %}
            {% endif %}
            //* Get extra buffer data, and copy pointed to values in extra allocated space. Note that
            //* currently, there is an implicit restriction that "skip_serialize" members must not be be
            //* a "value" type, and that they are the last non-"value" type specified in the list in
            //* dawn_wire.json.
            {% do assert(member.annotation != "const*const*") %}
            {% if member.type.category != "object" and member.optional %}
                //* Non-constant length optional members use length=0 to denote they aren't present.
                //* Otherwise we could have length=N and has_member=false, causing reads from an
                //* uninitialized pointer.
                {% do assert(member.length == "constant") %}
                bool has_{{memberName}} = transfer->has_{{memberName}};
                record->{{memberName}} = nullptr;
                if (has_{{memberName}}) {
            {% else %}
                {
            {% endif %}
                auto memberLength = {{member_length(member, "record->")}};
                const volatile {{member_transfer_type(member)}}* memberBuffer;
                WIRE_TRY(deserializeBuffer->ReadN(memberLength, &memberBuffer));

                //* For data-only members (e.g. "data" in WriteBuffer and WriteTexture), they are
                //* not security sensitive so we can directly refer the data inside the transfer
                //* buffer in dawn_native. For other members, as prevention of TOCTOU attacks is an
                //* important feature of the wire, we must make sure every single value returned to
                //* dawn_native must be a copy of what's in the wire.
                {% if member.json_data["wire_is_data_only"] %}
                    record->{{memberName}} =
                        const_cast<const {{member_transfer_type(member)}}*>(memberBuffer);

                {% else %}
                    {{as_cType(member.type.name)}}* copiedMembers;
                    WIRE_TRY(GetSpace(allocator, memberLength, &copiedMembers));
                    record->{{memberName}} = copiedMembers;

                    {% if member.type.is_wire_transparent %}
                        //* memcpy is not allowed to copy from volatile objects. However, these
                        //* arrays are just used as plain data, and don't impact control flow. So if
                        //* the underlying data were changed while the copy was still executing, we
                        //* would get different data - but it wouldn't cause unexpected downstream
                        //* effects.
                        memcpy(
                            copiedMembers,
                            const_cast<const {{member_transfer_type(member)}}*>(memberBuffer),
                           {{member_transfer_sizeof(member)}} * memberLength);
                    {% else %}
                        //* This loop cannot overflow because it iterates up to |memberLength|. Even
                        //* if memberLength were the maximum integer value, |i| would become equal
                        //* to it just before exiting the loop, but not increment past or wrap
                        //* around.
                        for (decltype(memberLength) i = 0; i < memberLength; ++i) {
                            {{deserialize_member(member, "memberBuffer[i]", "copiedMembers[i]")}}
                        }
                    {% endif %}
                {% endif %}
            }
        {% endfor %}

        return WireResult::Success;
    }
    DAWN_UNUSED_FUNC({{Return}}{{name}}Deserialize);
{%- endmacro -%}

{%- macro write_command_serialization_methods(command, is_return) -%}
    {% set Return = "Return" if is_return else "" %}
    {% set Name = Return + command.name.CamelCase() %}
    {% set Cmd = Name + "Cmd" %}
    size_t {{Cmd}}::GetRequiredSize() const {
        return WireAlignSizeof<{{Name}}Transfer>() + {{Name}}GetExtraRequiredSize(*this);
    }

    {% if command.may_have_dawn_object %}
        WireResult {{Cmd}}::Serialize(
            size_t commandSize,
            SerializeBuffer* serializeBuffer,
            const ObjectIdProvider& provider) const {
            {{Name}}Transfer* transfer;
            WIRE_TRY(serializeBuffer->Next(&transfer));
            transfer->commandSize = commandSize;
            return ({{Name}}Serialize(*this, transfer, serializeBuffer, provider));
        }
        WireResult {{Cmd}}::Serialize(size_t commandSize, SerializeBuffer* serializeBuffer) const {
            ErrorObjectIdProvider provider;
            return Serialize(commandSize, serializeBuffer, provider);
        }

        WireResult {{Cmd}}::Deserialize(
            DeserializeBuffer* deserializeBuffer,
            DeserializeAllocator* allocator,
            const ObjectIdResolver& resolver) {
            const volatile {{Name}}Transfer* transfer;
            WIRE_TRY(deserializeBuffer->Read(&transfer));
            return {{Name}}Deserialize(this, transfer, deserializeBuffer, allocator, resolver);
        }
        WireResult {{Cmd}}::Deserialize(DeserializeBuffer* deserializeBuffer, DeserializeAllocator* allocator) {
            ErrorObjectIdResolver resolver;
            return Deserialize(deserializeBuffer, allocator, resolver);
        }
    {% else %}
        WireResult {{Cmd}}::Serialize(size_t commandSize, SerializeBuffer* serializeBuffer) const {
            {{Name}}Transfer* transfer;
            WIRE_TRY(serializeBuffer->Next(&transfer));
            transfer->commandSize = commandSize;
            return ({{Name}}Serialize(*this, transfer, serializeBuffer));
        }
        WireResult {{Cmd}}::Serialize(
            size_t commandSize,
            SerializeBuffer* serializeBuffer,
            const ObjectIdProvider&) const {
            return Serialize(commandSize, serializeBuffer);
        }

        WireResult {{Cmd}}::Deserialize(DeserializeBuffer* deserializeBuffer, DeserializeAllocator* allocator) {
            const volatile {{Name}}Transfer* transfer;
            WIRE_TRY(deserializeBuffer->Read(&transfer));
            return {{Name}}Deserialize(this, transfer, deserializeBuffer, allocator);
        }
        WireResult {{Cmd}}::Deserialize(
            DeserializeBuffer* deserializeBuffer,
            DeserializeAllocator* allocator,
            const ObjectIdResolver&) {
            return Deserialize(deserializeBuffer, allocator);
        }
    {% endif %}
{%- endmacro -%}

{%- macro make_chained_struct_serialization_helpers(out=None) %}
    {% set ChainedStructPtr = "WGPUChainedStructOut*" if out else "const WGPUChainedStruct*" %}
    {% set ChainedStruct = "WGPUChainedStructOut" if out else "WGPUChainedStruct" %}
    //* Generate the list of sTypes that we need to handle.
    {% set sTypes = [] %}
    {% for sType in types["s type"].values %}
        {% if not sType.valid %}
            {% continue %}
        {% elif sType.name.CamelCase() in client_side_structures %}
            {% continue %}
        {% elif types[sType.name.get()].output != out %}
            {% continue %}
        {% endif %}
        {% do sTypes.append(sType) %}
    {% endfor %}

    size_t GetChainedStructExtraRequiredSize({{ChainedStructPtr}} chainedStruct) {
        DAWN_ASSERT(chainedStruct != nullptr);
        size_t result = 0;
        while (chainedStruct != nullptr) {
            switch (chainedStruct->sType) {
                {% for sType in sTypes %}
                    case {{as_cEnum(types["s type"].name, sType.name)}}: {
                        const auto& typedStruct = *reinterpret_cast<{{as_cType(sType.name)}} const *>(chainedStruct);
                        result += WireAlignSizeof<{{as_cType(sType.name)}}Transfer>();
                        result += {{as_cType(sType.name)}}GetExtraRequiredSize(typedStruct);
                        chainedStruct = typedStruct.chain.next;
                        break;
                    }
                {% endfor %}
                // Explicitly list the Invalid enum. MSVC complains about no case labels.
                case WGPUSType_Invalid:
                default:
                    // Invalid enum. Reserve space just for the transfer header (sType and hasNext).
                    result += WireAlignSizeof<WGPUChainedStructTransfer>();
                    chainedStruct = chainedStruct->next;
                    break;
            }
        }
        return result;
    }

    [[nodiscard]] WireResult SerializeChainedStruct({{ChainedStructPtr}} chainedStruct,
                                                    SerializeBuffer* buffer,
                                                    const ObjectIdProvider& provider) {
        DAWN_ASSERT(chainedStruct != nullptr);
        DAWN_ASSERT(buffer != nullptr);
        do {
            switch (chainedStruct->sType) {
                {% for sType in sTypes %}
                    {% set CType = as_cType(sType.name) %}
                    case {{as_cEnum(types["s type"].name, sType.name)}}: {
                        {{CType}}Transfer* transfer;
                        WIRE_TRY(buffer->Next(&transfer));
                        transfer->chain.sType = chainedStruct->sType;
                        transfer->chain.hasNext = chainedStruct->next != nullptr;

                        WIRE_TRY({{CType}}Serialize(*reinterpret_cast<{{CType}} const*>(chainedStruct), transfer, buffer
                            {%- if types[sType.name.get()].may_have_dawn_object -%}
                            , provider
                            {%- endif -%}
                        ));

                        chainedStruct = chainedStruct->next;
                    } break;
                {% endfor %}
                // Explicitly list the Invalid enum. MSVC complains about no case labels.
                case WGPUSType_Invalid:
                default: {
                    // Invalid enum. Serialize just the transfer header with Invalid as the sType.
                    // TODO(crbug.com/dawn/369): Unknown sTypes are silently discarded.
                    if (chainedStruct->sType != WGPUSType_Invalid) {
                        dawn::WarningLog() << "Unknown sType " << chainedStruct->sType << " discarded.";
                    }

                    WGPUChainedStructTransfer* transfer;
                    WIRE_TRY(buffer->Next(&transfer));
                    transfer->sType = WGPUSType_Invalid;
                    transfer->hasNext = chainedStruct->next != nullptr;

                    // Still move on in case there are valid structs after this.
                    chainedStruct = chainedStruct->next;
                    break;
                }
            }
        } while (chainedStruct != nullptr);
        return WireResult::Success;
    }

    WireResult DeserializeChainedStruct({{ChainedStructPtr}}* outChainNext,
                                        DeserializeBuffer* deserializeBuffer,
                                        DeserializeAllocator* allocator,
                                        const ObjectIdResolver& resolver) {
        bool hasNext;
        do {
            const volatile WGPUChainedStructTransfer* header;
            WIRE_TRY(deserializeBuffer->Peek(&header));
            WGPUSType sType = header->sType;
            switch (sType) {
                {% for sType in sTypes %}
                    {% set CType = as_cType(sType.name) %}
                    case {{as_cEnum(types["s type"].name, sType.name)}}: {
                        const volatile {{CType}}Transfer* transfer;
                        WIRE_TRY(deserializeBuffer->Read(&transfer));

                        {{CType}}* outStruct;
                        WIRE_TRY(GetSpace(allocator, 1u, &outStruct));
                        outStruct->chain.sType = sType;
                        outStruct->chain.next = nullptr;

                        *outChainNext = &outStruct->chain;
                        outChainNext = &outStruct->chain.next;

                        WIRE_TRY({{CType}}Deserialize(outStruct, transfer, deserializeBuffer, allocator
                            {%- if types[sType.name.get()].may_have_dawn_object -%}
                                , resolver
                            {%- endif -%}
                        ));

                        hasNext = transfer->chain.hasNext;
                    } break;
                {% endfor %}
                // Explicitly list the Invalid enum. MSVC complains about no case labels.
                case WGPUSType_Invalid:
                default: {
                    // Invalid enum. Deserialize just the transfer header with Invalid as the sType.
                    // TODO(crbug.com/dawn/369): Unknown sTypes are silently discarded.
                    if (sType != WGPUSType_Invalid) {
                        dawn::WarningLog() << "Unknown sType " << sType << " discarded.";
                    }

                    const volatile WGPUChainedStructTransfer* transfer;
                    WIRE_TRY(deserializeBuffer->Read(&transfer));

                    {{ChainedStruct}}* outStruct;
                    WIRE_TRY(GetSpace(allocator, 1u, &outStruct));
                    outStruct->sType = WGPUSType_Invalid;
                    outStruct->next = nullptr;

                    // Still move on in case there are valid structs after this.
                    *outChainNext = outStruct;
                    outChainNext = &outStruct->next;
                    hasNext = transfer->hasNext;
                    break;
                }
            }
        } while (hasNext);
        return WireResult::Success;
    }
{% endmacro %}


namespace dawn::wire {
namespace {

// Allocates enough space from allocator to countain T[count] and return it in out.
// Return FatalError if the allocator couldn't allocate the memory.
// Always writes to |out| on success.
template <typename T, typename N>
WireResult GetSpace(DeserializeAllocator* allocator, N count, T** out) {
    // Because we use this function extensively when `count` == 1, we can optimize the
    // size computations a bit more for those cases via constexpr version of the
    // alignment computation.
    constexpr size_t kSizeofT = WireAlignSizeof<T>();
    size_t size = 0;
    if (count == 1) {
      size = kSizeofT;
    } else {
      auto sizeN = WireAlignSizeofN<T>(count);
      // A size of 0 indicates an overflow, so return an error.
      if (!sizeN) {
        return WireResult::FatalError;
      }
      size = *sizeN;
    }

    *out = static_cast<T*>(allocator->GetSpace(size));
    if (*out == nullptr) {
        return WireResult::FatalError;
    }

    return WireResult::Success;
}

struct WGPUChainedStructTransfer {
    WGPUSType sType;
    bool hasNext;
};

size_t GetChainedStructExtraRequiredSize(const WGPUChainedStruct* chainedStruct);
[[nodiscard]] WireResult SerializeChainedStruct(const WGPUChainedStruct* chainedStruct,
                                                  SerializeBuffer* buffer,
                                                  const ObjectIdProvider& provider);
WireResult DeserializeChainedStruct(const WGPUChainedStruct** outChainNext,
                                    DeserializeBuffer* deserializeBuffer,
                                    DeserializeAllocator* allocator,
                                    const ObjectIdResolver& resolver);

size_t GetChainedStructExtraRequiredSize(WGPUChainedStructOut* chainedStruct);
[[nodiscard]] WireResult SerializeChainedStruct(WGPUChainedStructOut* chainedStruct,
                                                  SerializeBuffer* buffer,
                                                  const ObjectIdProvider& provider);
WireResult DeserializeChainedStruct(WGPUChainedStructOut** outChainNext,
                                    DeserializeBuffer* deserializeBuffer,
                                    DeserializeAllocator* allocator,
                                    const ObjectIdResolver& resolver);

//* Output structure [de]serialization first because it is used by commands.
{% for type in by_category["structure"] %}
    {%- set name = as_cType(type.name) -%}
    {% if type.name.CamelCase() not in client_side_structures -%}
        {{write_record_serialization_helpers(type, name, type.members, is_cmd=False)}}
    {% endif %}
{% endfor %}

{{make_chained_struct_serialization_helpers(out=False)}}
{{make_chained_struct_serialization_helpers(out=True)}}

//* Output [de]serialization helpers for commands
{% for command in cmd_records["command"] %}
    {%- set name = command.name.CamelCase() -%}
    {{write_record_serialization_helpers(command, name, command.members, is_cmd=True)}}
{% endfor %}

//* Output [de]serialization helpers for return commands
{% for command in cmd_records["return command"] %}
    {%- set name = command.name.CamelCase() -%}
    {{write_record_serialization_helpers(command, name, command.members,
                                         is_cmd=True, is_return_command=True)}}
{% endfor %}

// Implementation of ObjectIdResolver that always errors.
// Used when the generator adds a provider argument because of a chained
// struct, but in practice, a chained struct in that location is invalid.
class ErrorObjectIdResolver final : public ObjectIdResolver {
    public:
    {% for type in by_category["object"] %}
      WireResult GetFromId(ObjectId id, {{as_cType(type.name)}}* out) const override {
          return WireResult::FatalError;
      }
      WireResult GetOptionalFromId(ObjectId id, {{as_cType(type.name)}}* out) const override {
          return WireResult::FatalError;
      }
    {% endfor %}
};

// Implementation of ObjectIdProvider that always errors.
// Used when the generator adds a provider argument because of a chained
// struct, but in practice, a chained struct in that location is invalid.
class ErrorObjectIdProvider final : public ObjectIdProvider {
    public:
    {% for type in by_category["object"] %}
      WireResult GetId({{as_cType(type.name)}} object, ObjectId* out) const override {
          return WireResult::FatalError;
      }
      WireResult GetOptionalId({{as_cType(type.name)}} object, ObjectId* out) const override {
          return WireResult::FatalError;
      }
    {% endfor %}
};

}  // anonymous namespace

{% for command in cmd_records["command"] -%}
    {{write_command_serialization_methods(command, False)}}
{% endfor %}

{% for command in cmd_records["return command"] -%}
    {{write_command_serialization_methods(command, True)}}
{% endfor %}

}  // namespace dawn::wire
