// 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 <zircon/assert.h>

#include <unordered_set>

#include "fidl/flat_ast.h"
#include "fidl/names.h"
#include "fidl/type_shape.h"

namespace fidl {

namespace {

// RAII helper class to reset the iostream to its original flags.
class IOFlagsGuard {
 public:
  explicit IOFlagsGuard(std::ostream* stream) : stream_(stream), flags_(stream_->flags()) {}

  ~IOFlagsGuard() { stream_->setf(flags_); }

 private:
  std::ostream* stream_;
  std::ios::fmtflags flags_;
};

// 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 = "    ";

// Mapping of library name to set of declaration names.
// These declarations are treated as though they have the
// [ForDeprecatedCBindings] attribute even though they violate the constraints
// enforced on them.
//
// For protocols this means that some of the methods can't be supported and
// will simply be left out (unless they're listed below in allowed_methods).
//
// For structs this means that a member can have an unsupported type such as a
// vector of strings or a union.
const std::map<std::string, std::set<std::string>> allowed_decls({
    {"fuchsia.tracing.provider", {"Provider", "ProviderConfig", "StartOptions"}},
    {"fuchsia.logger", {"Log", "LogSink", "LogMessage", "LogListenerSafe", "LogFilterOptions"}},
    {"fuchsia.hardware.power.statecontrol", {"Admin"}},
    {"fidl.test.llcpp.dirent", {"DirEntTestInterface"}},
});

bool DeclAlwaysAllowed(const flat::Name& name) {
  auto library_name = flat::LibraryName(name.library()->name, ".");

  auto iter = allowed_decls.find(library_name);
  if (iter != allowed_decls.end()) {
    const auto& decls = iter->second;
    if (decls.find(std::string(name.decl_name())) != decls.end()) {
      return true;
    }
  }
  return false;
}

// Mapping of library name to mapping of protocol name to set of methods.
// Data structures should be generated for these methods even if they violate
// the constraints of the simple C bindings.
std::map<std::string, std::map<std::string, std::set<std::string>>> allowed_methods({
    {"fuchsia.device.manager", {{"DeviceController", {"CompleteRemoval", "Unbind"}}}},
    {"fuchsia.hardware.power.statecontrol",
     {{"Admin", {"Poweroff", "Reboot", "RebootToBootloader", "RebootToRecovery", "SuspendToRam"}}}},
});

bool MethodAlwaysAllowed(const flat::Protocol::Method& method) {
  auto library_name = flat::LibraryName(method.owning_protocol->name.library()->name, ".");
  auto iter = allowed_methods.find(library_name);
  if (iter != allowed_methods.end()) {
    const auto& protocols = iter->second;
    auto protocol = protocols.find(std::string(method.owning_protocol->name.decl_name()));
    if (protocol != protocols.end()) {
      const auto& methods = protocol->second;
      if (methods.find(std::string(method.name.data())) != methods.end()) {
        return true;
      }
    }
  }
  return false;
}

bool DeclAllowed(const flat::Decl* decl) {
  if (HasSimpleLayout(decl) || DeclAlwaysAllowed(decl->name)) {
    return true;
  }

  switch (decl->kind) {
    case flat::Decl::Kind::kBits:
    case flat::Decl::Kind::kConst:
    case flat::Decl::Kind::kEnum:
      // bits, const, enum are always allowed.
      return true;
    default:
      return false;
  }
}

bool TypeAllowed(const flat::Type* type) {
  ZX_ASSERT(type != nullptr);
  // treat box types like we do nullable structs
  if (type->kind == flat::Type::Kind::kBox)
    type = static_cast<const flat::BoxType*>(type)->boxed_type;
  if (type->kind == flat::Type::Kind::kIdentifier) {
    auto identifier_type = static_cast<const flat::IdentifierType*>(type);
    if (!DeclAllowed(identifier_type->type_decl)) {
      return false;
    }
  }
  return true;
}

bool PayloadLayoutAllowed(const std::unique_ptr<flat::TypeConstructor>& payload) {
  if (!payload) {
    return true;
  }

  auto id = static_cast<const flat::IdentifierType*>(payload->type);

  // Since no new uses of the C bindings are allowed, fail on payloads that are either unions or
  // tables, as support for such payloads was added after C binding usage was frozen.
  if (id->type_decl->kind != flat::Decl::Kind::kStruct) {
    return false;
  }

  auto as_struct = static_cast<const flat::Struct*>(id->type_decl);
  for (const auto& member : as_struct->members) {
    if (!TypeAllowed(member.type_ctor->type)) {
      return false;
    }
  }
  return true;
}

bool MethodAllowed(const flat::Protocol::Method& method) {
  return MethodAlwaysAllowed(method) || (PayloadLayoutAllowed(method.maybe_request) &&
                                         PayloadLayoutAllowed(method.maybe_response));
}

CGenerator::Member MessageHeader() {
  return {
      flat::Type::Kind::kIdentifier,
      flat::Decl::Kind::kStruct,
      "fidl_message_header_t",
      "hdr",
      {},
      {},
      types::Nullability::kNonnullable,
      {},
  };
}

CGenerator::Member EmptyStructMember() {
  return {
      .kind = flat::Type::Kind::kPrimitive,
      .type = NamePrimitiveCType(types::PrimitiveSubtype::kUint8),

      // Prepend the reserved uint8_t field with a single underscore, which is
      // for reserved identifiers (see ISO C standard, section 7.1.3
      // <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>).
      .name = "_reserved",
  };
}

// Can encode and decode functions be generated for these members?
bool CanGenerateCodecFunctions(const std::vector<CGenerator::Member>& members) {
  for (const auto& m : members) {
    if (m.kind == flat::Type::Kind::kIdentifier &&
        m.decl_kind.value() == flat::Decl::Kind::kUnion) {
      return false;
    }
  }
  return true;
}

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

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

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

void EmitAllowlistCheck(std::ostream* file) {
  *file << "#if !defined(FIDL_ALLOW_DEPRECATED_C_BINDINGS)\n";
  *file << "#error This target is not allowed to include the deprecated C bindings header. \\\n";
  *file << " Please consider migrating to the C++ bindings.\n";
  *file << "#endif\n";
}

void EmitIncludeHeader(std::ostream* file, std::string_view 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::kBox:
      ZX_PANIC("no box types should appear at this point");
    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::kTransportSide:
    case flat::Type::Kind::kPrimitive:
      *file << member.type << " " << member.name;
      break;
    case flat::Type::Kind::kIdentifier:
      switch (member.decl_kind.value()) {
        case flat::Decl::Kind::kBuiltin:
        case flat::Decl::Kind::kConst:
        case flat::Decl::Kind::kResource:
        case flat::Decl::Kind::kService:
        case flat::Decl::Kind::kTypeAlias:
          ZX_PANIC("bad decl kind for member");
        case flat::Decl::Kind::kNewType:
          ZX_PANIC("c-codegen for new-types not implemented");
        case flat::Decl::Kind::kBits:
        case flat::Decl::Kind::kEnum:
        case flat::Decl::Kind::kProtocol:
          *file << member.type << " " << member.name;
          break;
        case flat::Decl::Kind::kStruct:
        case flat::Decl::Kind::kTable:
        case flat::Decl::Kind::kUnion:
          switch (member.nullability) {
            case types::Nullability::kNullable:
              *file << "const " << member.type << " " << member.name;
              break;
            case types::Nullability::kNonnullable:
              *file << "const " << member.type << "* " << member.name;
              break;
          }
          break;
      }
      break;
    case flat::Type::Kind::kUntypedNumeric:
      ZX_PANIC("should not have untyped numeric here");
  }
}

void EmitMethodOutParamDecl(std::ostream* file, const CGenerator::Member& member) {
  switch (member.kind) {
    case flat::Type::Kind::kBox:
      ZX_PANIC("no box types should appear at this point");
    case flat::Type::Kind::kArray:
      *file << member.type << " out_" << member.name;
      for (uint32_t array_count : member.array_counts) {
        *file << "[" << array_count << "]";
      }
      break;
    case flat::Type::Kind::kVector:
      *file << member.element_type << "* " << member.name << "_buffer, "
            << "size_t " << member.name << "_capacity, "
            << "size_t* out_" << member.name << "_count";
      break;
    case flat::Type::Kind::kString:
      *file << "char* " << member.name << "_buffer, "
            << "size_t " << member.name << "_capacity, "
            << "size_t* out_" << member.name << "_size";
      break;
    case flat::Type::Kind::kHandle:
    case flat::Type::Kind::kTransportSide:
    case flat::Type::Kind::kPrimitive:
      *file << member.type << "* out_" << member.name;
      break;
    case flat::Type::Kind::kIdentifier:
      switch (member.decl_kind.value()) {
        case flat::Decl::Kind::kBuiltin:
        case flat::Decl::Kind::kConst:
        case flat::Decl::Kind::kResource:
        case flat::Decl::Kind::kService:
        case flat::Decl::Kind::kTypeAlias:
          ZX_PANIC("bad decl kind for member");
        case flat::Decl::Kind::kNewType:
          ZX_PANIC("c-codegen for new-types not implemented");
        case flat::Decl::Kind::kBits:
        case flat::Decl::Kind::kEnum:
        case flat::Decl::Kind::kProtocol:
          *file << member.type << "* out_" << member.name;
          break;
        case flat::Decl::Kind::kStruct:
        case flat::Decl::Kind::kTable:
        case flat::Decl::Kind::kUnion:
          switch (member.nullability) {
            case types::Nullability::kNullable:
              *file << member.type << " out_" << member.name;
              break;
            case types::Nullability::kNonnullable:
              *file << member.type << "* out_" << member.name;
              break;
          }
          break;
      }
      break;
    case flat::Type::Kind::kUntypedNumeric:
      ZX_PANIC("should not have untyped numeric here");
  }
}

void EmitClientMethodDecl(std::ostream* file, std::string_view 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 (const auto& member : response) {
    *file << ", ";
    EmitMethodOutParamDecl(file, member);
  }
  *file << ")";
}

void EmitServerMethodDecl(std::ostream* file, std::string_view 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, std::string_view protocol_name) {
  *file << "zx_status_t " << protocol_name
        << "_dispatch(void* ctx, fidl_txn_t* txn, fidl_incoming_msg_t* msg, const " << protocol_name
        << "_ops_t* ops)";
}

void EmitServerTryDispatchDecl(std::ostream* file, std::string_view protocol_name) {
  *file << "zx_status_t " << protocol_name
        << "_try_dispatch(void* ctx, fidl_txn_t* txn, fidl_incoming_msg_t* msg, const "
        << protocol_name << "_ops_t* ops)";
}

void EmitServerReplyDecl(std::ostream* file, std::string_view 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 << ")";
}

bool IsStoredOutOfLine(const CGenerator::Member& member) {
  if (member.kind == flat::Type::Kind::kVector || member.kind == flat::Type::Kind::kString)
    return true;
  if (member.kind == flat::Type::Kind::kIdentifier) {
    if (member.decl_kind.value() == flat::Decl::Kind::kTable) {
      return true;
    }
    if (member.nullability == types::Nullability::kNullable) {
      return member.decl_kind.value() == flat::Decl::Kind::kStruct ||
             member.decl_kind.value() == flat::Decl::Kind::kUnion;
    }
  }
  return false;
}

void EmitMeasureInParams(std::ostream* file, const std::vector<CGenerator::Member>& params) {
  for (const auto& member : params) {
    if (member.kind == flat::Type::Kind::kVector) {
      *file << " + FIDL_ALIGN(sizeof(*" << member.name << "_data) * " << member.name << "_count)";
    } else if (member.kind == flat::Type::Kind::kString) {
      *file << " + FIDL_ALIGN(" << member.name << "_size)";
    } else if (IsStoredOutOfLine(member)) {
      *file << " + (" << member.name << " ? FIDL_ALIGN(sizeof(*" << member.name << ")) : 0u)";
    }
  }
}

void EmitParameterSizeValidation(std::ostream* file,
                                 const std::vector<CGenerator::Member>& params) {
  for (const auto& member : params) {
    if (member.max_num_elements == std::numeric_limits<uint32_t>::max())
      continue;
    std::string param_name;
    if (member.kind == flat::Type::Kind::kVector) {
      param_name = member.name + "_count";
    } else if (member.kind == flat::Type::Kind::kString) {
      param_name = member.name + "_size";
    } else {
      ZX_PANIC("only vector/string has size limit");
    }
    *file << kIndent << "if (" << param_name << " > " << member.max_num_elements << ") {\n";
    *file << kIndent << kIndent << "return ZX_ERR_INVALID_ARGS;\n";
    *file << kIndent << "}\n";
  }
}

void EmitMeasureOutParams(std::ostream* file, const std::vector<CGenerator::Member>& params) {
  for (const auto& member : params) {
    if (member.kind == flat::Type::Kind::kVector) {
      *file << " + FIDL_ALIGN(sizeof(*" << member.name << "_buffer) * " << member.name
            << "_capacity)";
    } else if (member.kind == flat::Type::Kind::kString) {
      *file << " + FIDL_ALIGN(" << member.name << "_capacity)";
    } else if (IsStoredOutOfLine(member)) {
      *file << " + (out_" << member.name << " ? FIDL_ALIGN(sizeof(*out_" << member.name
            << ")) : 0u)";
    }
  }
}

void EmitArraySizeOf(std::ostream* file, const CGenerator::Member& member) {
  for (const auto c : member.array_counts) {
    *file << c;
    *file << " * ";
  }
  *file << "sizeof(" << member.element_type << ")";
}

void EmitMagicNumberCheck(std::ostream* file) {
  *file << kIndent << "status = fidl_validate_txn_header(hdr);\n";
  *file << kIndent << "if (status != ZX_OK) {\n";
  *file << kIndent << kIndent << "FidlHandleCloseMany(msg->handles, msg->num_handles);\n";
  *file << kIndent << kIndent << "ZX_DEBUG_ASSERT(status == ZX_ERR_PROTOCOL_NOT_SUPPORTED);";
  *file << kIndent << kIndent << "return status;\n";
  *file << kIndent << "}\n";
}

// This function assumes the |params| are part of a [ForDeprecatedCBindings] protocol.
// In particular, simple protocols 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 (IsStoredOutOfLine(member))
      ++count;
  }
  return count;
}

