// 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 <iostream>

#include "banjo/ddk_generator.h"

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

namespace banjo {

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[] = "    ";

// 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;
}

std::string ToSnakeCase(StringView name, bool upper = false) {
    const auto is_upper = [](char c) { return c >= 'A' && c <= 'Z'; };
    const auto is_lower = [](char c) { return c >= 'a' && c <= 'z'; };
    const auto to_upper = [&](char c) { return is_lower(c) ? c + ('A' - 'a') : c; };
    const auto to_lower = [&](char c) { return is_upper(c) ? c - ('A' - 'a') : c; };
    std::string snake;
    snake += name[0];
    for (auto it = name.begin() + 1; it != name.end(); ++it) {
        if (is_upper(*it) && *(it - 1) != '_' && !is_upper(*(it - 1))) {
            snake += '_';
        }
        snake += *it;
    }
    if (upper) {
        std::transform(snake.begin(), snake.end(), snake.begin(), to_upper);
    } else {
        std::transform(snake.begin(), snake.end(), snake.begin(), to_lower);
    }
    return snake;
}

std::string ToLispCase(StringView name) {
    std::string lisp = ToSnakeCase(name);
    const auto to_lisp = [&](char c) { return c == '_' ? '-' : c; };
    std::transform(lisp.begin(), lisp.end(), lisp.begin(), to_lisp);
    return lisp;
}

std::string NameBuffer(const DdkGenerator::Member& member) {
    return member.name + (member.element_type == "void" ? "_buffer" : "_list");
}

std::string NameCount(const DdkGenerator::Member& member) {
    return member.name + (member.element_type == "void" ? "_size" : "_count");
}

bool ReturnFirst(const std::vector<DdkGenerator::Member>& output) {
    return output.size() > 0 && (output[0].kind == flat::Type::Kind::kPrimitive ||
                                 (output[0].kind == flat::Type::Kind::kIdentifier &&
                                  output[0].decl_kind == flat::Decl::Kind::kEnum));
}

void EmitFileComment(std::ostream* file, banjo::StringView name) {
    *file << "// Copyright 2018 The Fuchsia Authors. All rights reserved.\n";
    *file << "// Use of this source code is governed by a BSD-style license that can be\n";
    *file << "// found in the LICENSE file.\n\n";
    *file << "// WARNING: THIS FILE IS MACHINE GENERATED. DO NOT EDIT.\n";
    *file << "//          MODIFY system/banjo/ddk-protocol-" << name << "/" << name
          << ".banjo INSTEAD.\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 EmitNamespacePrologue(std::ostream* file, StringView name) {
    *file << "namespace " << name << " {\n";
}

void EmitNamespaceEpilogue(std::ostream* file, StringView name) {
    *file << "} // namespace " << name << "\n";
}

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

std::vector<StringView> SplitString(const std::string& src, char delimiter) {
    std::vector<StringView> result;
    if (src.empty())
        return result;

    size_t start = 0;
    while (start != std::string::npos) {
        const size_t end = src.find(delimiter, start);

        if (end == std::string::npos) {
            StringView view(&src[start], src.size() - start);
            if (!view.empty())
                result.push_back(view);
            start = std::string::npos;
        } else {
            StringView view(&src[start], end - start);
            if (!view.empty())
                result.push_back(view);
            start = end + 1;
        }
    }
    return result;
}

template <typename T>
void EmitDocstring(std::ostream* file, const T& decl, bool indent) {
    if (!decl.doc.empty()) {
        const auto lines = SplitString(decl.doc, '\n');
        for (auto line : lines) {
            if (indent) {
                *file << kIndent;
            }
            *file << "//" << line << "\n";
        }
    }
}

void EmitMemberDecl(std::ostream* file, const DdkGenerator::Member& member, bool output = false) {
    const auto member_name = (output ? "* " : " ") + member.name;
    switch (member.kind) {
    case flat::Type::Kind::kArray:
        *file << member.type << member_name;
        for (uint32_t array_count : member.array_counts) {
            *file << "[" << array_count << "]";
        }
        break;
    case flat::Type::Kind::kVector:
        if (output) {
            *file << member.element_type << (output ? "* " : " ") << NameBuffer(member) << ";\n"
                  << kIndent << "size_t " << NameCount(member) << ";\n"
                  << kIndent << "size_t" << member_name << "_actual";
        } else {
            const auto prefix = member.nullability == types::Nullability::kNullable ? "" : "const ";
            *file << prefix << member.element_type << (output ? "** " : "* ")
                  << NameBuffer(member) << ";\n"
                  << kIndent << "size_t " << NameCount(member);
        }
        break;
    case flat::Type::Kind::kString:
        if (member.array_counts.size() > 0) {
            *file << "char " << member_name;
            for (uint32_t array_count : member.array_counts) {
                *file << "[" << array_count << "]";
            }
        } else {
            *file << member.type << member_name;
        }
        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:
        switch (member.decl_kind) {
        case flat::Decl::Kind::kConst:
            assert(false && "bad decl kind for member");
            break;
        case flat::Decl::Kind::kEnum:
            *file << member.type << member_name;
            break;
        case flat::Decl::Kind::kInterface:
            *file << member.type << (output ? "*" : "") << member_name;
            break;
        case flat::Decl::Kind::kStruct:
        case flat::Decl::Kind::kUnion:
            *file << member.type << member_name;
            break;
        }
        break;
    }
}

// If tranform is true, interface structs will be inlined as void* ctx and
// foo_ops_t* ops members.
void EmitMethodInParamDecl(std::ostream* file, const DdkGenerator::Member& member,
                           bool emit_name = true, bool transform = false) {
    const auto member_name = emit_name ? " " + member.name : "";
    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:
        if (emit_name) {
            *file << "const " << member.element_type << "* " << NameBuffer(member) << ", "
                  << "size_t " << NameCount(member);
        } else {
            *file << "const " << member.element_type << "*, size_t";
        }
        break;
    case flat::Type::Kind::kString:
    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:
        switch (member.decl_kind) {
        case flat::Decl::Kind::kConst:
            assert(false && "bad decl kind for member");
            break;
        case flat::Decl::Kind::kEnum:
            *file << member.type << member_name;
            break;
        case flat::Decl::Kind::kInterface:
            if (transform &&
                member.name.find("cb") == std::string::npos &&
                member.name.find("callback") == std::string::npos &&
                member.name.find("func") == std::string::npos) {
                const auto ctx = emit_name ? member_name + "_ctx" : "";
                const auto ops = emit_name ? member_name + "_ops" : "";
                const auto type = member.type.substr(6, member.type.size() - 8) + "_ops_t";
                *file << "void*" << ctx << ", " << type << "*" << ops;
            } else {
                *file << member.type << "*" << member_name;
            }
            break;
        case flat::Decl::Kind::kStruct:
        case flat::Decl::Kind::kUnion:
            switch (member.nullability) {
            case types::Nullability::kNullable:
                // TODO: We are using nullability as a proxy for const...
                *file << member.type << member_name;
                break;
            case types::Nullability::kNonnullable:
                *file << "const " << member.type << "*" << member_name;
                break;
            }
            break;
        }
        break;
    }
}

