//* 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 "common/Assert.h"
#include "common/Log.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
    {%- else -%}
        {{ assert(as_cType(member.type.name) != "size_t") }}
        {{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"%}
        {%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%}
        {% if member.annotation == "const*const*" %}
            WIRE_TRY({{as_cType(member.type.name)}}Serialize(*{{in}}, &{{out}}, buffer{{Provider}}));
        {% else %}
            WIRE_TRY({{as_cType(member.type.name)}}Serialize({{in}}, &{{out}}, buffer{{Provider}}));
        {% endif %}
    {%- 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" -%}
        WIRE_TRY({{as_cType(member.type.name)}}Deserialize(&{{out}}, &{{in}}, deserializeBuffer, allocator
            {%- if member.type.may_have_dawn_object -%}
                , resolver
            {%- endif -%}
        ));
    {%- 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 %}

        //* Value types are directly in the command, objects being replaced with their IDs.
        {% for member in members if member.annotation == "value" %}
            {{member_transfer_type(member)}} {{as_varName(member.name)}};
        {% endfor %}

        //* const char* have their length embedded directly in the command.
        {% for member in members if member.length == "strlen" %}
            uint64_t {{as_varName(member.name)}}Strlen;
        {% endfor %}

        {% for member in members if member.optional and member.annotation != "value" and member.type.category != "object" %}
            bool has_{{as_varName(member.name)}};
        {% 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 %}

        //* Special handling of const char* that have their length embedded directly in the command
        {% for member in members if member.length == "strlen" %}
            {% set memberName = as_varName(member.name) %}

            {% if member.optional %}
                bool has_{{memberName}} = record.{{memberName}} != nullptr;
                if (has_{{memberName}})
            {% endif %}
            {
            result += std::strlen(record.{{memberName}});
            }
        {% endfor %}

        //* Gather how much space will be needed for pointer members.
        {% for member in members if member.length != "strlen" and not member.skip_serialize %}
            {% if member.type.category != "object" and member.optional %}
                if (record.{{as_varName(member.name)}} != nullptr)
            {% endif %}
            {
                {% if member.annotation != "value" %}
                    auto memberLength = {{member_length(member, "record.")}};
                    result += memberLength * {{member_transfer_sizeof(member)}};
                    //* 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) {
                            {% if member.annotation == "const*const*" %}
                                result += {{as_cType(member.type.name)}}GetExtraRequiredSize(*record.{{as_varName(member.name)}}[i]);
                            {% else %}
                                {{assert(member.annotation == "const*")}}
                                result += {{as_cType(member.type.name)}}GetExtraRequiredSize(record.{{as_varName(member.name)}}[i]);
                            {% endif %}
                        }
                    {% endif %}
                {% elif member.type.category == "structure" %}
                    result += {{as_cType(member.type.name)}}GetExtraRequiredSize(record.{{as_varName(member.name)}});
                {% 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 %}

        //* Value types are directly in the transfer record, objects being replaced with their IDs.
        {% for member in members if member.annotation == "value" %}
            {% set memberName = as_varName(member.name) %}
            {{serialize_member(member, "record." + memberName, "transfer->" + memberName)}}
        {% endfor %}

        {% 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 %}

        //* Special handling of const char* that have their length embedded directly in the command
        {% for member in members if member.length == "strlen" %}
            {% set memberName = as_varName(member.name) %}

            {% if member.optional %}
                bool has_{{memberName}} = record.{{memberName}} != nullptr;
                transfer->has_{{memberName}} = has_{{memberName}};
                if (has_{{memberName}})
            {% 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);
            }
        {% endfor %}

        //* Allocate space and write the non-value arguments in it.
        {% for member in members if member.annotation != "value" and member.length != "strlen" and not member.skip_serialize %}
            {% set memberName = as_varName(member.name) %}

            {% if member.type.category != "object" and member.optional %}
                bool has_{{memberName}} = record.{{memberName}} != nullptr;
                transfer->has_{{memberName}} = has_{{memberName}};
                if (has_{{memberName}})
            {% 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 %}

        //* Value types are directly in the transfer record, objects being replaced with their IDs.
        {% for member in members if member.annotation == "value" %}
            {% set memberName = as_varName(member.name) %}
            {{deserialize_member(member, "transfer->" + memberName, "record->" + memberName)}}
        {% endfor %}

        {% 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 %}

        //* Special handling of const char* that have their length embedded directly in the command
        {% for member in members if member.length == "strlen" %}
            {% set memberName = as_varName(member.name) %}

            {% if member.optional %}
                bool has_{{memberName}} = transfer->has_{{memberName}};
                record->{{memberName}} = nullptr;
                if (has_{{memberName}})
            {% 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;
            }
        {% endfor %}

        //* Get extra buffer data, and copy pointed to values in extra allocated space.
        {% for member in members if member.annotation != "value" and member.length != "strlen" %}
            {% set memberName = as_varName(member.name) %}

            {% 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.
                {{ assert(member.length == "constant") }}
                bool has_{{memberName}} = transfer->has_{{memberName}};
                record->{{memberName}} = nullptr;
                if (has_{{memberName}})
            {% endif %}
            {
                auto memberLength = {{member_length(member, "record->")}};
                const volatile {{member_transfer_type(member)}}* memberBuffer;
                WIRE_TRY(deserializeBuffer->ReadN(memberLength, &memberBuffer));

                {{as_cType(member.type.name)}}* copiedMembers;
                WIRE_TRY(GetSpace(allocator, memberLength, &copiedMembers));
                {% if member.annotation == "const*const*" %}
                    {{as_cType(member.type.name)}}** pointerArray;
                    WIRE_TRY(GetSpace(allocator, memberLength, &pointerArray));

                    //* 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) {
                        pointerArray[i] = &copiedMembers[i];
                    }
                    record->{{memberName}} = pointerArray;
                {% else %}
                    record->{{memberName}} = copiedMembers;
                {% endif %}

                {% 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 %}
            }
        {% 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 {
        size_t size = sizeof({{Name}}Transfer) + {{Name}}GetExtraRequiredSize(*this);
        return size;
    }

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

        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" %}
        size_t GetChainedStructExtraRequiredSize({{ChainedStructPtr}} chainedStruct) {
            ASSERT(chainedStruct != nullptr);
            size_t result = 0;
            while (chainedStruct != nullptr) {
                switch (chainedStruct->sType) {
                    {% for sType in types["s type"].values if (
                            sType.valid and
                            (sType.name.CamelCase() not in client_side_structures) and
                            (types[sType.name.get()].output == out)
                    ) %}
                        case {{as_cEnum(types["s type"].name, sType.name)}}: {
                            const auto& typedStruct = *reinterpret_cast<{{as_cType(sType.name)}} const *>(chainedStruct);
                            result += sizeof({{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 += sizeof(WGPUChainedStructTransfer);
                        chainedStruct = chainedStruct->next;
                        break;
                }
            }
            return result;
        }

        DAWN_NO_DISCARD WireResult SerializeChainedStruct({{ChainedStructPtr}} chainedStruct,
                                                          SerializeBuffer* buffer,
                                                          const ObjectIdProvider& provider) {
            ASSERT(chainedStruct != nullptr);
            ASSERT(buffer != nullptr);
            do {
                switch (chainedStruct->sType) {
                    {% for sType in types["s type"].values if (
                            sType.valid and
                            (sType.name.CamelCase() not in client_side_structures) and
                            (types[sType.name.get()].output == out)
                    ) %}
                        {% 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 types["s type"].values if (
                            sType.valid and
                            (sType.name.CamelCase() not in client_side_structures) and
                            (types[sType.name.get()].output == out)
                    ) %}
                        {% 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, sizeof({{CType}}), &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, sizeof({{ChainedStruct}}), &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 {

    ObjectHandle::ObjectHandle() = default;
    ObjectHandle::ObjectHandle(ObjectId id, ObjectGeneration generation)
        : id(id), generation(generation) {
    }

    ObjectHandle::ObjectHandle(const volatile ObjectHandle& rhs)
        : id(rhs.id), generation(rhs.generation) {
    }
    ObjectHandle& ObjectHandle::operator=(const volatile ObjectHandle& rhs) {
        id = rhs.id;
        generation = rhs.generation;
        return *this;
    }

    ObjectHandle& ObjectHandle::AssignFrom(const ObjectHandle& rhs) {
        id = rhs.id;
        generation = rhs.generation;
        return *this;
    }
    ObjectHandle& ObjectHandle::AssignFrom(const volatile ObjectHandle& rhs) {
        id = rhs.id;
        generation = rhs.generation;
        return *this;
    }

    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) {
            constexpr size_t kMaxCountWithoutOverflows = std::numeric_limits<size_t>::max() / sizeof(T);
            if (count > kMaxCountWithoutOverflows) {
                return WireResult::FatalError;
            }

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

            return WireResult::Success;
        }

        struct WGPUChainedStructTransfer {
            WGPUSType sType;
            bool hasNext;
        };

        size_t GetChainedStructExtraRequiredSize(const WGPUChainedStruct* chainedStruct);
        DAWN_NO_DISCARD 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);
        DAWN_NO_DISCARD 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 %}

    // Implementations of serialization/deserialization of WPGUDeviceProperties.
    size_t SerializedWGPUDevicePropertiesSize(const WGPUDeviceProperties* deviceProperties) {
        return sizeof(WGPUDeviceProperties) +
               WGPUDevicePropertiesGetExtraRequiredSize(*deviceProperties);
    }

    void SerializeWGPUDeviceProperties(const WGPUDeviceProperties* deviceProperties,
                                       char* buffer) {
        SerializeBuffer serializeBuffer(buffer, SerializedWGPUDevicePropertiesSize(deviceProperties));

        WGPUDevicePropertiesTransfer* transfer;

        WireResult result = serializeBuffer.Next(&transfer);
        ASSERT(result == WireResult::Success);

        ErrorObjectIdProvider provider;
        result = WGPUDevicePropertiesSerialize(*deviceProperties, transfer, &serializeBuffer, provider);
        ASSERT(result == WireResult::Success);
    }

    bool DeserializeWGPUDeviceProperties(WGPUDeviceProperties* deviceProperties,
                                         const volatile char* buffer,
                                         size_t size) {
        const volatile WGPUDevicePropertiesTransfer* transfer;
        DeserializeBuffer deserializeBuffer(buffer, size);
        if (deserializeBuffer.Read(&transfer) != WireResult::Success) {
            return false;
        }

        ErrorObjectIdResolver resolver;
        return WGPUDevicePropertiesDeserialize(deviceProperties, transfer, &deserializeBuffer,
                                               nullptr, resolver) == WireResult::Success;
    }

    size_t SerializedWGPUSupportedLimitsSize(const WGPUSupportedLimits* supportedLimits) {
        return sizeof(WGPUSupportedLimits) +
               WGPUSupportedLimitsGetExtraRequiredSize(*supportedLimits);
    }

    void SerializeWGPUSupportedLimits(
        const WGPUSupportedLimits* supportedLimits,
        char* buffer) {
        SerializeBuffer serializeBuffer(buffer, SerializedWGPUSupportedLimitsSize(supportedLimits));

        WGPUSupportedLimitsTransfer* transfer;

        WireResult result = serializeBuffer.Next(&transfer);
        ASSERT(result == WireResult::Success);

        ErrorObjectIdProvider provider;
        result = WGPUSupportedLimitsSerialize(*supportedLimits, transfer, &serializeBuffer, provider);
        ASSERT(result == WireResult::Success);
    }

    bool DeserializeWGPUSupportedLimits(WGPUSupportedLimits* supportedLimits,
                                        const volatile char* buffer,
                                        size_t size) {
        const volatile WGPUSupportedLimitsTransfer* transfer;
        DeserializeBuffer deserializeBuffer(buffer, size);
        if (deserializeBuffer.Read(&transfer) != WireResult::Success) {
            return false;
        }

        ErrorObjectIdResolver resolver;
        return WGPUSupportedLimitsDeserialize(supportedLimits, transfer, &deserializeBuffer,
                                              nullptr, resolver) == WireResult::Success;
    }

}  // namespace dawn_wire
