// 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/c_generator.h"

#include "fidl/attributes.h"
#include "fidl/names.h"

namespace fidl {

namespace {

// Various string values are looked up or computed in these
// functions. Nothing else should be dealing in string literals, or
// computing strings from these or AST values.

constexpr const char* kIndent = "    ";

CGenerator::Member MessageHeader() {
    return {flat::Type::Kind::kIdentifier, "fidl_message_header_t", "hdr", {}, {}};
}

// Functions named "Emit..." are called to actually emit to an std::ostream
// is here. No other functions should directly emit to the streams.

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

void EmitFileComment(std::ostream* file) {
    *file << "// WARNING: This file is machine generated by fidlc.\n\n";
}

void EmitHeaderGuard(std::ostream* file) {
    // TODO(704) Generate an appropriate header guard name.
    *file << "#pragma once\n";
}

void EmitIncludeHeader(std::ostream* file, StringView header) {
    *file << "#include " << header << "\n";
}

void EmitBeginExternC(std::ostream* file) {
    *file << "#if defined(__cplusplus)\nextern \"C\" {\n#endif\n";
}

void EmitEndExternC(std::ostream* file) {
    *file << "#if defined(__cplusplus)\n}\n#endif\n";
}

void EmitBlank(std::ostream* file) {
    *file << "\n";
}

void EmitMemberDecl(std::ostream* file, const CGenerator::Member& member) {
    *file << member.type << " " << member.name;
    for (uint32_t array_count : member.array_counts) {
        *file << "[" << array_count << "]";
    }
}

void EmitMethodInParamDecl(std::ostream* file, const CGenerator::Member& member) {
    switch (member.kind) {
    case flat::Type::Kind::kArray:
        *file << "const " << member.type << " " << member.name;
        for (uint32_t array_count : member.array_counts) {
            *file << "[" << array_count << "]";
        }
        break;
    case flat::Type::Kind::kVector:
        *file << "const " << member.element_type << "* " << member.name << "_data, "
              << "size_t " << member.name << "_count";
        break;
    case flat::Type::Kind::kString:
        *file << "const char* " << member.name << "_data, "
              << "size_t " << member.name << "_size";
        break;
    case flat::Type::Kind::kHandle:
    case flat::Type::Kind::kRequestHandle:
    case flat::Type::Kind::kPrimitive:
        *file << member.type << " " << member.name;
        break;
    case flat::Type::Kind::kIdentifier:
        *file << "const " << member.type << "* " << member.name;
        break;
    }
}

void EmitMethodOutParamDecl(std::ostream* file, const CGenerator::Member& member) {
    switch (member.kind) {
    case flat::Type::Kind::kArray:
        *file << member.type << " out_" << member.name;
        for (uint32_t array_count : member.array_counts) {
            *file << "[" << array_count << "]";
        }
    case flat::Type::Kind::kVector:
        *file << member.element_type << "* " << member.name << "_data, "
              << "size_t " << member.name << "_capacity, "
              << "size_t* out_" << member.name << "_count";
        break;
    case flat::Type::Kind::kString:
        *file << "char* " << member.name << "_data, "
              << "size_t " << member.name << "_capacity, "
              << "size_t* out_" << member.name << "_size";
        break;
    case flat::Type::Kind::kHandle:
    case flat::Type::Kind::kRequestHandle:
    case flat::Type::Kind::kPrimitive:
    case flat::Type::Kind::kIdentifier:
        *file << member.type << "* " << member.name;
        break;
    }
}

void EmitClientMethodDecl(std::ostream* file, StringView method_name,
                          const std::vector<CGenerator::Member>& request,
                          const std::vector<CGenerator::Member>& response) {
    *file << "zx_status_t " << method_name << "(zx_handle_t _channel";
    for (const auto& member : request) {
        *file << ", ";
        EmitMethodInParamDecl(file, member);
    }
    for (auto member : response) {
        *file << ", ";
        EmitMethodOutParamDecl(file, member);
    }
    *file << ")";
}

void EmitServerMethodDecl(std::ostream* file, StringView method_name,
                          const std::vector<CGenerator::Member>& request,
                          bool has_response) {
    *file << "zx_status_t (*" << method_name << ")(void* ctx";
    for (const auto& member : request) {
        *file << ", ";
        EmitMethodInParamDecl(file, member);
    }
    if (has_response) {
        *file << ", fidl_txn_t* txn";
    }
    *file << ")";
}

void EmitServerDispatchDecl(std::ostream* file, StringView interface_name) {
    *file << "zx_status_t " << interface_name
          << "_dispatch(void* ctx, fidl_txn_t* txn, fidl_msg_t* msg, const "
          << interface_name << "_ops_t* ops)";
}

void EmitServerReplyDecl(std::ostream* file, StringView method_name,
                         const std::vector<CGenerator::Member>& response) {
    *file << "zx_status_t " << method_name << "_reply(fidl_txn_t* _txn";
    for (const auto& member : response) {
        *file << ", ";
        EmitMethodInParamDecl(file, member);
    }
    *file << ")";
}

void EmitMeasureParams(std::ostream* file,
                       const std::vector<CGenerator::Member>& params,
                       StringView vector_suffix,
                       StringView string_suffix) {
    for (const auto& member : params) {
        if (member.kind == flat::Type::Kind::kVector)
            *file << " + FIDL_ALIGN(sizeof(*" << member.name << "_data) * " << member.name << vector_suffix << ")";
        else if (member.kind == flat::Type::Kind::kString)
            *file << " + FIDL_ALIGN(" << member.name << string_suffix << ")";
    }
}

// This function assumes the |params| are part of a [Layout="Simple"] interface.
// In particular, simple interfaces don't have nullable structs or nested
// vectors. The only secondary objects they contain are top-level vectors and
// strings.
size_t CountSecondaryObjects(const std::vector<CGenerator::Member>& params) {
    size_t count = 0u;
    for (const auto& member : params) {
        if (member.kind == flat::Type::Kind::kVector ||
            member.kind == flat::Type::Kind::kString)
            ++count;
    }
    return count;
}

void EmitLinearizeMessage(std::ostream* file,
                          StringView receiver,
                          StringView bytes,
                          const std::vector<CGenerator::Member>& request) {
    if (CountSecondaryObjects(request) > 0)
        *file << kIndent << "uint32_t _next = sizeof(*" << receiver << ");\n";
    for (const auto& member : request) {
        const auto& name = member.name;
        switch (member.kind) {
        case flat::Type::Kind::kArray:
            *file << kIndent << "memcpy(" << receiver << "->" << name << ", "
                  << name << ", sizeof(" << receiver << "->" << name << "));\n";
            break;
        case flat::Type::Kind::kVector:
            *file << kIndent << receiver << "->" << name << ".data = &" << bytes << "[_next];\n";
            *file << kIndent << receiver << "->" << name << ".count = " << name << "_count;\n";
            *file << kIndent << "memcpy(" << receiver << "->" << name << ".data, " << name << "_data, sizeof(*" << name << "_data) * " << name << "_count);\n";
            *file << kIndent << "_next += FIDL_ALIGN(sizeof(*" << name << "_data) * " << name << "_count);\n";
            break;
        case flat::Type::Kind::kString:
            *file << kIndent << receiver << "->" << name << ".data = &" << bytes << "[_next];\n";
            *file << kIndent << receiver << "->" << name << ".size = " << name << "_size;\n";
            *file << kIndent << "memcpy(" << receiver << "->" << name << ".data, " << name << "_data, " << name << "_size);\n";
            *file << kIndent << "_next += FIDL_ALIGN(" << name << "_size);\n";
            break;
        case flat::Type::Kind::kHandle:
        case flat::Type::Kind::kRequestHandle:
        case flat::Type::Kind::kPrimitive:
            *file << kIndent << receiver << "->" << name << " = " << name << ";\n";
            break;
        case flat::Type::Kind::kIdentifier:
            *file << kIndent << receiver << "->" << name << " = *" << name << ";\n";
            break;
        }
    }
}

// Various computational helper routines.

void EnumValue(types::PrimitiveSubtype type, const flat::Constant* constant,
               const flat::Library* library, std::string* out_value) {
    // TODO(kulakowski) Move this into library resolution.

    std::ostringstream member_value;

    switch (type) {
    case types::PrimitiveSubtype::kInt8: {
        int8_t value;
        bool success = library->ParseIntegerConstant(constant, &value);
        if (!success) {
            __builtin_trap();
        }
        // The char-sized overloads of operator<< here print
        // the character value, not the numeric value, so cast up.
        member_value << static_cast<int>(value);
        break;
    }
    case types::PrimitiveSubtype::kInt16: {
        int16_t value;
        bool success = library->ParseIntegerConstant(constant, &value);
        if (!success) {
            __builtin_trap();
        }
        member_value << value;
        break;
    }
    case types::PrimitiveSubtype::kInt32: {
        int32_t value;
        bool success = library->ParseIntegerConstant(constant, &value);
        if (!success) {
            __builtin_trap();
        }
        member_value << value;
        break;
    }
    case types::PrimitiveSubtype::kInt64: {
        int64_t value;
        bool success = library->ParseIntegerConstant(constant, &value);
        if (!success) {
            __builtin_trap();
        }
        member_value << value;
        break;
    }
    case types::PrimitiveSubtype::kUint8: {
        uint8_t value;
        bool success = library->ParseIntegerConstant(constant, &value);
        if (!success) {
            __builtin_trap();
        }
        // The char-sized overloads of operator<< here print
        // the character value, not the numeric value, so cast up.
        member_value << static_cast<unsigned int>(value);
        break;
    }
    case types::PrimitiveSubtype::kUint16: {
        uint16_t value;
        bool success = library->ParseIntegerConstant(constant, &value);
        if (!success) {
            __builtin_trap();
        }
        member_value << value;
        break;
    }
    case types::PrimitiveSubtype::kUint32: {
        uint32_t value;
        bool success = library->ParseIntegerConstant(constant, &value);
        if (!success) {
            __builtin_trap();
        }
        member_value << value;
        break;
    }
    case types::PrimitiveSubtype::kUint64: {
        uint64_t value;
        bool success = library->ParseIntegerConstant(constant, &value);
        if (!success) {
            __builtin_trap();
        }
        member_value << value;
        break;
    }
    case types::PrimitiveSubtype::kBool:
    case types::PrimitiveSubtype::kStatus:
    case types::PrimitiveSubtype::kFloat32:
    case types::PrimitiveSubtype::kFloat64:
        assert(false && "bad primitive type for an enum");
        break;
    }

    *out_value = member_value.str();
}

std::vector<uint32_t> ArrayCounts(const flat::Library* library, const flat::Type* type) {
    std::vector<uint32_t> array_counts;
    for (;;) {
        switch (type->kind) {
        default: { return array_counts; }
        case flat::Type::Kind::kArray: {
            auto array_type = static_cast<const flat::ArrayType*>(type);
            uint32_t element_count = array_type->element_count.Value();
            array_counts.push_back(element_count);
            type = array_type->element_type.get();
            continue;
        }
        }
    }
}

template <typename T>
CGenerator::Member CreateMember(const flat::Library* library, const T& decl) {
    std::string name = NameIdentifier(decl.name);
    const flat::Type* type = decl.type.get();
    auto type_name = NameFlatCType(library, type);
    std::vector<uint32_t> array_counts = ArrayCounts(library, type);
    std::string element_type;
    if (type->kind == flat::Type::Kind::kVector) {
        auto vector_type = static_cast<const flat::VectorType*>(type);
        element_type = NameFlatCType(library, vector_type->element_type.get());
    }
    return CGenerator::Member{
        type->kind,
        std::move(type_name),
        std::move(name),
        std::move(element_type),
        std::move(array_counts),
    };
}

std::vector<CGenerator::Member>
GenerateMembers(const flat::Library* library,
                const std::vector<flat::Union::Member>& union_members) {
    std::vector<CGenerator::Member> members;
    members.reserve(union_members.size());
    for (const auto& union_member : union_members) {
        members.push_back(CreateMember(library, union_member));
    }
    return members;
}

void GetMethodParameters(const flat::Library* library,
                         const CGenerator::NamedMethod& method_info,
                         std::vector<CGenerator::Member>* request,
                         std::vector<CGenerator::Member>* response) {
    if (request) {
        request->reserve(method_info.request->parameters.size());
        for (const auto& parameter : method_info.request->parameters) {
            request->push_back(CreateMember(library, parameter));
        }
    }

    if (response && method_info.response) {
        response->reserve(method_info.request->parameters.size());
        for (const auto& parameter : method_info.response->parameters) {
            response->push_back(CreateMember(library, parameter));
        }
    }
}

} // namespace

void CGenerator::GeneratePrologues() {
    EmitFileComment(&file_);
    EmitHeaderGuard(&file_);
    EmitBlank(&file_);
    EmitIncludeHeader(&file_, "<stdalign.h>");
    EmitIncludeHeader(&file_, "<stdbool.h>");
    EmitIncludeHeader(&file_, "<stdint.h>");
    EmitIncludeHeader(&file_, "<zircon/fidl.h>");
    EmitIncludeHeader(&file_, "<zircon/syscalls/object.h>");
    EmitIncludeHeader(&file_, "<zircon/types.h>");
    for (const auto& pair : *library_->dependencies_) {
        if (pair.second.get() == library_)
            continue;
        EmitIncludeHeader(&file_, "<" + NameLibraryCHeader(pair.first) + ">");
    }
    EmitBlank(&file_);
    EmitBeginExternC(&file_);
    EmitBlank(&file_);
}

void CGenerator::GenerateEpilogues() {
    EmitEndExternC(&file_);
}

void CGenerator::GenerateIntegerDefine(StringView name, types::PrimitiveSubtype subtype,
                                       StringView value) {
    std::string literal_macro = NamePrimitiveIntegerCConstantMacro(subtype);
    file_ << "#define " << name << " " << literal_macro << "(" << value << ")\n";
}

void CGenerator::GenerateIntegerTypedef(types::PrimitiveSubtype subtype, StringView name) {
    std::string underlying_type = NamePrimitiveCType(subtype);
    file_ << "typedef " << underlying_type << " " << name << ";\n";
}

void CGenerator::GenerateStructTypedef(StringView name) {
    file_ << "typedef struct " << name << " " << name << ";\n";
}

void CGenerator::GenerateStructDeclaration(StringView name, const std::vector<Member>& members) {
    file_ << "struct " << name << " {\n";
    file_ << kIndent << "FIDL_ALIGNDECL\n";
    for (const auto& member : members) {
        file_ << kIndent;
        EmitMemberDecl(&file_, member);
        file_ << ";\n";
    }
    file_ << "};\n";
}

void CGenerator::GenerateTaggedUnionDeclaration(StringView name,
                                                const std::vector<Member>& members) {
    file_ << "struct " << name << " {\n";
    file_ << kIndent << "FIDL_ALIGNDECL\n";
    file_ << kIndent << "fidl_union_tag_t tag;\n";
    file_ << kIndent << "union {\n";
    for (const auto& member : members) {
        file_ << kIndent << kIndent;
        EmitMemberDecl(&file_, member);
        file_ << ";\n";
    }
    file_ << kIndent << "};\n";
    file_ << "};\n";
}

// TODO(TO-702) These should maybe check for global name
// collisions? Otherwise, is there some other way they should fail?
std::map<const flat::Decl*, CGenerator::NamedConst>
CGenerator::NameConsts(const std::vector<std::unique_ptr<flat::Const>>& const_infos) {
    std::map<const flat::Decl*, NamedConst> named_consts;
    for (const auto& const_info : const_infos) {
        named_consts.emplace(const_info.get(), NamedConst{"", *const_info});
    }
    return named_consts;
}

std::map<const flat::Decl*, CGenerator::NamedEnum>
CGenerator::NameEnums(const std::vector<std::unique_ptr<flat::Enum>>& enum_infos) {
    std::map<const flat::Decl*, NamedEnum> named_enums;
    for (const auto& enum_info : enum_infos) {
        std::string enum_name = NameName(enum_info->name, "_", "_");
        named_enums.emplace(enum_info.get(), NamedEnum{std::move(enum_name), *enum_info});
    }
    return named_enums;
}

std::map<const flat::Decl*, CGenerator::NamedInterface>
CGenerator::NameInterfaces(const std::vector<std::unique_ptr<flat::Interface>>& interface_infos) {
    std::map<const flat::Decl*, NamedInterface> named_interfaces;
    for (const auto& interface_info : interface_infos) {
        NamedInterface named_interface;
        named_interface.c_name = NameInterface(*interface_info);
        if (interface_info->HasAttribute("Discoverable")) {
            named_interface.discoverable_name = NameDiscoverable(*interface_info);
        }
        for (const auto& method : interface_info->methods) {
            NamedMethod named_method;
            std::string method_name = NameMethod(named_interface.c_name, method);
            named_method.ordinal = method.ordinal.Value();
            named_method.ordinal_name = NameOrdinal(method_name);
            named_method.identifier = NameIdentifier(method.name);
            named_method.c_name = method_name;
            if (method.maybe_request != nullptr) {
                std::string c_name = NameMessage(method_name, types::MessageKind::kRequest);
                std::string coded_name = NameTable(c_name);
                named_method.request = std::make_unique<NamedMessage>(NamedMessage{
                    std::move(c_name), std::move(coded_name), method.maybe_request->parameters});
            }
            if (method.maybe_response != nullptr) {
                if (method.maybe_request == nullptr) {
                    std::string c_name =
                        NameMessage(method_name, types::MessageKind::kEvent);
                    std::string coded_name = NameTable(c_name);
                    named_method.response = std::make_unique<NamedMessage>(
                        NamedMessage{std::move(c_name), std::move(coded_name),
                                     method.maybe_response->parameters});
                } else {
                    std::string c_name = NameMessage(method_name, types::MessageKind::kResponse);
                    std::string coded_name = NameTable(c_name);
                    named_method.response = std::make_unique<NamedMessage>(
                        NamedMessage{std::move(c_name), std::move(coded_name),
                                     method.maybe_response->parameters});
                }
            }
            named_interface.methods.push_back(std::move(named_method));
        }
        named_interfaces.emplace(interface_info.get(), std::move(named_interface));
    }
    return named_interfaces;
}

std::map<const flat::Decl*, CGenerator::NamedStruct>
CGenerator::NameStructs(const std::vector<std::unique_ptr<flat::Struct>>& struct_infos) {
    std::map<const flat::Decl*, NamedStruct> named_structs;
    for (const auto& struct_info : struct_infos) {
        std::string c_name = NameName(struct_info->name, "_", "_");
        std::string coded_name = c_name + "Coded";
        named_structs.emplace(struct_info.get(),
                              NamedStruct{std::move(c_name), std::move(coded_name), *struct_info});
    }
    return named_structs;
}

std::map<const flat::Decl*, CGenerator::NamedUnion>
CGenerator::NameUnions(const std::vector<std::unique_ptr<flat::Union>>& union_infos) {
    std::map<const flat::Decl*, NamedUnion> named_unions;
    for (const auto& union_info : union_infos) {
        std::string union_name = NameName(union_info->name, "_", "_");
        named_unions.emplace(union_info.get(), NamedUnion{std::move(union_name), *union_info});
    }
    return named_unions;
}

void CGenerator::ProduceConstForwardDeclaration(const NamedConst& named_const) {
    // TODO(TO-702)
}

void CGenerator::ProduceEnumForwardDeclaration(const NamedEnum& named_enum) {
    types::PrimitiveSubtype subtype = named_enum.enum_info.type;
    GenerateIntegerTypedef(subtype, named_enum.name);
    for (const auto& member : named_enum.enum_info.members) {
        std::string member_name = named_enum.name + "_" + NameIdentifier(member.name);
        std::string member_value;
        EnumValue(named_enum.enum_info.type, member.value.get(), library_, &member_value);
        GenerateIntegerDefine(member_name, subtype, std::move(member_value));
    }

    EmitBlank(&file_);
}

void CGenerator::ProduceInterfaceForwardDeclaration(const NamedInterface& named_interface) {
    if (!named_interface.discoverable_name.empty()) {
        file_ << "#define " << named_interface.c_name << "_Name \"" << named_interface.discoverable_name << "\"\n";
    }
    for (const auto& method_info : named_interface.methods) {
        file_ << "#define " << method_info.ordinal_name << " ((uint32_t)"
              << method_info.ordinal << ")\n";
        if (method_info.request)
            GenerateStructTypedef(method_info.request->c_name);
        if (method_info.response)
            GenerateStructTypedef(method_info.response->c_name);
    }
}

void CGenerator::ProduceStructForwardDeclaration(const NamedStruct& named_struct) {
    GenerateStructTypedef(named_struct.c_name);
}

void CGenerator::ProduceUnionForwardDeclaration(const NamedUnion& named_union) {
    GenerateStructTypedef(named_union.name);
}

void CGenerator::ProduceInterfaceExternDeclaration(const NamedInterface& named_interface) {
    for (const auto& method_info : named_interface.methods) {
        if (method_info.request)
            file_ << "extern const fidl_type_t " << method_info.request->coded_name << ";\n";
        if (method_info.response)
            file_ << "extern const fidl_type_t " << method_info.response->coded_name
                  << ";\n";
    }
}

void CGenerator::ProduceConstDeclaration(const NamedConst& named_const) {
    // TODO(TO-702)
    static_cast<void>(named_const);

    EmitBlank(&file_);
}

void CGenerator::ProduceMessageDeclaration(const NamedMessage& named_message) {
    std::vector<CGenerator::Member> members;
    members.reserve(1 + named_message.parameters.size());
    members.push_back(MessageHeader());
    for (const auto& parameter : named_message.parameters) {
        members.push_back(CreateMember(library_, parameter));
    }

    GenerateStructDeclaration(named_message.c_name, members);

    EmitBlank(&file_);
}

void CGenerator::ProduceInterfaceDeclaration(const NamedInterface& named_interface) {
    for (const auto& method_info : named_interface.methods) {
        if (method_info.request)
            ProduceMessageDeclaration(*method_info.request);
        if (method_info.response)
            ProduceMessageDeclaration(*method_info.response);
    }
}

void CGenerator::ProduceStructDeclaration(const NamedStruct& named_struct) {
    std::vector<CGenerator::Member> members;
    members.reserve(named_struct.struct_info.members.size());
    for (const auto& struct_member : named_struct.struct_info.members) {
        members.push_back(CreateMember(library_, struct_member));
    }

    GenerateStructDeclaration(named_struct.c_name, members);

    EmitBlank(&file_);
}

void CGenerator::ProduceUnionDeclaration(const NamedUnion& named_union) {
    std::vector<CGenerator::Member> members =
        GenerateMembers(library_, named_union.union_info.members);
    GenerateTaggedUnionDeclaration(named_union.name, members);

    uint32_t tag = 0u;
    for (const auto& member : named_union.union_info.members) {
        std::string tag_name = NameUnionTag(named_union.name, member);
        auto union_tag_type = types::PrimitiveSubtype::kUint32;
        std::ostringstream value;
        value << tag;
        GenerateIntegerDefine(std::move(tag_name), union_tag_type, value.str());
        ++tag;
    }

    EmitBlank(&file_);
}

void CGenerator::ProduceInterfaceClientDeclaration(const NamedInterface& named_interface) {
    for (const auto& method_info : named_interface.methods) {
        if (!method_info.request)
            continue;
        std::vector<Member> request;
        std::vector<Member> response;
        GetMethodParameters(library_, method_info, &request, &response);
        EmitClientMethodDecl(&file_, method_info.c_name, request, response);
        file_ << ";\n";
    }

    EmitBlank(&file_);
}

void CGenerator::ProduceInterfaceClientImplementation(const NamedInterface& named_interface) {
    for (const auto& method_info : named_interface.methods) {
        if (!method_info.request)
            continue;
        std::vector<Member> request;
        std::vector<Member> response;
        GetMethodParameters(library_, method_info, &request, &response);
        EmitClientMethodDecl(&file_, method_info.c_name, request, response);
        file_ << " {\n";
        file_ << kIndent << "uint32_t _wr_num_bytes = sizeof(" << method_info.request->c_name << ")";
        EmitMeasureParams(&file_, request, "_count", "_size");
        file_ << ";\n";
        file_ << kIndent << "FIDL_ALIGNDECL char _wr_bytes[_wr_num_bytes];\n";
        file_ << kIndent << method_info.request->c_name << "* _request = (" << method_info.request->c_name << "*)_wr_bytes;\n";
        file_ << kIndent << "memset(_wr_bytes, 0, sizeof(_wr_bytes));\n";
        file_ << kIndent << "_request->hdr.ordinal = " << method_info.ordinal << ";\n";
        EmitLinearizeMessage(&file_, "_request", "_wr_bytes", request);
        file_ << kIndent << "zx_handle_t _handles[ZX_CHANNEL_MAX_MSG_HANDLES];\n";
        file_ << kIndent << "uint32_t _wr_num_handles = 0u;\n";
        file_ << kIndent << "zx_status_t _status = fidl_encode(&" << method_info.request->coded_name
              << ", _wr_bytes, _wr_num_bytes, _handles, ZX_CHANNEL_MAX_MSG_HANDLES"
              << ", &_wr_num_handles, NULL);\n";
        file_ << kIndent << "if (_status != ZX_OK)\n";
        file_ << kIndent << kIndent << "return _status;\n";
        if (!method_info.response) {
            file_ << kIndent << "return zx_channel_write(_channel, 0u, _wr_bytes, _wr_num_bytes, _handles, _wr_num_handles);\n";
        } else {
            file_ << kIndent << "uint32_t _rd_num_bytes = sizeof(" << method_info.response->c_name << ")";
            EmitMeasureParams(&file_, response, "_capacity", "_capacity");
            file_ << ";\n";
            file_ << kIndent << "FIDL_ALIGNDECL char _rd_bytes[_rd_num_bytes];\n";
            if (!response.empty())
                file_ << kIndent << method_info.response->c_name << "* _response = (" << method_info.response->c_name << "*)_rd_bytes;\n";
            file_ << kIndent << "zx_channel_call_args_t _args = {\n";
            file_ << kIndent << kIndent << ".wr_bytes = _wr_bytes,\n";
            file_ << kIndent << kIndent << ".wr_handles = _handles,\n";
            file_ << kIndent << kIndent << ".rd_bytes = _rd_bytes,\n";
            file_ << kIndent << kIndent << ".rd_handles = _handles,\n";
            file_ << kIndent << kIndent << ".wr_num_bytes = _wr_num_bytes,\n";
            file_ << kIndent << kIndent << ".wr_num_handles = _wr_num_handles,\n";
            file_ << kIndent << kIndent << ".rd_num_bytes = _rd_num_bytes,\n";
            file_ << kIndent << kIndent << ".rd_num_handles = ZX_CHANNEL_MAX_MSG_HANDLES,\n";
            file_ << kIndent << "};\n";

            file_ << kIndent << "uint32_t _actual_num_bytes = 0u;\n";
            file_ << kIndent << "uint32_t _actual_num_handles = 0u;\n";
            file_ << kIndent << "_status = zx_channel_call(_channel, 0u, ZX_TIME_INFINITE, &_args, &_actual_num_bytes, &_actual_num_handles);\n";
            file_ << kIndent << "if (_status != ZX_OK)\n";
            file_ << kIndent << kIndent << "return _status;\n";

            // We check that we have enough capacity to copy out the parameters
            // before decoding the message so that we can close the handles
            // using |_handles| rather than trying to find them in the decoded
            // message.
            size_t count = CountSecondaryObjects(response);
            if (count > 0u) {
                file_ << kIndent << "if ";
                if (count > 1u)
                    file_ << "(";
                size_t i = 0;
                for (const auto& member : response) {
                    if (member.kind == flat::Type::Kind::kVector) {
                        if (i++ > 0u)
                            file_ << " || ";
                        file_ << "(_response->" << member.name << ".count > " << member.name << "_capacity)";
                    } else if (member.kind == flat::Type::Kind::kString) {
                        if (i++ > 0u)
                            file_ << " || ";
                        file_ << "(_response->" << member.name << ".size > " << member.name << "_capacity)";
                    }
                }
                if (count > 1u)
                    file_ << ")";
                file_ << " {\n";
                file_ << kIndent << kIndent << "zx_handle_close_many(_handles, _actual_num_handles);\n";
                file_ << kIndent << kIndent << "return ZX_ERR_BUFFER_TOO_SMALL;\n";
                file_ << kIndent << "}\n";
            }

            // TODO(FIDL-162): Validate the response ordinal. C++ bindings also need to do that.
            file_ << kIndent << "_status = fidl_decode(&" << method_info.response->coded_name
                  << ", _rd_bytes, _actual_num_bytes, _handles, _actual_num_handles, NULL);\n";
            file_ << kIndent << "if (_status != ZX_OK)\n";
            file_ << kIndent << kIndent << "return _status;\n";

            for (const auto& member : response) {
                const auto& name = member.name;
                switch (member.kind) {
                case flat::Type::Kind::kArray:
                    file_ << kIndent << "memcpy(out_" << name << ", _response->" << name << ", sizeof(out_" << name << "));\n";
                    break;
                case flat::Type::Kind::kVector:
                    file_ << kIndent << "memcpy(" << name << "_data, _response->" << name << ".data, sizeof(*" << name << "_data) * _response->" << name << ".count);\n";
                    file_ << kIndent << "*out_" << name << "_count = _response->" << name << ".count;\n";
                    break;
                case flat::Type::Kind::kString:
                    file_ << kIndent << "memcpy(" << name << "_data, _response->" << name << ".data, _response->" << name << ".size);\n";
                    file_ << kIndent << "*out_" << name << "_size = _response->" << name << ".size;\n";
                    break;
                case flat::Type::Kind::kHandle:
                case flat::Type::Kind::kRequestHandle:
                case flat::Type::Kind::kPrimitive:
                case flat::Type::Kind::kIdentifier:
                    file_ << kIndent << "*" << name << " = _response->" << name << ";\n";
                    break;
                }
            }

            file_ << kIndent << "return ZX_OK;\n";
        }
        file_ << "}\n\n";
    }
} // namespace fidl

void CGenerator::ProduceInterfaceServerDeclaration(const NamedInterface& named_interface) {
    file_ << "typedef struct " << named_interface.c_name << "_ops {\n";
    for (const auto& method_info : named_interface.methods) {
        if (!method_info.request)
            continue;
        std::vector<Member> request;
        GetMethodParameters(library_, method_info, &request, nullptr);
        bool has_response = method_info.response != nullptr;
        file_ << kIndent;
        EmitServerMethodDecl(&file_, method_info.identifier, request, has_response);
        file_ << ";\n";
    }
    file_ << "} " << named_interface.c_name << "_ops_t;\n\n";

    EmitServerDispatchDecl(&file_, named_interface.c_name);
    file_ << ";\n\n";

    for (const auto& method_info : named_interface.methods) {
        if (!method_info.request || !method_info.response)
            continue;
        std::vector<Member> response;
        GetMethodParameters(library_, method_info, nullptr, &response);
        EmitServerReplyDecl(&file_, method_info.c_name, response);
        file_ << ";\n";
    }

    EmitBlank(&file_);
}

void CGenerator::ProduceInterfaceServerImplementation(const NamedInterface& named_interface) {
    EmitServerDispatchDecl(&file_, named_interface.c_name);
    file_ << " {\n";
    file_ << kIndent << "if (msg->num_bytes < sizeof(fidl_message_header_t))\n";
    file_ << kIndent << kIndent << "return ZX_ERR_INVALID_ARGS;\n";
    file_ << kIndent << "fidl_message_header_t* hdr = (fidl_message_header_t*)msg->bytes;\n";
    file_ << kIndent << "zx_status_t status = ZX_OK;\n";
    file_ << kIndent << "switch (hdr->ordinal) {\n";

    for (const auto& method_info : named_interface.methods) {
        if (!method_info.request)
            continue;
        file_ << kIndent << "case " << method_info.ordinal_name << ": {\n";
        file_ << kIndent << kIndent << "status = fidl_decode_msg(&" << method_info.request->coded_name << ", msg, NULL);\n";
        file_ << kIndent << kIndent << "if (status != ZX_OK)\n";
        file_ << kIndent << kIndent << kIndent << "break;\n";
        std::vector<Member> request;
        GetMethodParameters(library_, method_info, &request, nullptr);
        if (!request.empty())
            file_ << kIndent << kIndent << method_info.request->c_name << "* request = (" << method_info.request->c_name << "*)msg->bytes;\n";
        file_ << kIndent << kIndent << "status = (*ops->" << method_info.identifier << ")(ctx";
        for (const auto& member : request) {
            switch (member.kind) {
            case flat::Type::Kind::kArray:
            case flat::Type::Kind::kHandle:
            case flat::Type::Kind::kRequestHandle:
            case flat::Type::Kind::kPrimitive:
                file_ << ", request->" << member.name;
                break;
            case flat::Type::Kind::kVector:
                file_ << ", (" << member.element_type << "*)request->" << member.name << ".data"
                      << ", request->" << member.name << ".count";
                break;
            case flat::Type::Kind::kString:
                file_ << ", request->" << member.name << ".data"
                      << ", request->" << member.name << ".size";
                break;
            case flat::Type::Kind::kIdentifier:
                file_ << ", &(request->" << member.name << ")";
                break;
            }
        }
        if (method_info.response != nullptr)
            file_ << ", txn";
        file_ << ");\n";
        file_ << kIndent << kIndent << "break;\n";
        file_ << kIndent << "}\n";
    }
    file_ << kIndent << "default: {\n";
    file_ << kIndent << kIndent << "zx_handle_close_many(msg->handles, msg->num_handles);\n";
    file_ << kIndent << kIndent << "status = ZX_ERR_NOT_SUPPORTED;\n";
    file_ << kIndent << kIndent << "break;\n";
    file_ << kIndent << "}\n";
    file_ << kIndent << "}\n";
    file_ << kIndent << "return status;\n";
    file_ << "}\n\n";

    for (const auto& method_info : named_interface.methods) {
        if (!method_info.request || !method_info.response)
            continue;
        std::vector<Member> response;
        GetMethodParameters(library_, method_info, nullptr, &response);
        EmitServerReplyDecl(&file_, method_info.c_name, response);
        file_ << " {\n";
        file_ << kIndent << "uint32_t _wr_num_bytes = sizeof(" << method_info.response->c_name << ")";
        EmitMeasureParams(&file_, response, "_count", "_size");
        file_ << ";\n";
        file_ << kIndent << "char _wr_bytes[_wr_num_bytes];\n";
        file_ << kIndent << method_info.response->c_name << "* _response = (" << method_info.response->c_name << "*)_wr_bytes;\n";
        file_ << kIndent << "memset(_wr_bytes, 0, sizeof(_wr_bytes));\n";
        file_ << kIndent << "_response->hdr.ordinal = " << method_info.ordinal << ";\n";
        EmitLinearizeMessage(&file_, "_response", "_wr_bytes", response);
        file_ << kIndent << "zx_handle_t _handles[ZX_CHANNEL_MAX_MSG_HANDLES];\n";
        file_ << kIndent << "fidl_msg_t _msg = {\n";
        file_ << kIndent << kIndent << ".bytes = _wr_bytes,\n";
        file_ << kIndent << kIndent << ".handles = _handles,\n";
        file_ << kIndent << kIndent << ".num_bytes = _wr_num_bytes,\n";
        file_ << kIndent << kIndent << ".num_handles = ZX_CHANNEL_MAX_MSG_HANDLES,\n";
        file_ << kIndent << "};\n";
        file_ << kIndent << "zx_status_t _status = fidl_encode_msg(&"
              << method_info.response->coded_name << ", &_msg, &_msg.num_handles, NULL);\n";
        file_ << kIndent << "if (_status != ZX_OK)\n";
        file_ << kIndent << kIndent << "return _status;\n";
        file_ << kIndent << "return _txn->reply(_txn, &_msg);\n";
        file_ << "}\n\n";
    }
}

std::ostringstream CGenerator::ProduceHeader() {
    GeneratePrologues();

    std::map<const flat::Decl*, NamedConst> named_consts =
        NameConsts(library_->const_declarations_);
    std::map<const flat::Decl*, NamedEnum> named_enums = NameEnums(library_->enum_declarations_);
    std::map<const flat::Decl*, NamedInterface> named_interfaces =
        NameInterfaces(library_->interface_declarations_);
    std::map<const flat::Decl*, NamedStruct> named_structs =
        NameStructs(library_->struct_declarations_);
    std::map<const flat::Decl*, NamedUnion> named_unions =
        NameUnions(library_->union_declarations_);

    file_ << "\n// Forward declarations\n\n";

    for (const auto* decl : library_->declaration_order_) {
        switch (decl->kind) {
        case flat::Decl::Kind::kConst: {
            auto iter = named_consts.find(decl);
            if (iter != named_consts.end()) {
                ProduceConstForwardDeclaration(iter->second);
            }
            break;
        }
        case flat::Decl::Kind::kEnum: {
            auto iter = named_enums.find(decl);
            if (iter != named_enums.end()) {
                ProduceEnumForwardDeclaration(iter->second);
            }
            break;
        }
        case flat::Decl::Kind::kInterface: {
            auto iter = named_interfaces.find(decl);
            if (iter != named_interfaces.end()) {
                ProduceInterfaceForwardDeclaration(iter->second);
            }
            break;
        }
        case flat::Decl::Kind::kStruct: {
            auto iter = named_structs.find(decl);
            if (iter != named_structs.end()) {
                ProduceStructForwardDeclaration(iter->second);
            }
            break;
        }
        case flat::Decl::Kind::kUnion: {
            auto iter = named_unions.find(decl);
            if (iter != named_unions.end()) {
                ProduceUnionForwardDeclaration(iter->second);
            }
            break;
        }
        default:
            abort();
        }
    }

    file_ << "\n// Extern declarations\n\n";

    for (const auto* decl : library_->declaration_order_) {
        switch (decl->kind) {
        case flat::Decl::Kind::kConst:
        case flat::Decl::Kind::kEnum:
        case flat::Decl::Kind::kStruct:
        case flat::Decl::Kind::kUnion:
            // Only messages have extern fidl_type_t declarations.
            break;
        case flat::Decl::Kind::kInterface: {
            auto iter = named_interfaces.find(decl);
            if (iter != named_interfaces.end()) {
                ProduceInterfaceExternDeclaration(iter->second);
            }
            break;
        }
        default:
            abort();
        }
    }

    file_ << "\n// Declarations\n\n";

    for (const auto* decl : library_->declaration_order_) {
        switch (decl->kind) {
        case flat::Decl::Kind::kConst: {
            auto iter = named_consts.find(decl);
            if (iter != named_consts.end()) {
                ProduceConstDeclaration(iter->second);
            }
            break;
        }
        case flat::Decl::Kind::kEnum:
            // Enums can be entirely forward declared, as they have no
            // dependencies other than standard headers.
            break;
        case flat::Decl::Kind::kInterface: {
            auto iter = named_interfaces.find(decl);
            if (iter != named_interfaces.end()) {
                ProduceInterfaceDeclaration(iter->second);
            }
            break;
        }
        case flat::Decl::Kind::kStruct: {
            auto iter = named_structs.find(decl);
            if (iter != named_structs.end()) {
                ProduceStructDeclaration(iter->second);
            }
            break;
        }
        case flat::Decl::Kind::kUnion: {
            auto iter = named_unions.find(decl);
            if (iter != named_unions.end()) {
                ProduceUnionDeclaration(iter->second);
            }
            break;
        }
        default:
            abort();
        }
    }

    file_ << "\n// Simple bindings \n\n";

    for (const auto* decl : library_->declaration_order_) {
        switch (decl->kind) {
        case flat::Decl::Kind::kConst:
        case flat::Decl::Kind::kEnum:
        case flat::Decl::Kind::kStruct:
        case flat::Decl::Kind::kUnion:
            // Only interfaces have client declarations.
            break;
        case flat::Decl::Kind::kInterface: {
            if (!HasSimpleLayout(decl))
                break;
            auto iter = named_interfaces.find(decl);
            if (iter != named_interfaces.end()) {
                ProduceInterfaceClientDeclaration(iter->second);
                ProduceInterfaceServerDeclaration(iter->second);
            }
            break;
        }
        default:
            abort();
        }
    }

    GenerateEpilogues();

    return std::move(file_);
}

std::ostringstream CGenerator::ProduceClient() {
    EmitFileComment(&file_);
    EmitIncludeHeader(&file_, "<lib/fidl/coding.h>");
    EmitIncludeHeader(&file_, "<string.h>");
    EmitIncludeHeader(&file_, "<zircon/syscalls.h>");
    EmitIncludeHeader(&file_, "<" + NameLibraryCHeader(library_->name()) + ">");
    EmitBlank(&file_);

    std::map<const flat::Decl*, NamedInterface> named_interfaces =
        NameInterfaces(library_->interface_declarations_);

    for (const auto* decl : library_->declaration_order_) {
        switch (decl->kind) {
        case flat::Decl::Kind::kConst:
        case flat::Decl::Kind::kEnum:
        case flat::Decl::Kind::kStruct:
        case flat::Decl::Kind::kUnion:
            // Only interfaces have client implementations.
            break;
        case flat::Decl::Kind::kInterface: {
            if (!HasSimpleLayout(decl))
                break;
            auto iter = named_interfaces.find(decl);
            if (iter != named_interfaces.end()) {
                ProduceInterfaceClientImplementation(iter->second);
            }
            break;
        }
        default:
            abort();
        }
    }

    return std::move(file_);
}

std::ostringstream CGenerator::ProduceServer() {
    EmitFileComment(&file_);
    EmitIncludeHeader(&file_, "<lib/fidl/coding.h>");
    EmitIncludeHeader(&file_, "<string.h>");
    EmitIncludeHeader(&file_, "<zircon/syscalls.h>");
    EmitIncludeHeader(&file_, "<" + NameLibraryCHeader(library_->name()) + ">");
    EmitBlank(&file_);

    std::map<const flat::Decl*, NamedInterface> named_interfaces =
        NameInterfaces(library_->interface_declarations_);

    for (const auto* decl : library_->declaration_order_) {
        switch (decl->kind) {
        case flat::Decl::Kind::kConst:
        case flat::Decl::Kind::kEnum:
        case flat::Decl::Kind::kStruct:
        case flat::Decl::Kind::kUnion:
            // Only interfaces have client implementations.
            break;
        case flat::Decl::Kind::kInterface: {
            if (!HasSimpleLayout(decl))
                break;
            auto iter = named_interfaces.find(decl);
            if (iter != named_interfaces.end()) {
                ProduceInterfaceServerImplementation(iter->second);
            }
            break;
        }
        default:
            abort();
        }
    }

    return std::move(file_);
}

} // namespace fidl