void EmitMethodOutParamDecl(std::ostream* file, const DdkGenerator::Member& member,
                            bool emit_name = true) {
    const auto member_name = emit_name ? " out_" + member.name : "";
    switch (member.kind) {
    case flat::Type::Kind::kArray:
        *file << member.type << member_name;
        for (uint32_t array_count : member.array_counts) {
            *file << "[" << array_count << "]";
        }
    case flat::Type::Kind::kVector: {
        const auto buffer_name = emit_name ? " out_" + NameBuffer(member) : "";
        const auto count_name = emit_name ? " " + NameCount(member) : "";
        const auto actual_name = emit_name ? member_name + "_actual" : "";
        switch (member.nullability) {
        case types::Nullability::kNullable:
            *file << member.element_type << "**" << buffer_name << ", "
                  << "size_t*" << count_name;
            break;
        case types::Nullability::kNonnullable:
            *file << member.element_type << "*" << buffer_name << ", "
                  << "size_t" << count_name << ", "
                  << "size_t*" << actual_name;
            break;
        }
        break;
    }
    case flat::Type::Kind::kString:
        if (emit_name) {
            *file << "char*" << member_name << ", "
                  << "size_t " << member.name << "_capacity";
        } else {
            *file << "char*, size_t";
        }
        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:
        switch (member.decl_kind) {
        case flat::Decl::Kind::kConst:
            assert(false && "bad decl kind for member");
            break;
        case flat::Decl::Kind::kEnum:
        case flat::Decl::Kind::kInterface:
        case flat::Decl::Kind::kStruct:
        case flat::Decl::Kind::kUnion:
            *file << member.type << "*" << member_name;
            break;
        }
        break;
    }
}

void EmitMethodDeclHelper(std::ostream* file, StringView method_name,
                          const std::vector<DdkGenerator::Member>& input,
                          const std::vector<DdkGenerator::Member>& output,
                          StringView ctx, bool transform = false) {
    const bool return_first = ReturnFirst(output);
    if (return_first) {
        *file << output[0].type << " ";
    } else {
        *file << "void ";
    }
    *file << method_name << "(";
    if (!ctx.empty()) {
        *file << ctx;
    }
    bool first = ctx.empty();
    for (const auto& member : input) {
        if (first) {
            first = false;
        } else {
            *file << ", ";
        }
        EmitMethodInParamDecl(file, member, true, transform);
    }
    for (auto member = output.begin() + (return_first ? 1 : 0); member != output.end();
         member++) {
        if (first) {
            first = false;
        } else {
            *file << ", ";
        }
        EmitMethodOutParamDecl(file, *member);
    }
}

void EmitProtocolMethodDecl(std::ostream* file, StringView method_name,
                            const std::vector<DdkGenerator::Member>& input,
                            const std::vector<DdkGenerator::Member>& output) {
    EmitMethodDeclHelper(file, method_name, input, output, "");
}

void EmitProtocolMethodDeclTransform(std::ostream* file, StringView method_name,
                                     const std::vector<DdkGenerator::Member>& input,
                                     const std::vector<DdkGenerator::Member>& output) {
    EmitMethodDeclHelper(file, method_name, input, output, "", true);
}

void EmitProtocolMethodWithCtxDecl(std::ostream* file, StringView method_name,
                                   const std::vector<DdkGenerator::Member>& input,
                                   const std::vector<DdkGenerator::Member>& output) {
    EmitMethodDeclHelper(file, method_name, input, output, "void* ctx");
}

void EmitProtocolMethodWithSpecificCtxDecl(std::ostream* file, const std::string& protocol_name,
                                           banjo::StringView method_name,
                                           const std::vector<DdkGenerator::Member>& input,
                                           const std::vector<DdkGenerator::Member>& output) {
    EmitMethodDeclHelper(file, method_name, input, output,
                         "const " + protocol_name + "_t* proto", true);
}

void EmitProtocolMethodPtrDecl(std::ostream* file, const std::string& method_name,
                               const std::vector<DdkGenerator::Member>& input,
                               const std::vector<DdkGenerator::Member>& output) {
    EmitMethodDeclHelper(file, "(*" + method_name + ")", input, output, "void* ctx");
}

void EmitProtocolMethodTemplateDecl(std::ostream* file,
                                    const std::vector<DdkGenerator::Member>& input,
                                    const std::vector<DdkGenerator::Member>& output) {
    EmitMethodDeclHelper(file, "(C::*)", input, output, "");
    *file << "));\n";
}

void EmitMethodImplHelper(std::ostream* file, StringView method_name,
                          const std::vector<DdkGenerator::Member>& input,
                          const std::vector<DdkGenerator::Member>& output,
                          StringView ctx, bool save_ret = false) {
    const bool return_first = ReturnFirst(output);
    if (return_first)
        *file << (save_ret ? "auto ret = " : "return ");
    *file << method_name << "(";

    if (!ctx.empty()) {
        *file << ctx;
    }
    bool first = ctx.empty();
    for (const auto& member : input) {
        if (first) {
            first = false;
        } else {
            *file << ", ";
        }
        if (member.kind == flat::Type::Kind::kVector) {
            *file << NameBuffer(member) << ", " << NameCount(member);
        } else {
            *file << member.name;
        }
    }
    for (auto member = output.begin() + (return_first ? 1 : 0); member != output.end();
         member++) {
        if (first) {
            first = false;
        } else {
            *file << ", ";
        }

        if (member->kind == flat::Type::Kind::kVector) {
            *file << "out_" << NameBuffer(*member) << ", " << NameCount(*member);
            if (member->nullability == types::Nullability::kNonnullable) {
                *file << ", out_" << member->name << "_actual";
            }
        } else if (member->kind == flat::Type::Kind::kString) {
            *file << "out_" << member->name << ", " << member->name << "_capacity";
        } else {
            *file << (member->address_of ? "&" : "") << "out_" << member->name;
        }
    }
}

void EmitDdkProtocolMethodImpl(std::ostream* file, const std::string& method_name,
                               const std::vector<DdkGenerator::Member>& input,
                               const std::vector<DdkGenerator::Member>& output) {
    for (auto& member : input) {
        if (member.kind == flat::Type::Kind::kIdentifier &&
            member.decl_kind == flat::Decl::Kind::kInterface &&
            member.name.find("cb") == std::string::npos &&
            member.name.find("callback") == std::string::npos &&
            member.name.find("func") == std::string::npos) {
            *file << member.type << " " << member.name << "2 = {\n";
            *file << kIndent << kIndent << kIndent << ".ops = " << member.name << "_ops,\n";
            *file << kIndent << kIndent << kIndent << ".ctx = " << member.name << "_ctx,\n";
            *file << kIndent << kIndent << "};\n";
            *file << kIndent << kIndent << member.type << "* " << member.name
                  << " = &" << member.name << "2;\n";
            *file << kIndent << kIndent;
        }
    }
    EmitMethodImplHelper(file, "proto->ops->" + method_name, input, output,
                         "proto->ctx");
    *file << ");\n";
}

void EmitDdktlProtocolMethodImpl(std::ostream* file, const std::string& method_name,
                                 std::vector<DdkGenerator::Member> input,
                                 std::vector<DdkGenerator::Member> output) {
    for (auto& member : input) {
        if (member.kind == flat::Type::Kind::kHandle) {
            member.name = member.type + "(" + member.name + ")";
        }
    }
    for (auto& member : output) {
        if (member.kind == flat::Type::Kind::kHandle) {
            *file << kIndent << kIndent << member.type << " out_" << member.name << "2;\n";
            member.name = member.name + "2";
            member.address_of = true;
        }
    }
    *file << kIndent << kIndent;
    EmitMethodImplHelper(file, "static_cast<D*>(ctx)->" + method_name, input, output, "", true);
    *file << ");\n";
    for (auto& member : output) {
        if (member.kind == flat::Type::Kind::kHandle) {
            *file << kIndent << kIndent << "*out_"
                  << member.name.substr(0, member.name.size() - 1) << " = out_"
                  << member.name << ".release();\n";
        }
    }
    if (ReturnFirst(output)) {
        *file << kIndent << kIndent << "return ret;\n";
    }
}