void EmitTxnHeader(std::ostream* file, std::string_view msg_name, std::string_view ordinal_name) {
  *file << kIndent << "fidl_init_txn_header(&" << msg_name << "->hdr, 0, " << ordinal_name
        << ", FIDL_MESSAGE_HEADER_DYNAMIC_FLAGS_STRICT_METHOD);\n";
}

void EmitLinearizeMessage(std::ostream* file, std::string_view receiver, std::string_view 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::kBox:
        ZX_PANIC("no box types should appear at this point");
      case flat::Type::Kind::kArray:
        *file << kIndent << "memcpy(" << receiver << "->" << name << ", " << name << ", ";
        EmitArraySizeOf(file, member);
        *file << ");\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 << "_next += FIDL_ALIGN(" << name << "_size);\n";
        *file << kIndent << "if (" << name << "_data) {\n";
        *file << kIndent << kIndent << "memcpy(" << receiver << "->" << name << ".data, " << name
              << "_data, " << name << "_size);\n";
        *file << kIndent << "} else {\n";
        *file << kIndent << kIndent << "if (" << name << "_size != 0) {\n";
        *file << kIndent << kIndent << kIndent << "return ZX_ERR_INVALID_ARGS;\n";
        *file << kIndent << kIndent << "}\n";
        if (member.nullability == types::Nullability::kNullable) {
          *file << kIndent << kIndent << receiver << "->" << name << ".data = NULL;\n";
        }
        *file << kIndent << "}\n";
        break;
      case flat::Type::Kind::kHandle:
      case flat::Type::Kind::kTransportSide:
      case flat::Type::Kind::kPrimitive:
        *file << kIndent << receiver << "->" << name << " = " << name << ";\n";
        break;
      case flat::Type::Kind::kIdentifier:
        switch (member.decl_kind.value()) {
          case flat::Decl::Kind::kBuiltin:
          case flat::Decl::Kind::kConst:
          case flat::Decl::Kind::kResource:
          case flat::Decl::Kind::kService:
          case flat::Decl::Kind::kTypeAlias:
            ZX_PANIC("bad decl kind for member");
          case flat::Decl::Kind::kNewType:
            ZX_PANIC("c-codegen for new-types not implemented");
          case flat::Decl::Kind::kBits:
          case flat::Decl::Kind::kEnum:
          case flat::Decl::Kind::kProtocol:
            *file << kIndent << receiver << "->" << name << " = " << name << ";\n";
            break;
          case flat::Decl::Kind::kTable:
            ZX_PANIC("c-codegen for tables not implemented");
          case flat::Decl::Kind::kUnion:
            ZX_PANIC("c-codegen for unions not implemented");
          case flat::Decl::Kind::kStruct:
            switch (member.nullability) {
              case types::Nullability::kNullable:
                *file << kIndent << "if (" << name << ") {\n";
                *file << kIndent << kIndent << receiver << "->" << name << " = (void*)&" << bytes
                      << "[_next];\n";
                *file << kIndent << kIndent << "memcpy(" << receiver << "->" << name << ", " << name
                      << ", sizeof(*" << name << "));\n";
                *file << kIndent << kIndent << "_next += sizeof(*" << name << ");\n";
                *file << kIndent << "} else {\n";
                *file << kIndent << kIndent << receiver << "->" << name << " = NULL;\n";
                *file << kIndent << "}\n";
                break;
              case types::Nullability::kNonnullable:
                *file << kIndent << receiver << "->" << name << " = *" << name << ";\n";
                break;
            }
            break;
        }
        break;
      case flat::Type::Kind::kUntypedNumeric:
        ZX_PANIC("should not have untyped numeric here");
    }
  }
}

