//* Copyright 2017 The Dawn Authors
//*
//* Licensed under the Apache License, Version 2.0 (the "License");
//* you may not use this file except in compliance with the License.
//* You may obtain a copy of the License at
//*
//*     http://www.apache.org/licenses/LICENSE-2.0
//*
//* Unless required by applicable law or agreed to in writing, software
//* distributed under the License is distributed on an "AS IS" BASIS,
//* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//* See the License for the specific language governing permissions and
//* limitations under the License.

#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>

#ifdef __GNUC__
// 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 -%}
        {{ assert(member.type.is_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 %}
                    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*") %}
                        auto memberLength = {{member_length(member, "record.")}};
                        auto size = WireAlignSizeofN<{{member_transfer_type(member)}}>(memberLength);
                        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*") %}
                                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.
            ASSERT(transfer->chain.sType == {{as_cEnum(types["s type"].name, record.name)}});
            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 %}
            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.
            ASSERT(record->chain.sType == {{as_cEnum(types["s type"].name, record.name)}});
            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) {
            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) {
            ASSERT(chainedStruct != nullptr);
            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