void EmitClientMethodImpl(std::ostream* file, const std::string& method_name,
                          std::vector<DdkGenerator::Member>& input,
                          std::vector<DdkGenerator::Member>& output) {

    for (auto& member : input) {
        if (member.kind == flat::Type::Kind::kIdentifier &&
            member.decl_kind == flat::Decl::Kind::kInterface && 
            member.name.find("cb") == std::string::npos &&
            member.name.find("callback") == std::string::npos &&
            member.name.find("func") == std::string::npos) {
            *file << member.type << " " << member.name << "2 = {\n";
            *file << kIndent << kIndent << kIndent << ".ops = " << member.name << "_ops,\n";
            *file << kIndent << kIndent << kIndent << ".ctx = " << member.name << "_ctx,\n";
            *file << kIndent << kIndent << "};\n";
            *file << kIndent << kIndent << member.type << "* " << member.name
                  << " = &" << member.name << "2;\n";
            *file << kIndent << kIndent;
        }
    }
    for (auto& member : input) {
        if (member.kind == flat::Type::Kind::kHandle) {
            member.name = member.name + ".release()";
        }
    }
    for (auto& member : output) {
        if (member.kind == flat::Type::Kind::kHandle) {
            member.name = member.name + "->reset_and_get_address()";
        }
    }
    EmitMethodImplHelper(file, "ops_->" + method_name, input, output, "ctx_");
    *file << ");\n";
}

void EmitCallbackMethodImpl(std::ostream* file, const std::string& method_name,
                            const std::vector<DdkGenerator::Member>& members) {
    *file << kIndent << "struct " << method_name << "_callback_context* ctx = cookie;\n";
    EmitBlank(file);
    for (const auto& member : members) {
        const auto& name = member.name;
        switch (member.kind) {
        case flat::Type::Kind::kArray:
            *file << kIndent << "memcpy(ctx->" << name << ", " << name << ", sizeof(" << name << "));\n";
            break;
        case flat::Type::Kind::kVector:
            *file << kIndent << "memcpy(ctx->" << NameBuffer(member) << ", " << NameBuffer(member)
                  << ", sizeof(*" << NameBuffer(member) << ") * " << NameCount(member) << ");\n";
            *file << kIndent << "*ctx->" << name << "_actual = " << NameCount(member) << ";\n";
            break;
        case flat::Type::Kind::kString:
            *file << kIndent << "strcpy(ctx->" << name << ", " << name << ");\n";
            break;
        case flat::Type::Kind::kHandle:
        case flat::Type::Kind::kRequestHandle:
        case flat::Type::Kind::kPrimitive:
            *file << kIndent << "*ctx->" << name << " = " << name << ";\n";
            break;
        case flat::Type::Kind::kIdentifier:
            switch (member.decl_kind) {
            case flat::Decl::Kind::kConst:
                assert(false && "bad decl kind for member");
                break;
            case flat::Decl::Kind::kEnum:
            case flat::Decl::Kind::kInterface:
                *file << kIndent << "*ctx->" << name << " = " << name << ";\n";
                break;
            case flat::Decl::Kind::kStruct:
            case flat::Decl::Kind::kUnion:
                switch (member.nullability) {
                case types::Nullability::kNullable:
                    *file << kIndent << "if (" << name << ") {\n";
                    *file << kIndent << kIndent << "*ctx->" << name << " = *" << name << ";\n";
                    *file << kIndent << "} else {\n";
                    // We don't have a great way of signaling that the optional response member
                    // was not in the message. That means these bindings aren't particularly
                    // useful when the client needs to extract that bit. The best we can do is
                    // zero out the value to make sure the client has defined behavior.
                    //
                    // In many cases, the response contains other information (e.g., a status code)
                    // that lets the client do something reasonable.
                    *file << kIndent << kIndent << "memset(ctx->" << name
                          << ", 0, sizeof(*ctx->" << name << "));\n";
                    *file << kIndent << "}\n";
                    break;
                case types::Nullability::kNonnullable:
                    *file << kIndent << "*ctx->" << name << " = *" << name << ";\n";
                    break;
                }
                break;
            }
            break;
        }
    }
    EmitBlank(file);
    *file << kIndent << "sync_completion_signal(&ctx->completion);\n";
}

void EmitSyncMethodImpl(std::ostream* file, const std::string& protocol_name,
                        const std::string& method_name,
                        const std::vector<DdkGenerator::Member>& input,
                        const std::vector<DdkGenerator::Member>& members) {
    *file << kIndent << "struct " << method_name << "_callback_context ctx;\n";
    *file << kIndent << "sync_completion_reset(&ctx.completion);\n";

    const bool return_first = ReturnFirst(members);
    if (return_first) {
        *file << kIndent << members[0].type << " _" << members[0].name << ";\n";
        *file << kIndent << members[0].type << "* out_" << members[0].name << " = &_"
              << members[0].name << ";\n";
    }
    EmitBlank(file);
    for (const auto& member : members) {
        const auto& name = member.name;
        switch (member.kind) {
        case flat::Type::Kind::kArray:
            *file << kIndent << "ctx." << name << " = out_" << name << "\n";
            break;
        case flat::Type::Kind::kVector:
            *file << kIndent << "ctx." << NameBuffer(member) << " = out_" << NameBuffer(member)
                  << ";\n";
            *file << kIndent << "ctx." << NameCount(member) << " = " << NameCount(member) << ";\n";
            *file << kIndent << "ctx." << name << "_actual = out_" << name << "_actual;\n";
            break;
        case flat::Type::Kind::kString:
            *file << kIndent << "ctx." << name << " = out_" << name << ";\n";
            *file << kIndent << "ctx." << name << "capacity = out_" << name << "capacity;\n";
            break;
        case flat::Type::Kind::kHandle:
        case flat::Type::Kind::kRequestHandle:
        case flat::Type::Kind::kPrimitive:
            *file << kIndent << "ctx." << name << " = out_" << name << ";\n";
            break;
        case flat::Type::Kind::kIdentifier:
            switch (member.decl_kind) {
            case flat::Decl::Kind::kConst:
                assert(false && "bad decl kind for member");
                break;
            case flat::Decl::Kind::kEnum:
            case flat::Decl::Kind::kInterface:
                *file << kIndent << "ctx." << name << " = out_" << name << ";\n";
                break;
            case flat::Decl::Kind::kStruct:
            case flat::Decl::Kind::kUnion:
                switch (member.nullability) {
                case types::Nullability::kNullable:
                    *file << kIndent << "ctx." << name << " = out_" << name << ";\n";
                    break;
                case types::Nullability::kNonnullable:
                    *file << kIndent << "ctx." << name << " = out_" << name << ";\n";
                    break;
                }
                break;
            }
            break;
        }
    }

    EmitBlank(file);
    *file << kIndent;
    EmitMethodImplHelper(file, method_name, input, {}, protocol_name);
    *file << ", " << method_name << "_cb, &ctx);\n";
    *file << kIndent
          << "zx_status_t status = sync_completion_wait(&ctx.completion, ZX_TIME_INFINITE);\n";
    if (return_first) {
        *file << kIndent << "if (status != ZX_OK) {\n";
        *file << kIndent << kIndent << "return status;\n";
        *file << kIndent << "}\n";
        *file << kIndent << "return _" << members[0].name << ";\n";
    } else {
        *file << kIndent << "assert(status == ZX_OK);\n";
    }
}

// Various computational helper routines.

void EnumValue(types::PrimitiveSubtype type, const flat::Constant* constant,
               const flat::Library* library, std::string* out_value) {
    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::kFloat32:
    case types::PrimitiveSubtype::kFloat64:
    case types::PrimitiveSubtype::kUSize:
    case types::PrimitiveSubtype::kISize:
    case types::PrimitiveSubtype::kVoidPtr:
        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;
        }
        case flat::Type::Kind::kString: {
            auto str_type = static_cast<const flat::StringType*>(type);
            uint32_t max_size = str_type->max_size.Value();
            if (max_size < flat::Size::Max().Value())
                array_counts.push_back(max_size);
            return array_counts;
        }
        }
    }
}

flat::Decl::Kind GetDeclKind(const flat::Library* library, const flat::Type* type) {
    if (type->kind != flat::Type::Kind::kIdentifier)
        return flat::Decl::Kind::kConst;
    auto identifier_type = static_cast<const flat::IdentifierType*>(type);
    auto named_decl = library->LookupDeclByName(identifier_type->name);
    assert(named_decl && "library must contain declaration");
    return named_decl->kind;
}