// Various computational helper routines.

void BitsValue(const flat::Constant* constant, std::string* out_value) {
  std::ostringstream member_value;

  const flat::ConstantValue& const_val = constant->Value();
  switch (const_val.kind) {
    case flat::ConstantValue::Kind::kUint8: {
      auto& value = static_cast<const flat::NumericConstantValue<uint8_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kUint16: {
      auto& value = static_cast<const flat::NumericConstantValue<uint16_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kUint32: {
      auto& value = static_cast<const flat::NumericConstantValue<uint32_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kUint64: {
      auto& value = static_cast<const flat::NumericConstantValue<uint64_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kInt8:
    case flat::ConstantValue::Kind::kInt16:
    case flat::ConstantValue::Kind::kInt32:
    case flat::ConstantValue::Kind::kInt64:
    case flat::ConstantValue::Kind::kBool:
    case flat::ConstantValue::Kind::kFloat32:
    case flat::ConstantValue::Kind::kFloat64:
    case flat::ConstantValue::Kind::kDocComment:
    case flat::ConstantValue::Kind::kString:
      ZX_PANIC("bad primitive type for a bits declaration");
  }

  *out_value = member_value.str();
}

void EnumValue(const flat::Constant* constant, std::string* out_value) {
  std::ostringstream member_value;

  const flat::ConstantValue& const_val = constant->Value();
  switch (const_val.kind) {
    case flat::ConstantValue::Kind::kInt8: {
      auto& value = static_cast<const flat::NumericConstantValue<int8_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kInt16: {
      auto& value = static_cast<const flat::NumericConstantValue<int16_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kInt32: {
      auto& value = static_cast<const flat::NumericConstantValue<int32_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kInt64: {
      auto& value = static_cast<const flat::NumericConstantValue<int64_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kUint8: {
      auto& value = static_cast<const flat::NumericConstantValue<uint8_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kUint16: {
      auto& value = static_cast<const flat::NumericConstantValue<uint16_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kUint32: {
      auto& value = static_cast<const flat::NumericConstantValue<uint32_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kUint64: {
      auto& value = static_cast<const flat::NumericConstantValue<uint64_t>&>(const_val);
      member_value << value;
      break;
    }
    case flat::ConstantValue::Kind::kBool:
    case flat::ConstantValue::Kind::kFloat32:
    case flat::ConstantValue::Kind::kFloat64:
    case flat::ConstantValue::Kind::kDocComment:
    case flat::ConstantValue::Kind::kString:
      ZX_PANIC("bad primitive type for an enum");
  }

  *out_value = member_value.str();
}

void ArrayCountsAndElementTypeName(const flat::Type* type, std::vector<uint32_t>* out_array_counts,
                                   std::string* out_element_type_name) {
  std::vector<uint32_t> array_counts;
  for (;;) {
    switch (type->kind) {
      default: {
        *out_element_type_name = NameFlatCType(type);
        *out_array_counts = array_counts;
        return;
      }
      case flat::Type::Kind::kArray: {
        auto array_type = static_cast<const flat::ArrayType*>(type);
        array_counts.push_back(array_type->element_count->value);
        type = array_type->element_type;
        continue;
      }
    }
  }
}

template <typename T>
CGenerator::Member CreateMember(const T& decl, bool* out_allowed = nullptr) {
  std::string name = NameIdentifier(decl.name);
  const flat::Type* type = decl.type_ctor->type;
  // treat box types like we do nullable structs
  if (type->kind == flat::Type::Kind::kBox)
    type = static_cast<const flat::BoxType*>(type)->boxed_type;
  auto type_name = NameFlatCType(type);
  std::string element_type_name;
  std::vector<uint32_t> array_counts;
  types::Nullability nullability = types::Nullability::kNonnullable;
  uint32_t max_num_elements = std::numeric_limits<uint32_t>::max();
  if (out_allowed) {
    *out_allowed = true;
  }
  std::optional<flat::Decl::Kind> decl_kind;
  switch (type->kind) {
    case flat::Type::Kind::kBox:
      ZX_PANIC("no box types should appear at this point");
    case flat::Type::Kind::kArray: {
      ArrayCountsAndElementTypeName(type, &array_counts, &element_type_name);
      break;
    }
    case flat::Type::Kind::kVector: {
      auto vector_type = static_cast<const flat::VectorType*>(type);
      const auto element_type = vector_type->element_type;
      element_type_name = NameFlatCType(element_type);
      max_num_elements = vector_type->element_count->value;
      break;
    }
    case flat::Type::Kind::kIdentifier: {
      auto identifier_type = static_cast<const flat::IdentifierType*>(type);
      nullability = identifier_type->nullability;
      if (out_allowed) {
        *out_allowed = DeclAllowed(identifier_type->type_decl);
      }
      decl_kind = identifier_type->type_decl->kind;
      break;
    }
    case flat::Type::Kind::kString: {
      auto string_type = static_cast<const flat::StringType*>(type);
      nullability = string_type->nullability;
      max_num_elements = string_type->max_size->value;
      break;
    }
    case flat::Type::Kind::kHandle:
    case flat::Type::Kind::kTransportSide:
    case flat::Type::Kind::kPrimitive:
      break;
    case flat::Type::Kind::kUntypedNumeric:
      ZX_PANIC("should not have untyped numeric here");
  }
  return CGenerator::Member{
      type->kind,
      decl_kind,
      std::move(type_name),
      std::move(name),
      std::move(element_type_name),
      std::move(array_counts),
      nullability,
      max_num_elements,
  };
}

bool GetMethodParameters(const CGenerator::NamedMethod& method_info,
                         std::vector<CGenerator::Member>* request,
                         std::vector<CGenerator::Member>* response) {
  if (request && method_info.request->parameters) {
    request->reserve(method_info.request->parameters->size());
    for (const auto& parameter : *method_info.request->parameters) {
      bool allowed = true;
      request->push_back(CreateMember(parameter, &allowed));
      if (!allowed) {
        request->clear();
        if (response) {
          response->clear();
        }
        return false;
      }
    }
  }

  if (response && method_info.response && method_info.response->parameters) {
    response->reserve(method_info.response->parameters->size());
    for (const auto& parameter : *method_info.response->parameters) {
      bool allowed = true;
      response->push_back(CreateMember(parameter, &allowed));
      if (!allowed) {
        if (request) {
          request->clear();
        }
        response->clear();
        return false;
      }
    }
  }
  return true;
}

}  // namespace

uint32_t CGenerator::GetMaxHandlesFor(Transport transport, const TypeShape& typeshape) {
  switch (transport) {
    case Transport::Channel:
      return std::min(kChannelMaxMessageHandles, typeshape.max_handles);
  }
}

void CGenerator::GeneratePrologues() {
  EmitFileComment(&file_);
  EmitHeaderGuard(&file_);
  EmitBlank(&file_);
  EmitAllowlistCheck(&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>");
  // Dependencies are in pointer order... change to a deterministic
  // ordering prior to output.
  std::set<std::string> add_includes;
  for (const auto& dep : compilation_->direct_and_composed_dependencies) {
    add_includes.insert(NameLibraryCHeader(dep.library->name));
  }
  for (const auto& include : add_includes) {
    EmitIncludeHeader(&file_, "<" + include + ">");
  }
  EmitBlank(&file_);
  EmitBeginExternC(&file_);
  EmitBlank(&file_);
}

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

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

void CGenerator::GeneratePrimitiveDefine(std::string_view name, types::PrimitiveSubtype subtype,
                                         std::string_view 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;
    }
  }  // switch
}

void CGenerator::GenerateStringDefine(std::string_view name, std::string_view value) {
  file_ << "#define " << name << " " << value << "\n";
}

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

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

void CGenerator::GenerateStructDeclaration(std::string_view name,
                                           const std::vector<Member>& members, StructKind kind) {
  file_ << "struct " << name << " {\n";

  if (kind == StructKind::kMessage) {
    file_ << kIndent << "FIDL_ALIGNDECL\n";
  }

  auto emit_member = [this](const Member& member) {
    file_ << kIndent;
    EmitMemberDecl(&file_, member);
    file_ << ";\n";
  };

  for (const auto& member : members) {
    emit_member(member);
  }

  if (members.empty()) {
    emit_member(EmptyStructMember());
  }

  file_ << "};\n";
}

void CGenerator::GenerateTableDeclaration(std::string_view name) {
  file_ << "struct " << name << " {\n";
  file_ << kIndent << "fidl_table_t table_header;\n";
  file_ << "};\n";
}

void CGenerator::GenerateTaggedUnionDeclaration(std::string_view name,
                                                const std::vector<Member>& members) {
#ifdef FIDLC_DEPRECATE_C_UNIONS
  file_ << "struct __attribute__ ((deprecated)) " << name << " {\n";
#else
  file_ << "struct " << name << " {\n";
#endif
  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";
}

std::map<const flat::Decl*, CGenerator::NamedBits> CGenerator::NameBits(
    const std::vector<const flat::Bits*>& bits_infos) {
  std::map<const flat::Decl*, NamedBits> named_bits;
  for (const auto& bits_info : bits_infos) {
    std::string bits_name = NameCodedName(bits_info->name);
    named_bits.emplace(bits_info, NamedBits{std::move(bits_name), *bits_info});
  }
  return named_bits;
}

// TODO(fxbug.dev/27764) 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<const flat::Const*>& const_infos) {
  std::map<const flat::Decl*, NamedConst> named_consts;
  for (const auto& const_info : const_infos) {
    named_consts.emplace(const_info, NamedConst{NameCodedName(const_info->name), *const_info});
  }
  return named_consts;
}

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

std::map<const flat::Decl*, CGenerator::NamedProtocol> CGenerator::NameProtocols(
    const std::vector<const flat::Protocol*>& protocol_infos) {
  std::map<const flat::Decl*, NamedProtocol> named_protocols;
  for (const auto& protocol_info : protocol_infos) {
    NamedProtocol named_protocol;
    named_protocol.c_name = NameCodedName(protocol_info->name);
    if (protocol_info->attributes->Get("discoverable") != nullptr) {
      named_protocol.discoverable_name = NameDiscoverable(*protocol_info);
    }
    named_protocol.transport = CGenerator::Transport::Channel;
    for (const auto& method_with_info : protocol_info->all_methods) {
      ZX_ASSERT(method_with_info.method != nullptr);
      const auto& method = *method_with_info.method;
      if (!MethodAllowed(method)) {
        continue;
      }
      NamedMethod named_method;
      std::string method_name = NameMethod(named_protocol.c_name, method);
      named_method.ordinal = static_cast<uint64_t>(method.generated_ordinal64->value);
      named_method.ordinal_name = NameOrdinal(method_name);
      named_method.identifier = NameIdentifier(method.name);
      named_method.c_name = method_name;
      if (method.has_request) {
        std::string c_name = NameMessage(method_name, types::MessageKind::kRequest);
        std::string coded_name = NameTable(c_name);
        TypeShape typeshape = TypeShape::ForEmptyPayload();
        const std::vector<flat::Struct::Member>* members = nullptr;
        if (method.maybe_request) {
          auto id = static_cast<const flat::IdentifierType*>(method.maybe_request->type);

          // Since no new uses of the C bindings are allowed, assert that payloads that are either
          // unions or tables, as support for such payloads was added after C binding usage was
          // frozen. The previous call to `MethodAllowed` should have exited early, so this assert
          // should never be hit.
          ZX_ASSERT_MSG(id->type_decl->kind == flat::Decl::Kind::kStruct,
                        "table/union method payloads disallowed");
          auto as_struct = static_cast<const flat::Struct*>(id->type_decl);
          typeshape = as_struct->typeshape(WireFormat::kV1NoEe);
          members = &as_struct->members;
        }

        ZX_ASSERT(members == nullptr || !members->empty());
        named_method.request = std::make_unique<NamedMessage>(
            NamedMessage{std::move(c_name), std::move(coded_name), members, typeshape});
      }
      if (method.has_response) {
        auto message_kind =
            method.has_request ? types::MessageKind::kResponse : types::MessageKind::kEvent;
        std::string c_name = NameMessage(method_name, message_kind);
        std::string coded_name = NameTable(c_name);
        TypeShape typeshape = TypeShape::ForEmptyPayload();
        const std::vector<flat::Struct::Member>* members = nullptr;
        if (method.maybe_response) {
          auto id = static_cast<const flat::IdentifierType*>(method.maybe_response->type);

          // Since no new uses of the C bindings are allowed, assert that payloads that are either
          // unions or tables, as support for such payloads was added after C binding usage was
          // frozen. The previous call to `MethodAllowed` should have exited early, so this assert
          // should never be hit.
          ZX_ASSERT_MSG(id->type_decl->kind == flat::Decl::Kind::kStruct,
                        "table/union method payloads disallowed");
          auto as_struct = static_cast<const flat::Struct*>(id->type_decl);
          typeshape = as_struct->typeshape(WireFormat::kV1NoEe);
          members = &as_struct->members;
        }

        ZX_ASSERT(members == nullptr || !members->empty());
        named_method.response = std::make_unique<NamedMessage>(
            NamedMessage{std::move(c_name), std::move(coded_name), members, typeshape});
      }
      named_protocol.methods.push_back(std::move(named_method));
    }
    if (!named_protocol.methods.empty()) {
      named_protocols.emplace(protocol_info, std::move(named_protocol));
    }
  }
  return named_protocols;
}

std::map<const flat::Decl*, CGenerator::NamedStruct> CGenerator::NameStructs(
    const std::vector<const flat::Struct*>& struct_infos,
    const std::vector<const flat::Protocol*>& protocol_infos) {
  std::set<const flat::Name> message_body_type_names;
  for (const auto& protocol_info : protocol_infos) {
    for (const auto& method_info : protocol_info->all_methods) {
      if (method_info.method->maybe_request != nullptr) {
        message_body_type_names.insert(method_info.method->maybe_request->layout.resolved().name());
      }
      if (method_info.method->maybe_response != nullptr) {
        message_body_type_names.insert(
            method_info.method->maybe_response->layout.resolved().name());
      }
    }
  }

  std::map<const flat::Decl*, NamedStruct> named_structs;
  for (const auto& struct_info : struct_infos) {
    // If this struct is only ever used as an anonymous transactional message body definition, there
    // is no need to name it.
    if (struct_info->name.as_anonymous() != nullptr &&
        message_body_type_names.find(struct_info->name) != message_body_type_names.end()) {
      continue;
    }
    std::string c_name = NameCodedName(struct_info->name);
    std::string coded_name = c_name + "Coded";
    named_structs.emplace(struct_info,
                          NamedStruct{std::move(c_name), std::move(coded_name), *struct_info});
  }
  return named_structs;
}

void CGenerator::ProduceBitsForwardDeclaration(const NamedBits& named_bits) {
  auto subtype =
      static_cast<const flat::PrimitiveType*>(named_bits.bits_info.subtype_ctor->type)->subtype;
  GenerateIntegerTypedef(subtype, named_bits.name);
  for (const auto& member : named_bits.bits_info.members) {
    std::string member_name = named_bits.name + "_" + NameIdentifier(member.name);
    std::string member_value;
    BitsValue(member.value.get(), &member_value);
    GenerateIntegerDefine(member_name, subtype, std::move(member_value));
  }

  EmitBlank(&file_);
}

void CGenerator::ProduceConstForwardDeclaration(const NamedConst& named_const) {
  // TODO(fxbug.dev/27764)
}

void CGenerator::ProduceEnumForwardDeclaration(const NamedEnum& named_enum) {
  types::PrimitiveSubtype subtype = named_enum.enum_info.type->subtype;
  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(member.value.get(), &member_value);
    GenerateIntegerDefine(member_name, subtype, std::move(member_value));
  }
  if (named_enum.enum_info.strictness == types::Strictness::kFlexible) {
    // We emit the unknown member with two underscores to avoid any possibility
    // of name clashes should the enum contain a member named 'unknown'.
    std::string member_name = named_enum.name + "__UNKNOWN";
    std::string member_value;
    if (named_enum.enum_info.unknown_value_signed) {
      member_value = std::to_string(named_enum.enum_info.unknown_value_signed.value());
    } else {
      member_value = std::to_string(named_enum.enum_info.unknown_value_unsigned.value());
    }
    GenerateIntegerDefine(member_name, subtype, member_value);
  }
  EmitBlank(&file_);
}

void CGenerator::ProduceProtocolForwardDeclaration(const NamedProtocol& named_protocol) {
  if (!named_protocol.discoverable_name.empty()) {
    file_ << "#define " << named_protocol.c_name << "_Name \"" << named_protocol.discoverable_name
          << "\"\n";
  }
  for (const auto& method_info : named_protocol.methods) {
    {
      IOFlagsGuard reset_flags(&file_);
      file_ << "#define " << method_info.ordinal_name << " ((uint64_t)0x" << std::uppercase
            << std::hex << method_info.ordinal << std::dec << ")\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::ProduceProtocolExternDeclaration(const NamedProtocol& named_protocol) {
  for (const auto& method_info : named_protocol.methods) {
    if (method_info.request) {
      file_ << "__LOCAL extern const fidl_type_t " << method_info.request->coded_name << ";\n";
    }
    if (method_info.response) {
      file_ << "__LOCAL extern const fidl_type_t " << method_info.response->coded_name << ";\n";
    }
  }
}

void CGenerator::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;
  }

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

  EmitBlank(&file_);
}

void CGenerator::ProduceMessageDeclaration(const NamedMessage& named_message) {
  // When we generate a request or response struct (i.e. messages), we must
  // both include the message header, and ensure the message is FIDL aligned.

  std::vector<CGenerator::Member> members;
  if (named_message.parameters) {
    members.reserve(1 + named_message.parameters->size());
    members.push_back(MessageHeader());
    for (const auto& parameter : *named_message.parameters) {
      members.push_back(CreateMember(parameter));
    }
  } else {
    members.reserve(1);
    members.push_back(MessageHeader());
  }

  GenerateStructDeclaration(named_message.c_name, members, StructKind::kMessage);

  EmitBlank(&file_);
}

void CGenerator::ProduceProtocolDeclaration(const NamedProtocol& named_protocol) {
  for (const auto& method_info : named_protocol.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(struct_member));
  }

  GenerateStructDeclaration(named_struct.c_name, members, StructKind::kNonmessage);

  EmitBlank(&file_);
}

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

  EmitBlank(&file_);
}

void CGenerator::ProduceProtocolClientImplementation(const NamedProtocol& named_protocol) {
  for (const auto& method_info : named_protocol.methods) {
    if (!method_info.request)
      continue;
    std::vector<Member> request;
    std::vector<Member> response;
    if (!GetMethodParameters(method_info, &request, &response) ||
        !CanGenerateCodecFunctions(request) || !CanGenerateCodecFunctions(response)) {
      continue;
    }

    size_t count = CountSecondaryObjects(request);
    size_t request_hcount =
        GetMaxHandlesFor(named_protocol.transport, method_info.request->typeshape);
    size_t response_hcount = 0;
    if (method_info.response) {
      response_hcount = GetMaxHandlesFor(named_protocol.transport, method_info.response->typeshape);
    }

    bool has_padding = method_info.request->typeshape.has_padding;
    bool encode_request = !request.empty() && ((count > 0) || (request_hcount > 0) || has_padding);

    EmitClientMethodDecl(&file_, method_info.c_name, request, response);
    file_ << " {\n";
    EmitParameterSizeValidation(&file_, request);
    file_ << kIndent << "uint32_t _wr_num_bytes = sizeof(" << method_info.request->c_name << ")";
    EmitMeasureInParams(&file_, request);
    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";
    EmitTxnHeader(&file_, "_request", method_info.ordinal_name);
    EmitLinearizeMessage(&file_, "_request", "_wr_bytes", request);
    const char* handle_infos_value = "NULL";
    const char* handle_dispositions_value = "NULL";
    if (request_hcount > 0) {
      file_ << kIndent << "zx_handle_disposition_t _handle_dispositions[" << request_hcount
            << "];\n";
      handle_dispositions_value = "_handle_dispositions";
    }
    if (response_hcount > 0) {
      file_ << kIndent << "zx_handle_info_t _handle_infos[" << response_hcount << "];\n";
      handle_infos_value = "_handle_infos";
    }
    if (encode_request) {
      file_ << kIndent << "uint32_t _wr_num_handles = 0u;\n";

      file_ << kIndent << "if (unlikely(_wr_num_bytes < sizeof(fidl_message_header_t))) {\n";
      file_ << kIndent << kIndent << "return ZX_ERR_INVALID_ARGS;\n";
      file_ << kIndent << "}\n";
      file_ << kIndent
            << "uint32_t _trimmed_wr_num_bytes = _wr_num_bytes - "
               "(uint32_t)(sizeof(fidl_message_header_t));\n";
      file_ << kIndent << "if (unlikely(_wr_bytes == NULL)) {\n";
      file_ << kIndent << kIndent << "return ZX_ERR_INVALID_ARGS;\n";
      file_ << kIndent << "}\n";
      file_ << kIndent
            << "uint8_t* _trimmed_wr_bytes = (uint8_t*)_wr_bytes + "
               "sizeof(fidl_message_header_t);\n";

      file_ << kIndent << "zx_status_t _encode_status = fidl_encode_etc(&"
            << method_info.request->coded_name << ", _trimmed_wr_bytes, _trimmed_wr_num_bytes, "
            << handle_dispositions_value << ", " << request_hcount
            << ", &_wr_num_handles, NULL);\n";

      file_ << kIndent << "if (_encode_status != ZX_OK)\n";
      file_ << kIndent << kIndent << "return _encode_status;\n";
    } else {
      file_ << kIndent << "// OPTIMIZED AWAY fidl_encode() of POD-only request\n";
    }
    if (!method_info.response) {
      switch (named_protocol.transport) {
        case Transport::Channel:
          if (encode_request) {
            file_ << kIndent
                  << "return zx_channel_write_etc(_channel, 0u, _wr_bytes, _wr_num_bytes, "
                  << handle_dispositions_value << ", _wr_num_handles);\n";
          } else {
            file_ << kIndent
                  << "return zx_channel_write_etc(_channel, 0u, _wr_bytes, _wr_num_bytes, NULL, "
                     "0);\n";
          }
          break;
      }
    } else {
      file_ << kIndent << "zx_status_t _status;\n";
      file_ << kIndent << "uint32_t _rd_num_bytes = sizeof(" << method_info.response->c_name << ")";
      EmitMeasureOutParams(&file_, response);
      file_ << ";\n";

      file_ << kIndent << "uint32_t _rd_num_bytes_max = _rd_num_bytes;\n";

      file_ << kIndent << "FIDL_ALIGNDECL uint8_t _rd_bytes_storage[_rd_num_bytes_max];\n";
      file_ << kIndent << "uint8_t* _rd_bytes = _rd_bytes_storage;\n";
      if (!response.empty()) {
        file_ << kIndent << method_info.response->c_name << "* _response = ("
              << method_info.response->c_name << "*)_rd_bytes;\n";
      }
      switch (named_protocol.transport) {
        case Transport::Channel:
          file_ << kIndent << "zx_channel_call_etc_args_t _args = {\n";
          file_ << kIndent << kIndent << ".wr_bytes = _wr_bytes,\n";
          file_ << kIndent << kIndent << ".wr_handles = " << handle_dispositions_value << ",\n";
          file_ << kIndent << kIndent << ".rd_bytes = _rd_bytes,\n";
          file_ << kIndent << kIndent << ".rd_handles = " << handle_infos_value << ",\n";
          file_ << kIndent << kIndent << ".wr_num_bytes = _wr_num_bytes,\n";
          if (encode_request) {
            file_ << kIndent << kIndent << ".wr_num_handles = _wr_num_handles,\n";
          } else {
            file_ << kIndent << kIndent << ".wr_num_handles = 0,\n";
          }
          file_ << kIndent << kIndent << ".rd_num_bytes = _rd_num_bytes_max,\n";
          file_ << kIndent << kIndent << ".rd_num_handles = " << response_hcount << ",\n";
          file_ << kIndent << "};\n";

          file_ << kIndent << "uint32_t _actual_num_bytes = 0u;\n";
          file_ << kIndent << "uint32_t _actual_num_handles = 0u;\n";
          file_ << "_status = zx_channel_call_etc(_channel, 0u, ZX_TIME_INFINITE, &_args, "
                   "&_actual_num_bytes, &_actual_num_handles);\n";
          break;
      }
      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.
      count = CountSecondaryObjects(response);
      has_padding = method_info.response->typeshape.has_padding;
      bool decode_response =
          !response.empty() && ((count > 0) || (response_hcount > 0) || has_padding);
      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)";
          } else if (IsStoredOutOfLine(member)) {
            if (i++ > 0u)
              file_ << " || ";
            file_ << "((uintptr_t)_response->" << member.name << " == FIDL_ALLOC_PRESENT && out_"
                  << member.name << " == NULL)";
          }
        }
        if (count > 1u)
          file_ << ")";
        file_ << " {\n";
        if (response_hcount > 0) {
          file_ << kIndent << kIndent
                << "FidlHandleInfoCloseMany(_handle_infos, _actual_num_handles);\n";
        }
        file_ << kIndent << kIndent << "return ZX_ERR_BUFFER_TOO_SMALL;\n";
        file_ << kIndent << "}\n";
      }

      if (decode_response) {
        // TODO(fxbug.dev/7499): Validate the response ordinal. C++ bindings also need to do that.
        switch (named_protocol.transport) {
          case Transport::Channel:
            file_ << kIndent
                  << "if (unlikely(_actual_num_bytes < sizeof(fidl_message_header_t))) {\n";
            file_ << kIndent << kIndent << "return ZX_ERR_INVALID_ARGS;\n";
            file_ << kIndent << "}\n";
            file_ << kIndent
                  << "uint32_t _trimmed_rd_num_bytes = _actual_num_bytes - "
                     "(uint32_t)(sizeof(fidl_message_header_t));\n";
            file_ << kIndent << "if (unlikely(_rd_bytes == NULL)) {\n";
            file_ << kIndent << kIndent << "return ZX_ERR_INVALID_ARGS;\n";
            file_ << kIndent << "}\n";
            file_ << kIndent
                  << "uint8_t* _trimmed_rd_bytes = (uint8_t*)_rd_bytes + "
                     "sizeof(fidl_message_header_t);\n";

            file_ << kIndent << "zx_status_t _decode_status = fidl_decode_etc(&"
                  << method_info.response->coded_name
                  << ", _trimmed_rd_bytes, _trimmed_rd_num_bytes, " << handle_infos_value
                  << ", _actual_num_handles, NULL);\n";
            break;
        }
        file_ << kIndent << "if (_decode_status != ZX_OK)\n";
        file_ << kIndent << kIndent << "return _decode_status;\n";
      } else {
        file_ << kIndent << "// OPTIMIZED AWAY fidl_decode() of POD-only response\n";
      }

      for (const auto& member : response) {
        const auto& name = member.name;
        switch (member.kind) {
          case flat::Type::Kind::kBox:
            ZX_PANIC("no box types should appear at this point");
          case flat::Type::Kind::kArray:
            file_ << kIndent << "memcpy(out_" << name << ", _response->" << name << ", ";
            EmitArraySizeOf(&file_, member);
            file_ << ");\n";
            break;
          case flat::Type::Kind::kVector:
            file_ << kIndent << "memcpy(" << name << "_buffer, _response->" << name
                  << ".data, sizeof(*" << name << "_buffer) * _response->" << name << ".count);\n";
            file_ << kIndent << "*out_" << name << "_count = _response->" << name << ".count;\n";
            break;
          case flat::Type::Kind::kString:
            file_ << kIndent << "memcpy(" << name << "_buffer, _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::kTransportSide:
          case flat::Type::Kind::kPrimitive:
            file_ << kIndent << "*out_" << name << " = _response->" << name << ";\n";
            break;
          case flat::Type::Kind::kIdentifier:
            switch (member.decl_kind.value()) {
              case flat::Decl::Kind::kBuiltin:
              case flat::Decl::Kind::kConst:
              case flat::Decl::Kind::kResource:
              case flat::Decl::Kind::kService:
              case flat::Decl::Kind::kTypeAlias:
                ZX_PANIC("bad decl kind for member");
              case flat::Decl::Kind::kBits:
              case flat::Decl::Kind::kEnum:
              case flat::Decl::Kind::kProtocol:
                file_ << kIndent << "*out_" << name << " = _response->" << name << ";\n";
                break;
              case flat::Decl::Kind::kTable:
                ZX_PANIC("c-codegen for tables not implemented");
              case flat::Decl::Kind::kUnion:
                ZX_PANIC("c-codegen for unions not implemented");
              case flat::Decl::Kind::kNewType:
                ZX_PANIC("c-codegen for new-types not implemented");
              case flat::Decl::Kind::kStruct:
                switch (member.nullability) {
                  case types::Nullability::kNullable:
                    file_ << kIndent << "if (_response->" << name << ") {\n";
                    file_ << kIndent << kIndent << "*out_" << name << " = *(_response->" << 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(out_" << name << ", 0, sizeof(*out_"
                          << name << "));\n";
                    file_ << kIndent << "}\n";
                    break;
                  case types::Nullability::kNonnullable:
                    file_ << kIndent << "*out_" << name << " = _response->" << name << ";\n";
                    break;
                }
                break;
            }
            break;
          case flat::Type::Kind::kUntypedNumeric:
            ZX_PANIC("should not have untyped numeric here");
        }
      }

      file_ << kIndent << "return ZX_OK;\n";
    }
    file_ << "}\n\n";
  }
}

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

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

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

  EmitBlank(&file_);
}

void CGenerator::ProduceProtocolServerImplementation(const NamedProtocol& named_protocol) {
  EmitServerTryDispatchDecl(&file_, named_protocol.c_name);
  file_ << " {\n";
  file_ << kIndent << "if (msg->num_bytes < sizeof(fidl_message_header_t)) {\n";
  file_ << kIndent << kIndent << "FidlHandleCloseMany(msg->handles, msg->num_handles);\n";
  file_ << kIndent << kIndent << "return ZX_ERR_INVALID_ARGS;\n";
  file_ << kIndent << "}\n";
  file_ << kIndent << "zx_status_t status = ZX_OK;\n";
  file_ << kIndent << "fidl_message_header_t* hdr = (fidl_message_header_t*)msg->bytes;\n";
  EmitMagicNumberCheck(&file_);
  file_ << kIndent << "switch (hdr->ordinal) {\n";

  for (const auto& method_info : named_protocol.methods) {
    if (!method_info.request)
      continue;
    std::vector<Member> request;
    if (!GetMethodParameters(method_info, &request, nullptr)) {
      continue;
    }
    file_ << kIndent << "case " << method_info.ordinal_name << ": {\n";
    if (!request.empty()) {
      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";
      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::kBox:
          ZX_PANIC("no box types should appear at this point");
        case flat::Type::Kind::kArray:
        case flat::Type::Kind::kHandle:
        case flat::Type::Kind::kTransportSide:
        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:
          switch (member.decl_kind.value()) {
            case flat::Decl::Kind::kBuiltin:
            case flat::Decl::Kind::kConst:
            case flat::Decl::Kind::kResource:
            case flat::Decl::Kind::kService:
            case flat::Decl::Kind::kTypeAlias:
              ZX_PANIC("bad decl kind for member");
            case flat::Decl::Kind::kNewType:
              ZX_PANIC("c-codegen for new-types not implemented");
            case flat::Decl::Kind::kBits:
            case flat::Decl::Kind::kEnum:
            case flat::Decl::Kind::kProtocol:
              file_ << ", request->" << member.name;
              break;
            case flat::Decl::Kind::kTable:
              ZX_PANIC("c-codegen for tables not yet implemented");
            case flat::Decl::Kind::kStruct:
            case flat::Decl::Kind::kUnion:
              switch (member.nullability) {
                case types::Nullability::kNullable:
                  file_ << ", request->" << member.name;
                  break;
                case types::Nullability::kNonnullable:
                  file_ << ", &(request->" << member.name << ")";
                  break;
              }
              break;
          }
          break;
        case flat::Type::Kind::kUntypedNumeric:
          ZX_PANIC("should not have untyped numeric here");
      }
    }
    if (method_info.response != nullptr)
      file_ << ", txn";
    file_ << ");\n";
    file_ << kIndent << kIndent << "break;\n";
    file_ << kIndent << "}\n";
  }
  file_ << kIndent << "default: {\n";
  file_ << kIndent << kIndent << "return ZX_ERR_NOT_SUPPORTED;\n";
  file_ << kIndent << "}\n";
  file_ << kIndent << "}\n";
  file_ << kIndent << "if ("
        << "status != ZX_OK && "
        << "status != ZX_ERR_STOP && "
        << "status != ZX_ERR_NEXT && "
        << "status != ZX_ERR_ASYNC) {\n";
  file_ << kIndent << kIndent << "return ZX_ERR_INTERNAL;\n";
  file_ << kIndent << "} else {\n";
  file_ << kIndent << kIndent << "return status;\n";
  file_ << kIndent << "}\n";
  file_ << "}\n\n";

  EmitServerDispatchDecl(&file_, named_protocol.c_name);
  file_ << " {\n";
  file_ << kIndent << "zx_status_t status = " << named_protocol.c_name
        << "_try_dispatch(ctx, txn, msg, ops);\n";
  file_ << kIndent << "if (status == ZX_ERR_NOT_SUPPORTED)\n";
  file_ << kIndent << kIndent << "FidlHandleCloseMany(msg->handles, msg->num_handles);\n";
  file_ << kIndent << "return status;\n";
  file_ << "}\n\n";

  for (const auto& method_info : named_protocol.methods) {
    if (!method_info.request || !method_info.response)
      continue;

    std::vector<Member> response;
    if (!GetMethodParameters(method_info, nullptr, &response) ||
        !CanGenerateCodecFunctions(response)) {
      continue;
    }

    size_t hcount = GetMaxHandlesFor(named_protocol.transport, method_info.response->typeshape);

    EmitServerReplyDecl(&file_, method_info.c_name, response);
    file_ << " {\n";
    file_ << kIndent << "uint32_t _wr_num_bytes = sizeof(" << method_info.response->c_name << ")";
    EmitMeasureInParams(&file_, response);
    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";
    EmitTxnHeader(&file_, "_response", method_info.ordinal_name);
    EmitLinearizeMessage(&file_, "_response", "_wr_bytes", response);
    const char* handle_value = "NULL";
    const char* handle_metadata_value = "NULL";
    if (hcount > 0) {
      file_ << kIndent << "zx_handle_t _handles[" << hcount << "];\n";
      file_ << kIndent << "fidl_channel_handle_metadata_t _handle_metadata[" << hcount << "];\n";
      handle_value = "_handles";
      handle_metadata_value = "_handle_metadata";
    }
    file_ << kIndent << "fidl_outgoing_msg_t _msg = {\n";
    file_ << kIndent << kIndent << ".type = FIDL_OUTGOING_MSG_TYPE_BYTE,\n";
    file_ << kIndent << kIndent << ".byte = {\n";
    file_ << kIndent << kIndent << kIndent << ".bytes = _wr_bytes,\n";
    file_ << kIndent << kIndent << kIndent << ".handles = " << handle_value << ",\n";
    file_ << kIndent << kIndent << kIndent << ".handle_metadata = (fidl_handle_metadata_t*)("
          << handle_metadata_value << "),\n";
    file_ << kIndent << kIndent << kIndent << ".num_bytes = _wr_num_bytes,\n";
    file_ << kIndent << kIndent << kIndent << ".num_handles = " << hcount << ",\n";
    file_ << kIndent << kIndent << "},\n";
    file_ << kIndent << "};\n";
    bool has_padding = method_info.response->typeshape.has_padding;
    bool encode_response = (hcount > 0) || CountSecondaryObjects(response) > 0 || has_padding;
    if (encode_response) {
      file_ << kIndent << "zx_status_t _status = fidl_encode_msg(&"
            << method_info.response->coded_name << ", &_msg.byte, &_msg.byte.num_handles, NULL);\n";
      file_ << kIndent << "if (_status != ZX_OK)\n";
      file_ << kIndent << kIndent << "return _status;\n";
    } else {
      file_ << kIndent << "// OPTIMIZED AWAY fidl_encode() of POD-only reply\n";
    }
    file_ << kIndent << "return _txn->reply(_txn, &_msg);\n";
    file_ << "}\n\n";
  }
}

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

  std::map<const flat::Decl*, NamedBits> named_bits = NameBits(compilation_->declarations.bits);
  std::map<const flat::Decl*, NamedConst> named_consts =
      NameConsts(compilation_->declarations.consts);
  std::map<const flat::Decl*, NamedEnum> named_enums = NameEnums(compilation_->declarations.enums);
  std::map<const flat::Decl*, NamedProtocol> named_protocols =
      NameProtocols(compilation_->declarations.protocols);
  std::map<const flat::Decl*, NamedStruct> named_structs =
      NameStructs(compilation_->declarations.structs, compilation_->declarations.protocols);

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

  for (const auto* decl : compilation_->declaration_order) {
    if (!DeclAllowed(decl)) {
      continue;
    }
    switch (decl->kind) {
      case flat::Decl::Kind::kBuiltin:
        ZX_PANIC("unexpected builtin");
      case flat::Decl::Kind::kBits: {
        auto iter = named_bits.find(decl);
        if (iter != named_bits.end()) {
          ProduceBitsForwardDeclaration(iter->second);
        }
        break;
      }
      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::kNewType:
        // TODO(fxbug.dev/7807): Do more than nothing.
        break;
      case flat::Decl::Kind::kProtocol: {
        auto iter = named_protocols.find(decl);
        if (iter != named_protocols.end()) {
          ProduceProtocolForwardDeclaration(iter->second);
        }
        break;
      }
      case flat::Decl::Kind::kResource:
        // Do nothing.
        break;
      case flat::Decl::Kind::kService:
        // Do nothing.
        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::kTable:
        // Do nothing.
        break;
      case flat::Decl::Kind::kTypeAlias:
        // TODO(fxbug.dev/7807): Do more than nothing.
        break;
      case flat::Decl::Kind::kUnion:
        // Do nothing.
        break;
    }  // switch
  }

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

  for (const auto* decl : compilation_->declaration_order) {
    if (!DeclAllowed(decl)) {
      continue;
    }

    switch (decl->kind) {
      case flat::Decl::Kind::kBuiltin:
      case flat::Decl::Kind::kBits:
      case flat::Decl::Kind::kConst:
      case flat::Decl::Kind::kEnum:
      case flat::Decl::Kind::kNewType:
      case flat::Decl::Kind::kResource:
      case flat::Decl::Kind::kService:
      case flat::Decl::Kind::kStruct:
      case flat::Decl::Kind::kTable:
      case flat::Decl::Kind::kTypeAlias:
      case flat::Decl::Kind::kUnion:
        // Only messages have extern fidl_type_t declarations.
        break;
      case flat::Decl::Kind::kProtocol: {
        auto iter = named_protocols.find(decl);
        if (iter != named_protocols.end()) {
          ProduceProtocolExternDeclaration(iter->second);
        }
        break;
      }
    }  // switch
  }

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

  for (const auto* decl : compilation_->declaration_order) {
    if (!DeclAllowed(decl)) {
      continue;
    }

    switch (decl->kind) {
      case flat::Decl::Kind::kBuiltin:
        ZX_PANIC("unexpected builtin");
      case flat::Decl::Kind::kBits:
        // Bits can be entirely forward declared, as they have no
        // dependencies other than standard headers.
        break;
      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::kNewType:
        // TODO(fxbug.dev/7807): Do more than nothing.
        break;
      case flat::Decl::Kind::kProtocol: {
        auto iter = named_protocols.find(decl);
        if (iter != named_protocols.end()) {
          ProduceProtocolDeclaration(iter->second);
        }
        break;
      }
      case flat::Decl::Kind::kResource:
        // Do nothing.
        break;
      case flat::Decl::Kind::kService:
        // Do nothing.
        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::kTable:
        // Do nothing.
        break;
      case flat::Decl::Kind::kTypeAlias:
        // TODO(fxbug.dev/7807): Do more than nothing.
        break;
      case flat::Decl::Kind::kUnion:
        // Do nothing.
        break;
    }  // switch
  }

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

  for (const auto* decl : compilation_->declaration_order) {
    switch (decl->kind) {
      case flat::Decl::Kind::kBuiltin:
      case flat::Decl::Kind::kBits:
      case flat::Decl::Kind::kConst:
      case flat::Decl::Kind::kEnum:
      case flat::Decl::Kind::kNewType:
      case flat::Decl::Kind::kResource:
      case flat::Decl::Kind::kService:
      case flat::Decl::Kind::kStruct:
      case flat::Decl::Kind::kTable:
      case flat::Decl::Kind::kTypeAlias:
      case flat::Decl::Kind::kUnion:
        // Only protocols have client declarations.
        break;
      case flat::Decl::Kind::kProtocol: {
        if (!HasSimpleLayout(decl))
          break;
        auto iter = named_protocols.find(decl);
        if (iter != named_protocols.end()) {
          ProduceProtocolClientDeclaration(iter->second);
          ProduceProtocolServerDeclaration(iter->second);
        }
        break;
      }
    }  // switch
  }

  GenerateEpilogues();

  return std::move(file_);
}

