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

#include "fidl/tables_generator.h"

#include "fidl/names.h"

namespace fidl {

namespace {

constexpr auto kIndent = "    ";

std::ostream& operator<<(std::ostream& stream, StringView view) {
    stream.rdbuf()->sputn(view.data(), view.size());
    return stream;
}

void Emit(std::ostream* file, StringView data) {
    *file << data;
}

void EmitNewlineAndIndent(std::ostream* file, size_t indent_level) {
    *file << "\n";
    while (indent_level--)
        *file << kIndent;
}

void EmitArrayBegin(std::ostream* file) {
    *file << "{";
}

void EmitArraySeparator(std::ostream* file, size_t indent_level) {
    *file << ",";
    EmitNewlineAndIndent(file, indent_level);
}

void EmitArrayEnd(std::ostream* file) {
    *file << "}";
}

void Emit(std::ostream* file, uint32_t value) {
    *file << value;
}

void Emit(std::ostream* file, types::HandleSubtype handle_subtype) {
    Emit(file, NameHandleZXObjType(handle_subtype));
}

void Emit(std::ostream* file, types::Nullability nullability) {
    switch (nullability) {
    case types::Nullability::kNullable:
        Emit(file, "::fidl::kNullable");
        break;
    case types::Nullability::kNonnullable:
        Emit(file, "::fidl::kNonnullable");
        break;
    }
}

} // namespace

void TablesGenerator::GenerateInclude(StringView filename) {
    Emit(&tables_file_, "#include ");
    Emit(&tables_file_, filename);
    Emit(&tables_file_, "\n");
}

void TablesGenerator::GenerateFilePreamble() {
    Emit(&tables_file_, "// WARNING: This file is machine generated by fidlc.\n\n");
    GenerateInclude("<lib/fidl/internal.h>");
    Emit(&tables_file_, "\nextern \"C\" {\n");
    Emit(&tables_file_, "\n");
}

void TablesGenerator::GenerateFilePostamble() {
    Emit(&tables_file_, "} // extern \"C\"\n");
}

template <typename Collection>
void TablesGenerator::GenerateArray(const Collection& collection) {
    EmitArrayBegin(&tables_file_);

    if (!collection.empty())
        EmitNewlineAndIndent(&tables_file_, ++indent_level_);

    for (size_t i = 0; i < collection.size(); ++i) {
        if (i)
            EmitArraySeparator(&tables_file_, indent_level_);
        Generate(collection[i]);
    }

    if (!collection.empty())
        EmitNewlineAndIndent(&tables_file_, --indent_level_);

    EmitArrayEnd(&tables_file_);
}

void TablesGenerator::Generate(const coded::StructType& struct_type) {
    Emit(&tables_file_, "static const ::fidl::FidlStructField ");
    Emit(&tables_file_, NameFields(struct_type.coded_name));
    Emit(&tables_file_, "[] = ");
    GenerateArray(struct_type.fields);
    Emit(&tables_file_, ";\n");

    Emit(&tables_file_, "const fidl_type_t ");
    Emit(&tables_file_, NameTable(struct_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedStruct(");
    Emit(&tables_file_, NameFields(struct_type.coded_name));
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, static_cast<uint32_t>(struct_type.fields.size()));
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, struct_type.size);
    Emit(&tables_file_, ", \"");
    Emit(&tables_file_, struct_type.qname);
    Emit(&tables_file_, "\"));\n\n");
}

void TablesGenerator::Generate(const coded::TableType& table_type) {
    Emit(&tables_file_, "static const ::fidl::FidlTableField ");
    Emit(&tables_file_, NameFields(table_type.coded_name));
    Emit(&tables_file_, "[] = ");
    GenerateArray(table_type.fields);
    Emit(&tables_file_, ";\n");

    Emit(&tables_file_, "const fidl_type_t ");
    Emit(&tables_file_, NameTable(table_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedTable(");
    Emit(&tables_file_, NameFields(table_type.coded_name));
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, static_cast<uint32_t>(table_type.fields.size()));
    Emit(&tables_file_, ", \"");
    Emit(&tables_file_, table_type.qname);
    Emit(&tables_file_, "\"));\n\n");
}

void TablesGenerator::Generate(const coded::UnionType& union_type) {
    Emit(&tables_file_, "static const fidl_type_t* ");
    Emit(&tables_file_, NameMembers(union_type.coded_name));
    Emit(&tables_file_, "[] = ");
    GenerateArray(union_type.types);
    Emit(&tables_file_, ";\n");

    Emit(&tables_file_, "const fidl_type_t ");
    Emit(&tables_file_, NameTable(union_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedUnion(");
    Emit(&tables_file_, NameMembers(union_type.coded_name));
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, static_cast<uint32_t>(union_type.types.size()));
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, union_type.data_offset);
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, union_type.size);
    Emit(&tables_file_, ", \"");
    Emit(&tables_file_, union_type.qname);
    Emit(&tables_file_, "\"));\n\n");
}

void TablesGenerator::Generate(const coded::XUnionType& xunion_type) {
    Emit(&tables_file_, "static const ::fidl::FidlXUnionField ");
    Emit(&tables_file_, NameFields(xunion_type.coded_name));
    Emit(&tables_file_, "[] = ");
    GenerateArray(xunion_type.fields);
    Emit(&tables_file_, ";\n");

    Emit(&tables_file_, "const fidl_type_t ");
    Emit(&tables_file_, NameTable(xunion_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedXUnion(");
    Emit(&tables_file_, static_cast<uint32_t>(xunion_type.fields.size()));
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, NameFields(xunion_type.coded_name));
    Emit(&tables_file_, ", \"");
    Emit(&tables_file_, xunion_type.qname);
    Emit(&tables_file_, "\"));\n\n");
}

void TablesGenerator::Generate(const coded::MessageType& message_type) {
    Emit(&tables_file_, "extern const fidl_type_t ");
    Emit(&tables_file_, NameTable(message_type.coded_name));
    Emit(&tables_file_, ";\n");

    Emit(&tables_file_, "static const ::fidl::FidlStructField ");
    Emit(&tables_file_, NameFields(message_type.coded_name));
    Emit(&tables_file_, "[] = ");
    GenerateArray(message_type.fields);
    Emit(&tables_file_, ";\n");

    Emit(&tables_file_, "const fidl_type_t ");
    Emit(&tables_file_, NameTable(message_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedStruct(");
    Emit(&tables_file_, NameFields(message_type.coded_name));
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, static_cast<uint32_t>(message_type.fields.size()));
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, message_type.size);
    Emit(&tables_file_, ", \"");
    Emit(&tables_file_, message_type.qname);
    Emit(&tables_file_, "\"));\n\n");
}

void TablesGenerator::Generate(const coded::HandleType& handle_type) {
    Emit(&tables_file_, "static const fidl_type_t ");
    Emit(&tables_file_, NameTable(handle_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedHandle(");
    Emit(&tables_file_, handle_type.subtype);
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, handle_type.nullability);
    Emit(&tables_file_, "));\n\n");
}

void TablesGenerator::Generate(const coded::RequestHandleType& request_type) {
    Emit(&tables_file_, "static const fidl_type_t ");
    Emit(&tables_file_, NameTable(request_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedHandle(");
    Emit(&tables_file_, types::HandleSubtype::kChannel);
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, request_type.nullability);
    Emit(&tables_file_, "));\n\n");
}

void TablesGenerator::Generate(const coded::InterfaceHandleType& interface_type) {
    Emit(&tables_file_, "static const fidl_type_t ");
    Emit(&tables_file_, NameTable(interface_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedHandle(");
    Emit(&tables_file_, types::HandleSubtype::kChannel);
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, interface_type.nullability);
    Emit(&tables_file_, "));\n\n");
}

void TablesGenerator::Generate(const coded::ArrayType& array_type) {
    Emit(&tables_file_, "static const fidl_type_t ");
    Emit(&tables_file_, NameTable(array_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedArray(&");
    Emit(&tables_file_, NameTable(array_type.element_type->coded_name));
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, array_type.size);
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, array_type.element_size);
    Emit(&tables_file_, "));\n\n");
}

void TablesGenerator::Generate(const coded::StringType& string_type) {
    Emit(&tables_file_, "static const fidl_type_t ");
    Emit(&tables_file_, NameTable(string_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedString(");
    Emit(&tables_file_, string_type.max_size);
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, string_type.nullability);
    Emit(&tables_file_, "));\n\n");
}

void TablesGenerator::Generate(const coded::VectorType& vector_type) {
    Emit(&tables_file_, "static const fidl_type_t ");
    Emit(&tables_file_, NameTable(vector_type.coded_name));
    Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedVector(");
    if (vector_type.element_type->coding_needed == coded::CodingNeeded::kNeeded) {
        Emit(&tables_file_, "&");
        Emit(&tables_file_, NameTable(vector_type.element_type->coded_name));
    } else {
        Emit(&tables_file_, "nullptr");
    }
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, vector_type.max_count);
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, vector_type.element_size);
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, vector_type.nullability);
    Emit(&tables_file_, "));\n\n");
}

void TablesGenerator::Generate(const coded::Type* type) {
    if (type) {
        Emit(&tables_file_, "&");
        Emit(&tables_file_, NameTable(type->coded_name));
    } else {
        Emit(&tables_file_, "nullptr");
    }
}

void TablesGenerator::Generate(const coded::StructField& field) {
    Emit(&tables_file_, "::fidl::FidlStructField(&");
    Emit(&tables_file_, NameTable(field.type->coded_name));
    Emit(&tables_file_, ", ");
    Emit(&tables_file_, field.offset);
    Emit(&tables_file_, ")");
}

void TablesGenerator::Generate(const coded::TableField& field) {
    Emit(&tables_file_, "::fidl::FidlTableField(&");
    Emit(&tables_file_, NameTable(field.type->coded_name));
    Emit(&tables_file_, ",");
    Emit(&tables_file_, field.ordinal);
    Emit(&tables_file_, ")");
}

void TablesGenerator::Generate(const coded::XUnionField& field) {
    Emit(&tables_file_, "::fidl::FidlXUnionField(&");
    Emit(&tables_file_, NameTable(field.type->coded_name));
    Emit(&tables_file_, ",");
    Emit(&tables_file_, field.ordinal);
    Emit(&tables_file_, ")");
}

void TablesGenerator::GeneratePointerIfNeeded(const coded::StructType& struct_type) {
    if (struct_type.referenced_by_pointer) {
        Emit(&tables_file_, "static const fidl_type_t ");
        Emit(&tables_file_, NameTable(struct_type.pointer_name));
        Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedStructPointer(&");
        Emit(&tables_file_, NameTable(struct_type.coded_name));
        Emit(&tables_file_, ".coded_struct));\n");
    }
}

void TablesGenerator::GeneratePointerIfNeeded(const coded::TableType& table_type) {
    if (table_type.referenced_by_pointer) {
        Emit(&tables_file_, "static const fidl_type_t ");
        Emit(&tables_file_, NameTable(table_type.pointer_name));
        Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedTablePointer(&");
        Emit(&tables_file_, NameTable(table_type.coded_name));
        Emit(&tables_file_, ".coded_table));\n");
    }
}

void TablesGenerator::GeneratePointerIfNeeded(const coded::UnionType& union_type) {
    if (union_type.referenced_by_pointer) {
        Emit(&tables_file_, "static const fidl_type_t ");
        Emit(&tables_file_, NameTable(union_type.pointer_name));
        Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedUnionPointer(&");
        Emit(&tables_file_, NameTable(union_type.coded_name));
        Emit(&tables_file_, ".coded_union));\n");
    }
}

void TablesGenerator::GeneratePointerIfNeeded(const coded::XUnionType& xunion_type) {
    if (xunion_type.referenced_by_pointer) {
        Emit(&tables_file_, "static const fidl_type_t ");
        Emit(&tables_file_, NameTable(xunion_type.pointer_name));
        Emit(&tables_file_, " = fidl_type_t(::fidl::FidlCodedXUnionPointer(&");
        Emit(&tables_file_, NameTable(xunion_type.coded_name));
        Emit(&tables_file_, ".coded_xunion));\n");
    }
}

void TablesGenerator::GenerateForward(const coded::StructType& struct_type) {
    Emit(&tables_file_, "extern const fidl_type_t ");
    Emit(&tables_file_, NameTable(struct_type.coded_name));
    Emit(&tables_file_, ";\n");
}

void TablesGenerator::GenerateForward(const coded::TableType& table_type) {
    Emit(&tables_file_, "extern const fidl_type_t ");
    Emit(&tables_file_, NameTable(table_type.coded_name));
    Emit(&tables_file_, ";\n");
}

void TablesGenerator::GenerateForward(const coded::UnionType& union_type) {
    Emit(&tables_file_, "extern const fidl_type_t ");
    Emit(&tables_file_, NameTable(union_type.coded_name));
    Emit(&tables_file_, ";\n");
}

void TablesGenerator::GenerateForward(const coded::XUnionType& xunion_type) {
    Emit(&tables_file_, "extern const fidl_type_t ");
    Emit(&tables_file_, NameTable(xunion_type.coded_name));
    Emit(&tables_file_, ";\n");
}

const coded::Type* TablesGenerator::CompileType(const flat::Type* type) {
    switch (type->kind) {
    case flat::Type::Kind::kArray: {
        auto array_type = static_cast<const flat::ArrayType*>(type);
        auto iter = array_type_map_.find(array_type);
        if (iter != array_type_map_.end())
            return iter->second;
        auto coded_element_type = CompileType(array_type->element_type.get());
        uint32_t array_size = array_type->size;
        uint32_t element_size = array_type->element_type->size;
        auto name = NameCodedArray(coded_element_type->coded_name, array_size);
        auto coded_array_type = std::make_unique<coded::ArrayType>(
            std::move(name), coded_element_type, array_size, element_size);
        array_type_map_[array_type] = coded_array_type.get();
        coded_types_.push_back(std::move(coded_array_type));
        return coded_types_.back().get();
    }
    case flat::Type::Kind::kVector: {
        auto vector_type = static_cast<const flat::VectorType*>(type);
        auto iter = vector_type_map_.find(vector_type);
        if (iter != vector_type_map_.end())
            return iter->second;
        auto coded_element_type = CompileType(vector_type->element_type.get());
        uint32_t max_count =
            static_cast<const flat::Size&>(vector_type->element_count->Value()).value;
        uint32_t element_size = coded_element_type->size;
        StringView element_name = coded_element_type->coded_name;
        auto name = NameCodedVector(element_name, max_count, vector_type->nullability);
        auto coded_vector_type = std::make_unique<coded::VectorType>(
            std::move(name), coded_element_type, max_count, element_size, vector_type->nullability);
        vector_type_map_[vector_type] = coded_vector_type.get();
        coded_types_.push_back(std::move(coded_vector_type));
        return coded_types_.back().get();
    }
    case flat::Type::Kind::kString: {
        auto string_type = static_cast<const flat::StringType*>(type);
        auto iter = string_type_map_.find(string_type);
        if (iter != string_type_map_.end())
            return iter->second;
        uint32_t max_size =
            static_cast<const flat::Size&>(string_type->max_size->Value()).value;
        auto name = NameCodedString(max_size, string_type->nullability);
        auto coded_string_type = std::make_unique<coded::StringType>(std::move(name), max_size,
                                                                     string_type->nullability);
        string_type_map_[string_type] = coded_string_type.get();
        coded_types_.push_back(std::move(coded_string_type));
        return coded_types_.back().get();
    }
    case flat::Type::Kind::kHandle: {
        auto handle_type = static_cast<const flat::HandleType*>(type);
        auto iter = handle_type_map_.find(handle_type);
        if (iter != handle_type_map_.end())
            return iter->second;
        auto name = NameCodedHandle(handle_type->subtype, handle_type->nullability);
        auto coded_handle_type = std::make_unique<coded::HandleType>(
            std::move(name), handle_type->subtype, handle_type->nullability);
        handle_type_map_[handle_type] = coded_handle_type.get();
        coded_types_.push_back(std::move(coded_handle_type));
        return coded_types_.back().get();
    }
    case flat::Type::Kind::kRequestHandle: {
        auto request_type = static_cast<const flat::RequestHandleType*>(type);
        auto iter = request_type_map_.find(request_type);
        if (iter != request_type_map_.end())
            return iter->second;
        auto name = NameCodedRequestHandle(NameName(request_type->name, "_", "_"), request_type->nullability);
        auto coded_request_type =
            std::make_unique<coded::RequestHandleType>(std::move(name), request_type->nullability);
        request_type_map_[request_type] = coded_request_type.get();
        coded_types_.push_back(std::move(coded_request_type));
        return coded_types_.back().get();
    }
    case flat::Type::Kind::kPrimitive: {
        auto primitive_type = static_cast<const flat::PrimitiveType*>(type);
        auto iter = primitive_type_map_.find(primitive_type);
        if (iter != primitive_type_map_.end())
            return iter->second;
        auto name = NamePrimitiveSubtype(primitive_type->subtype);
        auto coded_primitive_type = std::make_unique<coded::PrimitiveType>(
            std::move(name), primitive_type->subtype,
            flat::PrimitiveType::SubtypeSize(primitive_type->subtype));
        primitive_type_map_[primitive_type] = coded_primitive_type.get();
        coded_types_.push_back(std::move(coded_primitive_type));
        return coded_types_.back().get();
    }
    case flat::Type::Kind::kIdentifier: {
        auto identifier_type = static_cast<const flat::IdentifierType*>(type);
        auto iter = named_coded_types_.find(&identifier_type->name);
        if (iter == named_coded_types_.end()) {
            assert(false && "unknown type in named type map!");
        }
        // We may need to set the emit-pointer bit on structs, unions, and xunions now.
        auto coded_type = iter->second.get();
        switch (coded_type->kind) {
        case coded::Type::Kind::kStruct: {
            // Structs were compiled as part of decl compilation,
            // but we may now need to generate the StructPointer.
            if (identifier_type->nullability != types::Nullability::kNullable)
                break;
            auto coded_struct_type = static_cast<coded::StructType*>(coded_type);
            coded_struct_type->referenced_by_pointer = true;
            coded_types_.push_back(std::make_unique<coded::StructPointerType>(
                coded_struct_type->pointer_name, coded_struct_type));
            return coded_types_.back().get();
        }
        case coded::Type::Kind::kTable: {
            // Tables were compiled as part of decl compilation,
            // but we may now need to generate the TablePointer.
            if (identifier_type->nullability != types::Nullability::kNullable)
                break;
            auto coded_table_type = static_cast<coded::TableType*>(coded_type);
            coded_table_type->referenced_by_pointer = true;
            coded_types_.push_back(std::make_unique<coded::TablePointerType>(
                coded_table_type->pointer_name, coded_table_type));
            return coded_types_.back().get();
        }
        case coded::Type::Kind::kUnion: {
            // Unions were compiled as part of decl compilation,
            // but we may now need to generate the UnionPointer.
            if (identifier_type->nullability != types::Nullability::kNullable)
                break;
            auto coded_union_type = static_cast<coded::UnionType*>(coded_type);
            coded_union_type->referenced_by_pointer = true;
            coded_types_.push_back(std::make_unique<coded::UnionPointerType>(
                coded_union_type->pointer_name, coded_union_type));
            return coded_types_.back().get();
        }
        case coded::Type::Kind::kXUnion: {
            // XUnions were compiled as part of decl compilation,
            // but we may now need to generate the XUnionPointer.
            if (identifier_type->nullability != types::Nullability::kNullable)
                break;
            auto coded_xunion_type = static_cast<coded::XUnionType*>(coded_type);
            coded_xunion_type->referenced_by_pointer = true;
            coded_types_.push_back(std::make_unique<coded::XUnionPointerType>(
                coded_xunion_type->pointer_name, coded_xunion_type));
            return coded_types_.back().get();
        }
        case coded::Type::Kind::kInterface: {
            auto iter = interface_type_map_.find(identifier_type);
            if (iter != interface_type_map_.end())
                return iter->second;
            auto name = NameCodedInterfaceHandle(NameName(identifier_type->name, "_", "_"),
                                                 identifier_type->nullability);
            auto coded_interface_type = std::make_unique<coded::InterfaceHandleType>(
                std::move(name), identifier_type->nullability);
            interface_type_map_[identifier_type] = coded_interface_type.get();
            coded_types_.push_back(std::move(coded_interface_type));
            return coded_types_.back().get();
        }
        case coded::Type::Kind::kPrimitive:
            // These are from enums. We don't need to do anything with them.
            break;
        case coded::Type::Kind::kInterfaceHandle:
        case coded::Type::Kind::kStructPointer:
        case coded::Type::Kind::kTablePointer:
        case coded::Type::Kind::kUnionPointer:
        case coded::Type::Kind::kXUnionPointer:
        case coded::Type::Kind::kMessage:
        case coded::Type::Kind::kRequestHandle:
        case coded::Type::Kind::kHandle:
        case coded::Type::Kind::kArray:
        case coded::Type::Kind::kVector:
        case coded::Type::Kind::kString:
            assert(false && "anonymous type in named type map!");
            break;
        }
        return coded_type;
    }
    }
}

void TablesGenerator::CompileFields(const flat::Decl* decl) {
    switch (decl->kind) {
    case flat::Decl::Kind::kInterface: {
        auto interface_decl = static_cast<const flat::Interface*>(decl);
        coded::InterfaceType* coded_interface =
            static_cast<coded::InterfaceType*>(named_coded_types_[&decl->name].get());
        size_t i = 0;
        for (const auto& method_pointer : interface_decl->all_methods) {
            assert(method_pointer != nullptr);
            const auto& method = *method_pointer;
            auto CompileMessage = [&](const flat::Struct& message) -> void {
                std::unique_ptr<coded::MessageType>& coded_message = coded_interface->messages[i++];
                std::vector<coded::StructField>& request_fields = coded_message->fields;
                for (const auto& parameter : message.members) {
                    std::string parameter_name =
                        coded_message->coded_name + "_" + std::string(parameter.name.data());
                    auto coded_parameter_type = CompileType(parameter.type.get());
                    if (coded_parameter_type->coding_needed == coded::CodingNeeded::kNeeded)
                        request_fields.emplace_back(coded_parameter_type,
                                                    parameter.fieldshape.Offset());
                }
                // We move the coded_message to coded_types_ so that we'll generate tables for the
                // message
                // in the proper order.
                coded_types_.push_back(std::move(coded_message));
            };
            if (method.maybe_request) {
                CompileMessage(*method.maybe_request);
            }
            if (method.maybe_response) {
                CompileMessage(*method.maybe_response);
            }
        }
        break;
    }
    case flat::Decl::Kind::kStruct: {
        auto struct_decl = static_cast<const flat::Struct*>(decl);
        if (struct_decl->anonymous)
            break;
        coded::StructType* coded_struct =
            static_cast<coded::StructType*>(named_coded_types_[&decl->name].get());
        std::vector<coded::StructField>& struct_fields = coded_struct->fields;
        for (const auto& member : struct_decl->members) {
            std::string member_name =
                coded_struct->coded_name + "_" + std::string(member.name.data());
            auto coded_member_type = CompileType(member.type.get());
            if (coded_member_type->coding_needed == coded::CodingNeeded::kNeeded)
                struct_fields.emplace_back(coded_member_type, member.fieldshape.Offset());
        }
        break;
    }
    case flat::Decl::Kind::kUnion: {
        auto union_decl = static_cast<const flat::Union*>(decl);
        coded::UnionType* union_struct =
            static_cast<coded::UnionType*>(named_coded_types_[&decl->name].get());
        std::vector<const coded::Type*>& union_members = union_struct->types;
        for (const auto& member : union_decl->members) {
            std::string member_name =
                union_struct->coded_name + "_" + std::string(member.name.data());
            auto coded_member_type = CompileType(member.type.get());
            if (coded_member_type->coding_needed == coded::CodingNeeded::kNeeded) {
                union_members.push_back(coded_member_type);
            } else {
                // We need union_members.size() to match union_decl->members.size() because
                // the coding tables will use the union |tag| to index into the member array.
                union_members.push_back(nullptr);
            }
        }
        break;
    }
    case flat::Decl::Kind::kXUnion: {
        auto xunion_decl = static_cast<const flat::XUnion*>(decl);
        auto coded_xunion =
            static_cast<coded::XUnionType*>(named_coded_types_[&decl->name].get());

        std::map<uint32_t, const flat::XUnion::Member*> members;
        for (const auto& member : xunion_decl->members) {
            if (!members.emplace(member.ordinal->value, &member).second) {
                assert(false && "Duplicate ordinal found in table generation");
            }
        }

        for (const auto& member_pair : members) {
            const auto& member = *member_pair.second;
            auto coded_member_type = CompileType(member.type.get());
            if (coded_member_type->coding_needed == coded::CodingNeeded::kNeeded) {
                coded_xunion->fields.emplace_back(coded_member_type, member.ordinal->value);
            }
        }
        break;
    }
    case flat::Decl::Kind::kTable: {
        auto table_decl = static_cast<const flat::Table*>(decl);
        coded::TableType* coded_table =
            static_cast<coded::TableType*>(named_coded_types_[&decl->name].get());
        std::vector<coded::TableField>& table_fields = coded_table->fields;
        std::map<uint32_t, const flat::Table::Member*> members;
        for (const auto& member : table_decl->members) {
            if (!members.emplace(member.ordinal->value, &member).second) {
                assert(false && "Duplicate ordinal found in table generation");
            }
        }
        for (const auto& member_pair : members) {
            const auto& member = *member_pair.second;
            if (!member.maybe_used)
                continue;
            std::string member_name =
                coded_table->coded_name + "_" + std::string(member.maybe_used->name.data());
            auto coded_member_type = CompileType(member.maybe_used->type.get());
            if (coded_member_type->coding_needed == coded::CodingNeeded::kNeeded)
                table_fields.emplace_back(coded_member_type, member.ordinal->value);
        }
        break;
    }
    default: {
        break;
    }
    }
}

void TablesGenerator::Compile(const flat::Decl* decl) {
    switch (decl->kind) {
    case flat::Decl::Kind::kConst:
        // Nothing to do for const declarations.
        break;
    case flat::Decl::Kind::kEnum: {
        auto enum_decl = static_cast<const flat::Enum*>(decl);
        std::string enum_name = NameName(enum_decl->name, "_", "_");
        named_coded_types_.emplace(&enum_decl->name,
                                   std::make_unique<coded::PrimitiveType>(
                                       std::move(enum_name), enum_decl->type->subtype,
                                       flat::PrimitiveType::SubtypeSize(enum_decl->type->subtype)));
        break;
    }
    case flat::Decl::Kind::kInterface: {
        auto interface_decl = static_cast<const flat::Interface*>(decl);
        std::string interface_name = NameInterface(*interface_decl);
        std::string interface_qname = NameName(interface_decl->name, ".", "/");
        std::vector<std::unique_ptr<coded::MessageType>> interface_messages;
        for (const auto& method_pointer : interface_decl->all_methods) {
            assert(method_pointer != nullptr);
            const auto& method = *method_pointer;
            std::string method_name = NameMethod(interface_name, method);
            std::string method_qname = NameMethod(interface_qname, method);
            auto CreateMessage = [&](const flat::Struct& message,
                                     types::MessageKind kind) -> void {
                std::string message_name = NameMessage(method_name, kind);
                std::string message_qname = NameMessage(method_qname, kind);
                interface_messages.push_back(std::make_unique<coded::MessageType>(
                    std::move(message_name), std::vector<coded::StructField>(),
                    message.typeshape.Size(), std::move(message_qname)));
            };
            if (method.maybe_request) {
                CreateMessage(*method.maybe_request, types::MessageKind::kRequest);
            }
            if (method.maybe_response) {
                auto kind = method.maybe_request ? types::MessageKind::kResponse
                                                 : types::MessageKind::kEvent;
                CreateMessage(*method.maybe_response, kind);
            }
        }
        named_coded_types_.emplace(
            &decl->name, std::make_unique<coded::InterfaceType>(std::move(interface_messages)));
        break;
    }
    case flat::Decl::Kind::kTable: {
        auto table_decl = static_cast<const flat::Table*>(decl);
        std::string table_name = NameCodedTable(table_decl);
        std::string pointer_name = NamePointer(table_name);
        named_coded_types_.emplace(
            &decl->name,
            std::make_unique<coded::TableType>(std::move(table_name), std::vector<coded::TableField>(),
                                               table_decl->typeshape.Size(),
                                               std::move(pointer_name), NameName(table_decl->name, ".", "/")));
        break;
    }
    case flat::Decl::Kind::kStruct: {
        auto struct_decl = static_cast<const flat::Struct*>(decl);
        if (struct_decl->anonymous)
            break;
        std::string struct_name = NameCodedStruct(struct_decl);
        std::string pointer_name = NamePointer(struct_name);
        named_coded_types_.emplace(
            &decl->name,
            std::make_unique<coded::StructType>(std::move(struct_name), std::vector<coded::StructField>(),
                                                struct_decl->typeshape.Size(),
                                                std::move(pointer_name), NameName(struct_decl->name, ".", "/")));
        break;
    }
    case flat::Decl::Kind::kUnion: {
        auto union_decl = static_cast<const flat::Union*>(decl);
        std::string union_name = NameCodedUnion(union_decl);
        std::string pointer_name = NamePointer(union_name);
        named_coded_types_.emplace(
            &decl->name, std::make_unique<coded::UnionType>(
                             std::move(union_name), std::vector<const coded::Type*>(),
                             union_decl->membershape.Offset(), union_decl->typeshape.Size(),
                             std::move(pointer_name), NameName(union_decl->name, ".", "/")));
        break;
    }
    case flat::Decl::Kind::kXUnion: {
        auto xunion_decl = static_cast<const flat::XUnion*>(decl);
        std::string xunion_name = NameCodedXUnion(xunion_decl);
        std::string pointer_name = NamePointer(xunion_name);
        named_coded_types_.emplace(
            &decl->name, std::make_unique<coded::XUnionType>(
                             std::move(xunion_name), std::vector<coded::XUnionField>(),
                             std::move(pointer_name), NameName(xunion_decl->name, ".", "/")));
        break;
    }
    }
}

std::ostringstream TablesGenerator::Produce() {
    GenerateFilePreamble();

    for (const auto& decl : library_->declaration_order_) {
        Compile(decl);
    }

    for (const auto& decl : library_->declaration_order_) {
        if (decl->name.library() != library_)
            continue;
        CompileFields(decl);
    }

    for (const auto& decl : library_->declaration_order_) {
        coded::Type* coded_type = named_coded_types_[&decl->name].get();
        if (!coded_type)
            continue;
        switch (coded_type->kind) {
        case coded::Type::Kind::kStruct:
            GenerateForward(*static_cast<const coded::StructType*>(coded_type));
            break;
        case coded::Type::Kind::kTable:
            GenerateForward(*static_cast<const coded::TableType*>(coded_type));
            break;
        case coded::Type::Kind::kUnion:
            GenerateForward(*static_cast<const coded::UnionType*>(coded_type));
            break;
        case coded::Type::Kind::kXUnion:
            GenerateForward(*static_cast<const coded::XUnionType*>(coded_type));
            break;
        default:
            break;
        }
    }

    Emit(&tables_file_, "\n");

    for (const auto& decl : library_->declaration_order_) {
        coded::Type* coded_type = named_coded_types_[&decl->name].get();
        if (!coded_type)
            continue;
        switch (coded_type->kind) {
        case coded::Type::Kind::kStruct:
            GeneratePointerIfNeeded(*static_cast<const coded::StructType*>(coded_type));
            break;
        case coded::Type::Kind::kTable:
            GeneratePointerIfNeeded(*static_cast<const coded::TableType*>(coded_type));
            break;
        case coded::Type::Kind::kUnion:
            GeneratePointerIfNeeded(*static_cast<const coded::UnionType*>(coded_type));
            break;
        case coded::Type::Kind::kXUnion:
            GeneratePointerIfNeeded(*static_cast<const coded::XUnionType*>(coded_type));
            break;
        default:
            break;
        }
    }

    Emit(&tables_file_, "\n");

    for (const auto& coded_type : coded_types_) {
        if (coded_type->coding_needed == coded::CodingNeeded::kNotNeeded)
            continue;

        switch (coded_type->kind) {
        case coded::Type::Kind::kStruct:
        case coded::Type::Kind::kStructPointer:
        case coded::Type::Kind::kTable:
        case coded::Type::Kind::kTablePointer:
        case coded::Type::Kind::kUnion:
        case coded::Type::Kind::kUnionPointer:
        case coded::Type::Kind::kXUnion:
        case coded::Type::Kind::kXUnionPointer:
            // These are generated in the next phase.
            break;
        case coded::Type::Kind::kInterface:
            // Nothing to generate for interfaces. We've already moved the
            // messages from the interface into coded_types_ directly.
            break;
        case coded::Type::Kind::kMessage:
            Generate(*static_cast<const coded::MessageType*>(coded_type.get()));
            break;
        case coded::Type::Kind::kHandle:
            Generate(*static_cast<const coded::HandleType*>(coded_type.get()));
            break;
        case coded::Type::Kind::kInterfaceHandle:
            Generate(*static_cast<const coded::InterfaceHandleType*>(coded_type.get()));
            break;
        case coded::Type::Kind::kRequestHandle:
            Generate(*static_cast<const coded::RequestHandleType*>(coded_type.get()));
            break;
        case coded::Type::Kind::kArray:
            Generate(*static_cast<const coded::ArrayType*>(coded_type.get()));
            break;
        case coded::Type::Kind::kString:
            Generate(*static_cast<const coded::StringType*>(coded_type.get()));
            break;
        case coded::Type::Kind::kVector:
            Generate(*static_cast<const coded::VectorType*>(coded_type.get()));
            break;
        case coded::Type::Kind::kPrimitive:
            // These are only around to provide size information to
            // vectors. There's never anything to generate, and this
            // should not be reached.
            assert(false && "Primitive types should never need coding tables");
            break;
        }
    }

    for (const auto& decl : library_->declaration_order_) {
        if (decl->name.library() != library_)
            continue;

        coded::Type* coded_type = named_coded_types_[&decl->name].get();
        if (!coded_type)
            continue;
        switch (coded_type->kind) {
        case coded::Type::Kind::kStruct:
            Generate(*static_cast<const coded::StructType*>(coded_type));
            break;
        case coded::Type::Kind::kTable:
            Generate(*static_cast<const coded::TableType*>(coded_type));
            break;
        case coded::Type::Kind::kUnion:
            Generate(*static_cast<const coded::UnionType*>(coded_type));
            break;
        case coded::Type::Kind::kXUnion:
            Generate(*static_cast<const coded::XUnionType*>(coded_type));
            break;
        default:
            continue;
        }
    }

    GenerateFilePostamble();

    return std::move(tables_file_);
}

} // namespace fidl