std::string HandleToZxWrapper(const flat::HandleType* handle_type) {
    switch (handle_type->subtype) {
    case types::HandleSubtype::kHandle:
        return "zx::handle";
    case types::HandleSubtype::kProcess:
        return "zx::process";
    case types::HandleSubtype::kThread:
        return "zx::thread";
    case types::HandleSubtype::kVmo:
        return "zx::vmo";
    case types::HandleSubtype::kChannel:
        return "zx::channel";
    case types::HandleSubtype::kEvent:
        return "zx::event";
    case types::HandleSubtype::kPort:
        return "zx::port";
    case types::HandleSubtype::kInterrupt:
        return "zx::interrupt";
    case types::HandleSubtype::kLog:
        return "zx::debuglog";
    case types::HandleSubtype::kSocket:
        return "zx::socket";
    case types::HandleSubtype::kResource:
        return "zx::resource";
    case types::HandleSubtype::kEventpair:
        return "zx::eventpair";
    case types::HandleSubtype::kJob:
        return "zx::job";
    case types::HandleSubtype::kVmar:
        return "zx::vmar";
    case types::HandleSubtype::kFifo:
        return "zx::fifo";
    case types::HandleSubtype::kGuest:
        return "zx::guest";
    case types::HandleSubtype::kTimer:
        return "zx::timer";
    case types::HandleSubtype::kBti:
        return "zx::bti";
    case types::HandleSubtype::kProfile:
        return "zx::profile";
    default: {
        abort();
    }
    }
}

std::string NameType(const flat::Type* type, const flat::Decl::Kind& decl_kind,
                     bool handle_wrappers = false) {
    for (;;) {
        switch (type->kind) {
        case flat::Type::Kind::kHandle:
        case flat::Type::Kind::kRequestHandle: {
            if (handle_wrappers) {
                auto handle_type = static_cast<const flat::HandleType*>(type);
                return HandleToZxWrapper(handle_type);
            } else {
                return "zx_handle_t";
            }
        }

        case flat::Type::Kind::kString:
            return "const char*";

        case flat::Type::Kind::kPrimitive: {
            auto primitive_type = static_cast<const flat::PrimitiveType*>(type);
            if (primitive_type->subtype == types::PrimitiveSubtype::kInt32)
                return "zx_status_t";
            return NamePrimitiveCType(primitive_type->subtype);
        }

        case flat::Type::Kind::kArray: {
            auto array_type = static_cast<const flat::ArrayType*>(type);
            type = array_type->element_type.get();
            continue;
        }

        case flat::Type::Kind::kVector: {
            auto vector_type = static_cast<const flat::VectorType*>(type);
            type = vector_type->element_type.get();
            continue;
        }

        case flat::Type::Kind::kIdentifier: {
            auto identifier_type = static_cast<const flat::IdentifierType*>(type);
            switch (decl_kind) {
            case flat::Decl::Kind::kConst:
            case flat::Decl::Kind::kEnum:
            case flat::Decl::Kind::kStruct:
            case flat::Decl::Kind::kUnion: {
                std::string name = identifier_type->name.name().data();
                name = ToSnakeCase(name) + "_t";
                if (identifier_type->nullability == types::Nullability::kNullable) {
                    name.push_back('*');
                }
                return name;
            }
            case flat::Decl::Kind::kInterface: {
                return std::string(
                    "const " + ToSnakeCase(identifier_type->name.name().data()) + "_t");
            }
            default: {
                abort();
            }
            }
        }
        default: {
            abort();
        }
        }
    }
}

template <typename T>
DdkGenerator::Member CreateMember(const flat::Library* library, const T& decl,
                                  bool handle_wrappers = false, bool transform = false) {
    std::string name = NameIdentifier(decl.name);
    const flat::Type* type = decl.type.get();
    auto decl_kind = GetDeclKind(library, type);
    auto type_name = NameType(type, decl_kind, handle_wrappers);
    std::vector<uint32_t> array_counts = ArrayCounts(library, type);
    std::string element_type_name;
    std::string doc = decl.GetAttribute("Doc");
    if (type->kind == flat::Type::Kind::kVector) {
        auto vector_type = static_cast<const flat::VectorType*>(type);
        const flat::Type* element_type = vector_type->element_type.get();
        element_type_name = NameType(element_type, GetDeclKind(library, element_type));
    }
    types::Nullability nullability = types::Nullability::kNonnullable;
    if (type->kind == flat::Type::Kind::kIdentifier) {
        auto identifier_type = static_cast<const flat::IdentifierType*>(type);
        nullability = identifier_type->nullability;
    } else if (type->kind == flat::Type::Kind::kVector) {
        auto identifier_type = static_cast<const flat::VectorType*>(type);
        nullability = identifier_type->nullability;
    }
    return DdkGenerator::Member{
        type->kind,
        decl_kind,
        std::move(type_name),
        std::move(name),
        std::move(element_type_name),
        std::move(doc),
        std::move(array_counts),
        nullability,
    };
}

template <typename T>
std::vector<DdkGenerator::Member>
GenerateMembers(const flat::Library* library, const std::vector<T>& decl_members) {
    std::vector<DdkGenerator::Member> members;
    members.reserve(decl_members.size());
    for (const auto& member : decl_members) {
        members.push_back(CreateMember(library, member, false));
    }
    return members;
}

void GetMethodParameters(const flat::Library* library,
                         const DdkGenerator::NamedMethod& method_info,
                         std::vector<DdkGenerator::Member>* input,
                         std::vector<DdkGenerator::Member>* output,
                         bool handle_wrappers = false) {
    input->reserve(method_info.input_parameters.size() + (method_info.async ? 2 : 0));
    for (const auto& parameter : method_info.input_parameters) {
        input->push_back(CreateMember(library, parameter, handle_wrappers));
    }

    if (method_info.async) {
        input->push_back(DdkGenerator::Member{
            .kind = flat::Type::Kind::kIdentifier,
            .decl_kind = flat::Decl::Kind::kStruct,
            .type = ToSnakeCase(method_info.protocol_name) + "_callback",
            .name = "callback",
            .element_type = "",
            .array_counts = {},
            .nullability = types::Nullability::kNullable,
        });
        input->push_back(DdkGenerator::Member{
            .kind = flat::Type::Kind::kPrimitive,
            .decl_kind = flat::Decl::Kind::kStruct,
            .type = "void*",
            .name = "cookie",
            .element_type = "",
            .array_counts = {},
            .nullability = types::Nullability::kNullable,
        });
    } else {
        output->reserve(method_info.output_parameters.size());
        for (const auto& parameter : method_info.output_parameters) {
            output->push_back(CreateMember(library, parameter, handle_wrappers));
        }
    }
}
} // namespace

void DdkGenerator::GeneratePrologues() {
    EmitFileComment(&file_, library_->name().back());
    EmitHeaderGuard(&file_);
    EmitBlank(&file_);

    for (const auto& dep_library : library_->dependencies()) {
        if (dep_library == library_)
            continue;
        if (dep_library->HasAttribute("Internal"))
            continue;
        EmitIncludeHeader(&file_, "<" + ToLispCase(StringJoin(dep_library->name(), "/")) + ".h>");
    }
    EmitIncludeHeader(&file_, "<zircon/compiler.h>");
    EmitIncludeHeader(&file_, "<zircon/types.h>");

    EmitBlank(&file_);
    file_ << "__BEGIN_CDECLS;\n";
}