std::ostringstream CGenerator::ProduceClient() {
  EmitFileComment(&file_);
  EmitIncludeHeader(&file_, "<lib/fidl/coding.h>");
  EmitIncludeHeader(&file_, "<lib/fidl/internal.h>");
  EmitIncludeHeader(&file_, "<lib/fidl/txn_header.h>");
  EmitIncludeHeader(&file_, "<alloca.h>");
  EmitIncludeHeader(&file_, "<string.h>");
  EmitIncludeHeader(&file_, "<zircon/assert.h>");
  EmitIncludeHeader(&file_, "<zircon/syscalls.h>");
  EmitIncludeHeader(&file_, "<" + NameLibraryCHeader(compilation_->library_name) + ">");
  EmitBlank(&file_);

  std::map<const flat::Decl*, NamedProtocol> named_protocols =
      NameProtocols(compilation_->declarations.protocols);

  for (const auto* decl : compilation_->declaration_order) {
    switch (decl->kind) {
      case flat::Decl::Kind::kBuiltin:
      case flat::Decl::Kind::kBits:
      case flat::Decl::Kind::kConst:
      case flat::Decl::Kind::kEnum:
      case flat::Decl::Kind::kNewType:
      case flat::Decl::Kind::kResource:
      case flat::Decl::Kind::kService:
      case flat::Decl::Kind::kStruct:
      case flat::Decl::Kind::kTable:
      case flat::Decl::Kind::kTypeAlias:
      case flat::Decl::Kind::kUnion:
        // Only protocols have client implementations.
        break;
      case flat::Decl::Kind::kProtocol: {
        if (!HasSimpleLayout(decl))
          break;
        auto iter = named_protocols.find(decl);
        if (iter != named_protocols.end()) {
          ProduceProtocolClientImplementation(iter->second);
        }
        break;
      }
    }  // switch
  }

  return std::move(file_);
}

std::ostringstream CGenerator::ProduceServer() {
  EmitFileComment(&file_);
  EmitIncludeHeader(&file_, "<lib/fidl/coding.h>");
  EmitIncludeHeader(&file_, "<lib/fidl/internal.h>");
  EmitIncludeHeader(&file_, "<lib/fidl/txn_header.h>");
  EmitIncludeHeader(&file_, "<alloca.h>");
  EmitIncludeHeader(&file_, "<string.h>");
  EmitIncludeHeader(&file_, "<zircon/assert.h>");
  EmitIncludeHeader(&file_, "<zircon/syscalls.h>");
  EmitIncludeHeader(&file_, "<" + NameLibraryCHeader(compilation_->library_name) + ">");
  EmitBlank(&file_);

  std::map<const flat::Decl*, NamedProtocol> named_protocols =
      NameProtocols(compilation_->declarations.protocols);

  for (const auto* decl : compilation_->declaration_order) {
    switch (decl->kind) {
      case flat::Decl::Kind::kBuiltin:
      case flat::Decl::Kind::kBits:
      case flat::Decl::Kind::kConst:
      case flat::Decl::Kind::kEnum:
      case flat::Decl::Kind::kNewType:
      case flat::Decl::Kind::kResource:
      case flat::Decl::Kind::kService:
      case flat::Decl::Kind::kStruct:
      case flat::Decl::Kind::kTable:
      case flat::Decl::Kind::kTypeAlias:
      case flat::Decl::Kind::kUnion:
        // Only protocols have client implementations.
        break;
      case flat::Decl::Kind::kProtocol: {
        if (!HasSimpleLayout(decl))
          break;
        auto iter = named_protocols.find(decl);
        if (iter != named_protocols.end()) {
          ProduceProtocolServerImplementation(iter->second);
        }
        break;
      }
    }  // switch
  }

  return std::move(file_);
}

}  // namespace fidl