void DdktlGenerator::GeneratePrologues() {
    EmitFileComment(&file_, library_->name().back());
    EmitHeaderGuard(&file_);
    EmitBlank(&file_);
    EmitIncludeHeader(&file_, "<ddk/driver.h>");
    EmitIncludeHeader(&file_, "<" + ToLispCase(LibraryName(library_, "/")) + ".h>");
    for (const auto& dep_library : library_->dependencies()) {
        if (dep_library == library_)
            continue;
        if (dep_library->HasAttribute("Internal"))
            continue;
        EmitIncludeHeader(&file_, "<" + ToLispCase(StringJoin(dep_library->name(), "/")) + ".h>");
    }
    EmitIncludeHeader(&file_, "<ddktl/device-internal.h>");
    EmitIncludeHeader(&file_, "<zircon/assert.h>");
    EmitIncludeHeader(&file_, "<zircon/compiler.h>");
    EmitIncludeHeader(&file_, "<zircon/types.h>");

    // Enumerate list of includes based on zx_handle_t wrappers.
    std::set<std::string> includes;

    std::map<const flat::Decl*, NamedInterface> named_interfaces =
        NameInterfaces(library_->interface_declarations_);
    for (const auto& named_interface : named_interfaces) {
        for (const auto& method_info : named_interface.second.methods) {
            std::vector<Member> input;
            std::vector<Member> output;
            GetMethodParameters(library_, method_info, &input, &output, true);

            for (const auto& member : input) {
                if (member.kind == flat::Type::Kind::kHandle) {
                    includes.insert(std::string(member.type.substr(4)));
                }
            }
            for (const auto& member : output) {
                if (member.kind == flat::Type::Kind::kHandle) {
                    includes.insert(std::string(member.type.substr(4)));
                }
            }
        }
    }

    for (const auto& include : includes) {
        EmitIncludeHeader(&file_, "<lib/zx/" + include + ".h>");
    }

    EmitBlank(&file_);

    const auto& libname = library_->name();
    EmitIncludeHeader(&file_, "\"" + ToLispCase(libname.back()) + "-internal.h\"");
    EmitBlank(&file_);
}

void DdkGenerator::GenerateEpilogues() {
    file_ << "__END_CDECLS;\n";
}

void DdktlGenerator::GenerateEpilogues() {
    EmitNamespaceEpilogue(&file_, "ddk");
}

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

void DdkGenerator::GeneratePrimitiveDefine(StringView name, types::PrimitiveSubtype subtype,
                                           StringView value) {
    switch (subtype) {
    case types::PrimitiveSubtype::kInt8:
    case types::PrimitiveSubtype::kInt16:
    case types::PrimitiveSubtype::kInt32:
    case types::PrimitiveSubtype::kInt64:
    case types::PrimitiveSubtype::kUint8:
    case types::PrimitiveSubtype::kUint16:
    case types::PrimitiveSubtype::kUint32:
    case types::PrimitiveSubtype::kUint64: {
        std::string literal_macro = NamePrimitiveIntegerCConstantMacro(subtype);
        file_ << "#define " << name << " " << literal_macro << "(" << value << ")\n";
        break;
    }
    case types::PrimitiveSubtype::kBool:
    case types::PrimitiveSubtype::kFloat32:
    case types::PrimitiveSubtype::kFloat64: {
        file_ << "#define " << name << " "
              << "(" << value << ")\n";
        break;
    }
    default:
        abort();
    }
}

void DdkGenerator::GenerateStringDefine(StringView name, StringView value) {
    file_ << "#define " << name << " " << value << "\n";
}

#if 0
void DdktlGenerator::GeneratePrimitiveDefine(StringView name, types::PrimitiveSubtype subtype,
                                             StringView value) {
    std::string underlying_type = NamePrimitiveCType(subtype);
    file_ << "constexpr " << underlying_type << " " << name << " = " << value << ";\n";
}

void DdktlGenerator::GenerateStringDefine(StringView name, StringView value) {
    file_ << "constexpr const char" << name << "[] = " << value << "\n";
}
#endif

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

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

void DdkGenerator::GenerateUnionTypedef(StringView name, StringView type_name) {
    file_ << "typedef union " << name << " " << type_name << ";\n";
}

void DdkGenerator::GenerateStructDeclaration(StringView name, const std::vector<Member>& members,
                                             bool packed, bool helper) {
    file_ << "struct " << name << " {\n";
    bool first = true;
    for (const auto& member : members) {
        if (!helper) {
            EmitDocstring(&file_, member, true);
        }
        file_ << kIndent;
        EmitMemberDecl(&file_, member, helper && !first);
        file_ << ";\n";
        if (first)
            first = false;
    }
    if (packed) {
        file_ << "} __attribute__((__packed__));\n";
    } else {
        file_ << "};\n";
    }
}

void DdkGenerator::GenerateTaggedUnionDeclaration(StringView name,
                                                  const std::vector<Member>& members) {
    file_ << "union " << name << " {\n";
    for (const auto& member : members) {
        EmitDocstring(&file_, member, true);
        file_ << kIndent;
        EmitMemberDecl(&file_, member);
        file_ << ";\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*, DdkGenerator::NamedConst>
DdkGenerator::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) {
        std::string doc = const_info->GetAttribute("Doc");
        named_consts.emplace(const_info.get(),
                             NamedConst{NameIdentifier(const_info->name.name()), std::move(doc),
                                        *const_info});
    }
    return named_consts;
}

#if 0
std::map<const flat::Decl*, DdkGenerator::NamedConst>
DdktlGenerator::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{NameIdentifier(const_info->name.name()), *const_info});
    }
    return named_consts;
}
#endif

std::map<const flat::Decl*, DdkGenerator::NamedEnum>
DdkGenerator::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 = ToSnakeCase(enum_info->name.name().data(), true);
        std::string type_name = ToSnakeCase(enum_info->name.name().data()) + "_t";
        std::string doc = enum_info->GetAttribute("Doc");
        named_enums.emplace(enum_info.get(),
                            NamedEnum{std::move(enum_name), std::move(type_name), std::move(doc),
                                      *enum_info});
    }
    return named_enums;
}

#if 0
std::map<const flat::Decl*, DdkGenerator::NamedEnum>
DdktlGenerator::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 = enum_info->name.name().data();
        named_enums.emplace(enum_info.get(), NamedEnum{enum_name, enum_name, *enum_info});
    }
    return named_enums;
}
#endif

std::map<const flat::Decl*, DdkGenerator::NamedInterface>
DdkGenerator::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) {
        const auto layout = interface_info->GetAttribute("Layout");
        InterfaceType intf_type;
        std::string name = interface_info->name.name().data();
        if (layout == "ddk-protocol") {
            name += "Protocol";
            intf_type = InterfaceType::kProtocol;
        } else if (layout == "ddk-interface") {
            intf_type = InterfaceType::kInterface;
        } else if (layout == "ddk-callback") {
            intf_type = InterfaceType::kCallback;
        } else {
            continue;
        }

        NamedInterface named_interface;
        named_interface.type = intf_type;
        named_interface.shortname = interface_info->name.name().data();
        named_interface.camel_case_name = name;
        named_interface.snake_case_name = ToSnakeCase(std::move(name));
        named_interface.doc = interface_info->GetAttribute("Doc");
        for (const auto& method_pointer : interface_info->all_methods) {
            assert(method_pointer != nullptr);
            const auto& method = *method_pointer;
            std::string c_name = ToSnakeCase(method.name.data());
            NamedMethod named_method = {
                .async = method.HasAttribute("Async"),
                .generate_sync_method = method.HasAttribute("GenerateSync"),
                .c_name = c_name,
                .protocol_name = ToSnakeCase(named_interface.shortname) + "_" + c_name,
                .proxy_name = "",
                .doc = method.GetAttribute("Doc"),
                .input_parameters = method.maybe_request->parameters,
                .output_parameters = 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*, DdkGenerator::NamedInterface>
DdktlGenerator::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) {
        const auto layout = interface_info->GetAttribute("Layout");
        InterfaceType intf_type;
        std::string name = interface_info->name.name().data();
        if (layout == "ddk-protocol") {
            name += "Protocol";
            intf_type = InterfaceType::kProtocol;
        } else if (layout == "ddk-interface") {
            intf_type = InterfaceType::kInterface;
        } else if (layout == "ddk-callback") {
            intf_type = InterfaceType::kCallback;
        } else {
            continue;
        }

        NamedInterface named_interface;
        named_interface.type = intf_type;
        named_interface.shortname = interface_info->name.name().data();
        named_interface.camel_case_name = name;
        named_interface.snake_case_name = ToSnakeCase(std::move(name));
        named_interface.doc = interface_info->GetAttribute("Doc");
        for (const auto& method_pointer : interface_info->all_methods) {
            assert(method_pointer != nullptr);
            const auto& method = *method_pointer;
            std::string protocol_name = NameIdentifier(interface_info->name.name()) +
                                        NameIdentifier(method.name);
            std::string c_name = ToSnakeCase(method.name.data());
            std::string proxy_name = NameIdentifier(method.name);
            NamedMethod named_method = {
                .async = method.HasAttribute("Async"),
                .generate_sync_method = method.HasAttribute("GenerateSync"),
                .c_name = c_name,
                .protocol_name = protocol_name,
                .proxy_name = proxy_name,
                .doc = method.GetAttribute("Doc"),
                .input_parameters = method.maybe_request->parameters,
                .output_parameters = 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*, DdkGenerator::NamedStruct>
DdkGenerator::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) {
        const bool packed = struct_info->HasAttribute("Packed");
        std::string name = ToSnakeCase(struct_info->name.name().data());
        std::string type_name = name + "_t";
        std::string doc = struct_info->GetAttribute("Doc");
        named_structs.emplace(struct_info.get(),
                              NamedStruct{std::move(name), std::move(type_name), std::move(doc),
                                          packed, *struct_info});
    }
    return named_structs;
}

#if 0
std::map<const flat::Decl*, DdkGenerator::NamedStruct>
DdktlGenerator::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) {
        const bool packed = struct_info->HasAttribute("Packed");
        if (struct_info->GetAttribute("repr") == "C") {
            std::string name = ToSnakeCase(struct_info->name.name().data());
            std::string type_name = name + "_t";
            named_structs.emplace(struct_info.get(),
                                  NamedStruct{std::move(name), std::move(type_name), packed,
                                              *struct_info});
        } else {
            const std::string name = struct_info->name.name().data();
            named_structs.emplace(struct_info.get(), NamedStruct{name, name, packed, *struct_info});
        }
    }
    return named_structs;
}
#endif

std::map<const flat::Decl*, DdkGenerator::NamedUnion>
DdkGenerator::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 = ToSnakeCase(union_info->name.name().data());
        std::string type_name = union_name + "_t";
        std::string doc = union_info->GetAttribute("Doc");
        named_unions.emplace(union_info.get(),
                             NamedUnion{std::move(union_name), std::move(type_name), std::move(doc),
                                        *union_info});
    }
    return named_unions;
}

#if 0
std::map<const flat::Decl*, DdkGenerator::NamedUnion>
DdktlGenerator::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) {
        if (union_info->GetAttribute("repr") == "C") {
            std::string union_name = ToSnakeCase(union_info->name.name().data());
            std::string type_name = union_name + "_t";
            named_unions.emplace(union_info.get(),
                                 NamedUnion{std::move(union_name), std::move(type_name),
                                            *union_info});
        } else {
            const std::string union_name = union_info->name.name().data();
            named_unions.emplace(union_info.get(),
                                 NamedUnion{union_name, union_name, *union_info});
        }
    }
    return named_unions;
}
#endif

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

void DdkGenerator::ProduceProtocolForwardDeclaration(const NamedInterface& named_interface) {
    GenerateStructTypedef(named_interface.snake_case_name, named_interface.snake_case_name + "_t");

    for (const auto& method_info : named_interface.methods) {
        if (method_info.async) {
            std::vector<Member> input;
            input.reserve(method_info.output_parameters.size());
            for (const auto& parameter : method_info.output_parameters) {
                input.push_back(CreateMember(library_, parameter));
            }

            file_ << "typedef ";
            const auto method_name = method_info.protocol_name + "_callback";
            EmitProtocolMethodPtrDecl(&file_, method_name, input, {});
            file_ << ");\n";
        }
    }
}

#if 0
void DdktlGenerator::ProduceProtocolForwardDeclaration(const NamedInterface& named_interface) {}
#endif

void DdkGenerator::ProduceEnumForwardDeclaration(const NamedEnum& named_enum) {
    types::PrimitiveSubtype subtype = named_enum.enum_info.type;
    EmitDocstring(&file_, named_enum, false);
    GenerateIntegerTypedef(subtype, named_enum.type_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);
        struct {
            std::string doc;
        } temp = {member.GetAttribute("Doc")};
        EmitDocstring(&file_, temp, true);
        GenerateIntegerDefine(member_name, subtype, std::move(member_value));
    }

    EmitBlank(&file_);
}

#if 0
void DdktlGenerator::ProduceEnumForwardDeclaration(const NamedEnum& named_enum) {
    types::PrimitiveSubtype subtype = named_enum.enum_info.type;
    std::string underlying_type = NamePrimitiveCType(subtype);
    file_ << "enum class " << named_enum.name << " : " << underlying_type << " {\n";
    for (const auto& member : named_enum.enum_info.members) {
        std::string member_name = NameIdentifier(member.name);
        std::string member_value;
        EnumValue(named_enum.enum_info.type, member.value.get(), library_, &member_value);
        file_ << kIndent << member_name << " = " << member_value << ",\n";
    }
    file_ << "};\n";
}
#endif

void DdkGenerator::ProduceStructForwardDeclaration(const NamedStruct& named_struct) {
    // TODO: Hack - structs with no members are defined in a different header.
    if (named_struct.struct_info.members.empty())
        return;

    GenerateStructTypedef(named_struct.name, named_struct.type_name);
}

void DdkGenerator::ProduceUnionForwardDeclaration(const NamedUnion& named_union) {
    GenerateUnionTypedef(named_union.name, named_union.type_name);
}

void DdkGenerator::ProduceConstDeclaration(const NamedConst& named_const) {
    const flat::Const& ci = named_const.const_info;

    // Some constants are not literals.  Odd.
    if (ci.value->kind != flat::Constant::Kind::kLiteral) {
        return;
    }

    EmitDocstring(&file_, named_const, false);
    switch (ci.type->kind) {
    case flat::Type::Kind::kPrimitive:
        GeneratePrimitiveDefine(
            named_const.name,
            static_cast<flat::PrimitiveType*>(ci.type.get())->subtype,
            static_cast<flat::LiteralConstant*>(ci.value.get())->literal->location().data());
        break;
    case flat::Type::Kind::kString:
        GenerateStringDefine(
            named_const.name,
            static_cast<flat::LiteralConstant*>(ci.value.get())->literal->location().data());
        break;
    default:
        abort();
    }
    EmitBlank(&file_);
}

void DdkGenerator::ProduceProtocolImplementation(const NamedInterface& named_interface) {
    const auto& proto_name = named_interface.snake_case_name;

    if (named_interface.type == InterfaceType::kCallback) {
        assert(named_interface.methods.size() == 1 && "callback should only have 1 function");

        file_ << "struct " << proto_name << " {\n";
        const auto& method_info = named_interface.methods[0];
        std::vector<Member> input;
        std::vector<Member> output;
        GetMethodParameters(library_, method_info, &input, &output, false);

        file_ << kIndent;
        EmitProtocolMethodPtrDecl(&file_, method_info.c_name, input, output);
        file_ << ");\n";
        file_ << kIndent << "void* ctx;\n";
        file_ << "};\n";
        EmitBlank(&file_);
        return;
    }

    file_ << "typedef struct " << proto_name << "_ops {\n";
    for (const auto& method_info : named_interface.methods) {
        std::vector<Member> input;
        std::vector<Member> output;
        GetMethodParameters(library_, method_info, &input, &output, false);

        file_ << kIndent;
        EmitProtocolMethodPtrDecl(&file_, method_info.c_name, input, output);
        file_ << ");\n";
    }
    file_ << "} " << proto_name << "_ops_t;\n";
    EmitBlank(&file_);

    // Emit Protocol.
    EmitDocstring(&file_, named_interface, false);
    file_ << "struct " << proto_name << " {\n";
    file_ << kIndent << proto_name << "_ops_t* ops;\n";
    file_ << kIndent << "void* ctx;\n";
    file_ << "};\n";
    EmitBlank(&file_);

    // Emit Protocol helper functions.
    for (const auto& method_info : named_interface.methods) {
        std::vector<Member> input;
        std::vector<Member> output;
        GetMethodParameters(library_, method_info, &input, &output, false);

        EmitDocstring(&file_, method_info, false);
        file_ << "static inline ";
        EmitProtocolMethodWithSpecificCtxDecl(
            &file_, proto_name, method_info.protocol_name, input, output);
        file_ << ") {\n"
              << kIndent;
        EmitDdkProtocolMethodImpl(&file_, method_info.c_name, input, output);
        file_ << "}\n";
    }
    EmitBlank(&file_);

    // Emit Protocol async helper functions.
    for (const auto& method_info : named_interface.methods) {
        if (!method_info.async || !method_info.generate_sync_method)
            continue;
        // Generate context struct.
        std::vector<DdkGenerator::Member> members;
        members.reserve(method_info.output_parameters.size() + 1);
        members.push_back(DdkGenerator::Member{
            .kind = flat::Type::Kind::kIdentifier,
            .decl_kind = flat::Decl::Kind::kStruct,
            .type = "sync_completion_t",
            .name = "completion",
            .element_type = "",
            .array_counts = {},
            .nullability = types::Nullability::kNonnullable,
        });
        for (const auto& member : method_info.output_parameters) {
            members.push_back(CreateMember(library_, member, false));
        }
        GenerateStructDeclaration(method_info.protocol_name + "_callback_context", members, false,
                                  true);
        EmitBlank(&file_);

        // Generate callback function.
        members.erase(members.begin());
        file_ << "static ";
        EmitMethodDeclHelper(&file_, method_info.protocol_name + "_cb", members, {},
                             "void* cookie");
        file_ << ") {\n";
        EmitCallbackMethodImpl(&file_, method_info.protocol_name, members);
        file_ << "}\n";
        EmitBlank(&file_);

        // Generated sync version of helper function.
        auto method_info2 = method_info;
        method_info2.async = false;
        std::vector<Member> input;
        std::vector<Member> output;
        GetMethodParameters(library_, method_info2, &input, &output, false);

        file_ << "static inline ";
        EmitProtocolMethodWithSpecificCtxDecl(
            &file_, proto_name, method_info.protocol_name + "_sync", input,
            output);
        file_ << ") {\n";

        input.clear();
        output.clear();
        GetMethodParameters(library_, method_info, &input, &output, false);
        EmitSyncMethodImpl(&file_, proto_name, method_info.protocol_name, input, members);
        file_ << "}\n";
    }
}

void DdktlGenerator::ProduceExample(const NamedInterface& named_interface) {
    if (named_interface.type == InterfaceType::kCallback ||
        named_interface.type == InterfaceType::kInterface)
        return;

    const auto& shortname = named_interface.shortname;
    const auto& sc_name = named_interface.snake_case_name;
    const auto& cc_name = named_interface.camel_case_name;
    const auto lc_name = ToLispCase(sc_name);

    file_ << "// DDK " << ToLispCase(sc_name) << " support\n";
    file_ << "//\n";
    file_ << "// :: Proxies ::\n";
    file_ << "//\n";
    file_ << "// ddk::" << cc_name << "Client is a simple wrapper around\n";
    file_ << "// " << sc_name << "_t. It does not own the pointers passed to it\n";
    file_ << "//\n";
    file_ << "// :: Mixins ::\n";
    file_ << "//\n";
    file_ << "// ddk::" << cc_name << " is a mixin class that simplifies writing DDK "
          << "drivers\n";
    file_ << "// that implement the " << ToLispCase(shortname)
          << " protocol. It doesn't set the base protocol.\n";
    file_ << "//\n";
    file_ << "// :: Examples ::\n";
    file_ << "//\n";
    file_ << "// // A driver that implements a ZX_PROTOCOL_" << ToSnakeCase(shortname, true)
          << " device.\n";
    file_ << "// class " << shortname << "Device;\n";
    file_ << "// using " << shortname << "DeviceType = ddk::Device<" << shortname
          << "Device, /* ddk mixins */>;\n";
    file_ << "//\n";
    file_ << "// class " << shortname << "Device : public " << shortname << "DeviceType,\n";
    file_ << "// " << std::string(shortname.size() + 15, ' ') << "public ddk::" << cc_name << "<"
          << shortname << "Device> {\n";
    file_ << "//   public:\n";
    file_ << "// " << kIndent << shortname << "Device(zx_device_t* parent)\n";
    file_ << "// " << kIndent << kIndent << ": " << shortname << "DeviceType(parent) {}\n";
    file_ << "//\n";
    for (const auto& method_info : named_interface.methods) {
        std::vector<Member> input;
        std::vector<Member> output;
        GetMethodParameters(library_, method_info, &input, &output, true);

        file_ << "// " << kIndent;
        EmitProtocolMethodDecl(&file_, method_info.protocol_name, input, output);
        file_ << ");\n";
        file_ << "//\n";
    }
    file_ << "// " << kIndent << "...\n";
    file_ << "// };\n";
    EmitBlank(&file_);
}

void DdktlGenerator::ProduceProtocolImplementation(const NamedInterface& named_interface) {
    if (named_interface.type == InterfaceType::kCallback)
        return;

    const auto& sc_name = named_interface.snake_case_name;
    const auto& cc_name = named_interface.camel_case_name;

    const auto& ops = sc_name + "_ops_";

    EmitDocstring(&file_, named_interface, false);
    file_ << "template <typename D, typename Base = internal::base_mixin>\n";
    file_ << "class " << cc_name << " : public Base {\n";
    file_ << "public:\n";
    file_ << kIndent << cc_name << "() {\n";
    file_ << kIndent << kIndent << "internal::Check" << cc_name << "Subclass<D>();\n";
    for (const auto& method_info : named_interface.methods) {
        file_ << kIndent << kIndent << ops << "." << method_info.c_name
              << " = " << method_info.protocol_name << ";\n";
    }
    if (named_interface.type != InterfaceType::kInterface) {
        EmitBlank(&file_);
        file_ << kIndent << kIndent << "if constexpr (internal::is_base_proto<Base>::value) {\n";
        file_ << kIndent << kIndent << kIndent << "auto dev = static_cast<D*>(this);\n";
        file_ << kIndent << kIndent << kIndent
              << "// Can only inherit from one base_protocol implementation.\n";
        file_ << kIndent << kIndent << kIndent << "ZX_ASSERT(dev->ddk_proto_id_ == 0);\n";
        file_ << kIndent << kIndent << kIndent << "dev->ddk_proto_id_ = ZX_PROTOCOL_"
              << ToSnakeCase(named_interface.shortname, true) << ";\n";
        file_ << kIndent << kIndent << kIndent << "dev->ddk_proto_ops_ = &" << ops << ";\n";
        file_ << kIndent << kIndent << "}\n";
    }
    file_ << kIndent << "}\n";
    EmitBlank(&file_);
    file_ << "protected:\n";
    file_ << kIndent << sc_name << "_ops_t " << ops << " = {};\n";
    EmitBlank(&file_);
    file_ << "private:\n";
    for (const auto& method_info : named_interface.methods) {
        std::vector<Member> input;
        std::vector<Member> output;
        GetMethodParameters(library_, method_info, &input, &output, false);

        EmitDocstring(&file_, method_info, true);
        file_ << kIndent << "static ";
        EmitProtocolMethodWithCtxDecl(&file_, method_info.protocol_name, input, output);
        file_ << ") {\n";
        std::vector<Member> input2;
        std::vector<Member> output2;
        GetMethodParameters(library_, method_info, &input2, &output2, true);
        EmitDdktlProtocolMethodImpl(&file_, method_info.protocol_name, input2, output2);
        file_ << kIndent << "}\n";
    }
    file_ << "};\n";
    EmitBlank(&file_);

    ProduceClientImplementation(named_interface);
}

void DdktlGenerator::ProduceClientImplementation(const NamedInterface& named_interface) {
    if (named_interface.type == InterfaceType::kCallback)
        return;

    const auto& sc_name = named_interface.snake_case_name;
    const auto& cc_name = named_interface.camel_case_name;

    const auto type = sc_name + "_t";
    const auto proto_id = "ZX_PROTOCOL_" + ToSnakeCase(named_interface.shortname, true);

    file_ << "class " << cc_name << "Client {\n";
    file_ << "public:\n";
    file_ << kIndent << cc_name << "Client()\n";
    file_ << kIndent << kIndent << ": ops_(nullptr), ctx_(nullptr) {}\n";
    file_ << kIndent << cc_name << "Client(const " << type << "* proto)\n";
    file_ << kIndent << kIndent << ": ops_(proto->ops), ctx_(proto->ctx) {}\n";
    if (named_interface.type != InterfaceType::kInterface) {
        EmitBlank(&file_);
        file_ << kIndent << cc_name << "Client(zx_device_t* parent) {\n";
        file_ << kIndent << kIndent << type << " proto;\n";
        file_ << kIndent << kIndent << "if (device_get_protocol(parent, " << proto_id
              << ", &proto) == ZX_OK) {\n";
        file_ << kIndent << kIndent << kIndent << "ops_ = proto.ops;\n";
        file_ << kIndent << kIndent << kIndent << "ctx_ = proto.ctx;\n";
        file_ << kIndent << kIndent << "} else {\n";
        file_ << kIndent << kIndent << kIndent << "ops_ = nullptr;\n";
        file_ << kIndent << kIndent << kIndent << "ctx_ = nullptr;\n";
        file_ << kIndent << kIndent << "}\n";
        file_ << kIndent << "}\n";
    }
    EmitBlank(&file_);
    file_ << kIndent << "void GetProto(" << type << "* proto) const {\n";
    file_ << kIndent << kIndent << "proto->ctx = ctx_;\n";
    file_ << kIndent << kIndent << "proto->ops = ops_;\n";
    file_ << kIndent << "}\n";
    file_ << kIndent << "bool is_valid() const {\n";
    file_ << kIndent << kIndent << "return ops_ != nullptr;\n";
    file_ << kIndent << "}\n";
    file_ << kIndent << "void clear() {\n";
    file_ << kIndent << kIndent << "ctx_ = nullptr;\n";
    file_ << kIndent << kIndent << "ops_ = nullptr;\n";
    file_ << kIndent << "}\n";
    for (const auto& method_info : named_interface.methods) {
        std::vector<Member> input;
        std::vector<Member> output;
        GetMethodParameters(library_, method_info, &input, &output, true);

        EmitDocstring(&file_, method_info, true);
        file_ << kIndent;
        EmitProtocolMethodDeclTransform(&file_, method_info.proxy_name, input, output);
        file_ << ") const {\n"
              << kIndent << kIndent;
        EmitClientMethodImpl(&file_, method_info.c_name, input, output);
        file_ << kIndent << "}\n";
    }
    EmitBlank(&file_);
    file_ << "private:\n";
    file_ << kIndent << sc_name << "_ops_t* ops_;\n";
    file_ << kIndent << "void* ctx_;\n";
    file_ << "};\n";
    EmitBlank(&file_);
}

void DdktlGenerator::ProduceProtocolSubclass(const NamedInterface& named_interface) {
    if (named_interface.type == InterfaceType::kCallback)
        return;

    const auto& sc_name = named_interface.snake_case_name;
    const auto& cc_name = named_interface.camel_case_name;

    for (const auto& method_info : named_interface.methods) {
        std::vector<Member> input;
        std::vector<Member> output;
        GetMethodParameters(library_, method_info, &input, &output, true);

        file_ << "DECLARE_HAS_MEMBER_FN_WITH_SIGNATURE(has_" << sc_name << "_" << method_info.c_name
              << ", " << method_info.protocol_name << ",\n";
        file_ << kIndent << kIndent;
        EmitProtocolMethodTemplateDecl(&file_, input, output);
    }
    EmitBlank(&file_);

    file_ << "template <typename D>\n";
    file_ << "constexpr void Check" << cc_name << "Subclass() {\n";
    for (const auto& method_info : named_interface.methods) {
        std::vector<Member> input;
        std::vector<Member> output;
        GetMethodParameters(library_, method_info, &input, &output, true);

        file_ << kIndent << "static_assert(internal::has_" << sc_name << "_" << method_info.c_name
              << "<D>::value,\n";
        file_ << kIndent << kIndent << "\"" << cc_name << " subclasses must implement \"\n";
        file_ << kIndent << kIndent << "\"";
        EmitProtocolMethodDecl(&file_, method_info.protocol_name, input, output);
        file_ << ");\");\n";
    }
    file_ << "}\n";
    EmitBlank(&file_);
}

void DdkGenerator::ProduceStructDeclaration(const NamedStruct& named_struct) {
    // TODO: Hack - structs with no members are defined in a different header.
    if (named_struct.struct_info.members.empty())
        return;

    std::vector<DdkGenerator::Member> members =
        GenerateMembers(library_, named_struct.struct_info.members);
    EmitDocstring(&file_, named_struct, false);
    GenerateStructDeclaration(named_struct.name, members, named_struct.packed);

    EmitBlank(&file_);
}

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

    EmitBlank(&file_);
}

std::ostringstream DdkGenerator::ProduceHeader() {
    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_);

    GeneratePrologues();

    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()) {
                ProduceProtocolForwardDeclaration(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// 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()) {
                ProduceProtocolImplementation(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();
        }
    }

    GenerateEpilogues();

    return std::move(file_);
}

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

    GeneratePrologues();
    for (const auto& iter : named_interfaces) {
        ProduceExample(iter.second);
    }

    EmitNamespacePrologue(&file_, "ddk");
    EmitBlank(&file_);

    for (const auto* decl : library_->declaration_order_) {
        switch (decl->kind) {
        case flat::Decl::Kind::kInterface: {
            auto iter = named_interfaces.find(decl);
            if (iter != named_interfaces.end()) {
                ProduceProtocolImplementation(iter->second);
            }
            break;
        }
        default:
            continue;
        }
    }

    GenerateEpilogues();

    return std::move(file_);
}

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

    EmitFileComment(&file_, library_->name().back());
    EmitHeaderGuard(&file_);
    EmitBlank(&file_);
    EmitIncludeHeader(&file_, "<" + ToLispCase(StringJoin(library_->name(), "/")) + ".h>");
    EmitIncludeHeader(&file_, "<type_traits>");
    EmitBlank(&file_);
    EmitNamespacePrologue(&file_, "ddk");
    EmitNamespacePrologue(&file_, "internal");
    EmitBlank(&file_);

    for (const auto* decl : library_->declaration_order_) {
        switch (decl->kind) {
        case flat::Decl::Kind::kInterface: {
            auto iter = named_interfaces.find(decl);
            if (iter != named_interfaces.end()) {
                ProduceProtocolSubclass(iter->second);
            }
            break;
        }
        default:
            break;
        }
    }

    EmitNamespaceEpilogue(&file_, "internal");
    EmitNamespaceEpilogue(&file_, "ddk");

    return std::move(file_);
}
} // namespace banjo
