// Copyright 2014 The Chromium OS 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 "chromeos-dbus-bindings/proxy_generator.h"

#include <algorithm>
#include <utility>

#include <base/files/file_path.h>
#include <base/format_macros.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

#include "chromeos-dbus-bindings/disallow_copy_and_assign.h"
#include "chromeos-dbus-bindings/dbus_signature.h"
#include "chromeos-dbus-bindings/header_generator.h"
#include "chromeos-dbus-bindings/indented_text.h"
#include "chromeos-dbus-bindings/name_parser.h"

using base::StringPrintf;
using std::pair;
using std::string;
using std::vector;

namespace chromeos_dbus_bindings {

namespace {
// Helper struct to encapsulate information about method call parameter during
// code generation.
struct ParamDef {
  ParamDef(const string& param_type, const string& param_name, bool param_ref)
      : type(param_type), name(param_name), is_const_ref(param_ref) {}

  string type;
  string name;
  bool is_const_ref;
};

string GetParamString(const ParamDef& param_def) {
  return StringPrintf(param_def.is_const_ref ? "const %s& %s" : "%s* %s",
                      param_def.type.c_str(), param_def.name.c_str());
}
}  // anonymous namespace

ProxyGenerator::ProxyGenerator() = default;

bool ProxyGenerator::GenerateProxies(const ServiceConfig& config,
                                     const std::vector<Interface>& interfaces,
                                     const base::FilePath& output_file) {
  IndentedText text;

  text.AddLine("// Automatic generation of D-Bus interfaces:");
  for (const auto& interface : interfaces) {
    text.AddLine(StringPrintf("//  - %s", interface.name.c_str()));
  }
  string header_guard = GenerateHeaderGuard(output_file);
  text.AddLine(StringPrintf("#ifndef %s", header_guard.c_str()));
  text.AddLine(StringPrintf("#define %s", header_guard.c_str()));
  text.AddLine("#include <memory>");
  text.AddLine("#include <string>");
  text.AddLine("#include <vector>");
  text.AddBlankLine();
  text.AddLine("#include <base/bind.h>");
  text.AddLine("#include <base/callback.h>");
  text.AddLine("#include <base/files/scoped_file.h>");
  text.AddLine("#include <base/logging.h>");
  text.AddLine("#include <base/macros.h>");
  text.AddLine("#include <base/memory/ref_counted.h>");
  text.AddLine("#include <brillo/any.h>");
  text.AddLine("#include <brillo/dbus/dbus_method_invoker.h>");
  text.AddLine("#include <brillo/dbus/dbus_property.h>");
  text.AddLine("#include <brillo/dbus/dbus_signal_handler.h>");
  text.AddLine("#include <brillo/dbus/file_descriptor.h>");
  text.AddLine("#include <brillo/errors/error.h>");
  text.AddLine("#include <brillo/variant_dictionary.h>");
  text.AddLine("#include <dbus/bus.h>");
  text.AddLine("#include <dbus/message.h>");
  text.AddLine("#include <dbus/object_manager.h>");
  text.AddLine("#include <dbus/object_path.h>");
  text.AddLine("#include <dbus/object_proxy.h>");
  text.AddBlankLine();

  if (!config.object_manager.name.empty()) {
    // Add forward-declaration for Object Manager proxy class.
    NameParser parser{config.object_manager.name};
    parser.AddOpenNamespaces(&text, false);
    text.AddLine(
        StringPrintf("class %s;", parser.MakeProxyName(false).c_str()));
    parser.AddCloseNamespaces(&text, false);
    text.AddBlankLine();
  }

  for (const auto& interface : interfaces) {
    GenerateInterfaceProxyInterface(config, interface, &text);
    GenerateInterfaceProxy(config, interface, &text);
  }

  ObjectManager::GenerateProxy(config, interfaces, &text);

  text.AddLine(StringPrintf("#endif  // %s", header_guard.c_str()));
  return WriteTextToFile(output_file, text);
}

bool ProxyGenerator::GenerateMocks(const ServiceConfig& config,
                                   const std::vector<Interface>& interfaces,
                                   const base::FilePath& mock_file,
                                   const base::FilePath& proxy_file,
                                   bool use_literal_proxy_file) {
  IndentedText text;

  text.AddLine("// Automatic generation of D-Bus interface mock proxies for:");
  for (const auto& interface : interfaces) {
    text.AddLine(StringPrintf("//  - %s", interface.name.c_str()));
  }
  string header_guard = GenerateHeaderGuard(mock_file);
  text.AddLine(StringPrintf("#ifndef %s", header_guard.c_str()));
  text.AddLine(StringPrintf("#define %s", header_guard.c_str()));
  text.AddLine("#include <string>");
  text.AddLine("#include <vector>");
  text.AddBlankLine();
  text.AddLine("#include <base/callback_forward.h>");
  text.AddLine("#include <base/logging.h>");
  text.AddLine("#include <base/macros.h>");
  text.AddLine("#include <brillo/any.h>");
  text.AddLine("#include <brillo/errors/error.h>");
  text.AddLine("#include <brillo/variant_dictionary.h>");
  text.AddLine("#include <gmock/gmock.h>");
  text.AddBlankLine();

  if (!proxy_file.empty()) {
    // If we have a proxy header file, it would have the proxy interfaces we
    // need to base our mocks on, so we need to include that header file.
    base::FilePath relative_path;
    if (use_literal_proxy_file) {
      relative_path = proxy_file;
    } else {
      // Generate a relative path from |mock_file| to |proxy_file|.
      // First, get the path components for both source and destination paths.
      std::vector<std::string> src_components;
      mock_file.DirName().GetComponents(&src_components);
      std::vector<std::string> dest_components;
      proxy_file.DirName().GetComponents(&dest_components);

      // Find the common root.
      auto mismatch_pair =
          std::mismatch(src_components.begin(), src_components.end(),
                        dest_components.begin(), dest_components.end());

      // For each remaining components in the |src_components|, generate the
      // parent directory references ("..").
      size_t src_count =
          std::distance(mismatch_pair.first, src_components.end());
      std::vector<std::string> components{src_count,
                                          base::FilePath::kParentDirectory};
      // Append the remaining components from |dest_components|.
      components.insert(components.end(), mismatch_pair.second,
                        dest_components.end());
      // Finally, add the base name of the target file name.
      components.push_back(proxy_file.BaseName().value());
      // Now reconstruct the relative path.
      relative_path = base::FilePath{base::FilePath::kCurrentDirectory};
      for (const auto& component : components)
        relative_path = relative_path.Append(component);
    }
    text.AddLine(
        StringPrintf("#include \"%s\"", relative_path.value().c_str()));
    text.AddBlankLine();
  }

  for (const auto& interface : interfaces) {
    // If we have no proxy file, we need the abstract interfaces generated here.
    if (proxy_file.empty())
      GenerateInterfaceProxyInterface(config, interface, &text);
    GenerateInterfaceMock(config, interface, &text);
  }

  text.AddLine(StringPrintf("#endif  // %s", header_guard.c_str()));
  return WriteTextToFile(mock_file, text);
}

void ProxyGenerator::GenerateInterfaceProxyInterface(
    const ServiceConfig& config,
    const Interface& interface,
    IndentedText* text) {
  NameParser parser{interface.name};
  string proxy_name = parser.MakeProxyName(false);
  string base_interface_name = proxy_name + "Interface";

  parser.AddOpenNamespaces(text, false);
  text->AddBlankLine();

  text->AddLine(StringPrintf("// Abstract interface proxy for %s.",
                             parser.MakeFullCppName().c_str()));
  text->AddComments(interface.doc_string);
  text->AddLine(StringPrintf("class %s {", base_interface_name.c_str()));
  text->AddLineWithOffset("public:", kScopeOffset);
  text->PushOffset(kBlockOffset);
  text->AddLine(
      StringPrintf("virtual ~%s() = default;", base_interface_name.c_str()));

  for (const auto& method : interface.methods) {
    AddMethodProxy(method, interface.name, true, text);
    AddAsyncMethodProxy(method, interface.name, true, text);
  }
  for (const auto& signal : interface.signals) {
    AddSignalHandlerRegistration(signal, interface.name, true, text);
  }
  AddProperties(interface, true, text);
  text->AddBlankLine();
  text->AddLine("virtual const dbus::ObjectPath& GetObjectPath() const = 0;");
  text->AddLine("virtual dbus::ObjectProxy* GetObjectProxy() const = 0;");
  if (!interface.properties.empty()) {
    if (config.object_manager.name.empty())
      AddInitializeProperties(proxy_name, true, text);
    else
      AddSetPropertyChanged(proxy_name, true, text);
  }

  text->PopOffset();
  text->AddLine("};");
  text->AddBlankLine();

  parser.AddCloseNamespaces(text, false);
  text->AddBlankLine();
}

void ProxyGenerator::GenerateInterfaceProxy(const ServiceConfig& config,
                                            const Interface& interface,
                                            IndentedText* text) {
  NameParser parser{interface.name};
  string proxy_name = parser.MakeProxyName(false);
  string base_interface_name = proxy_name + "Interface";

  parser.AddOpenNamespaces(text, false);
  text->AddBlankLine();

  text->AddLine(StringPrintf("// Interface proxy for %s.",
                             parser.MakeFullCppName().c_str()));
  text->AddComments(interface.doc_string);
  text->AddLine(StringPrintf("class %s final : public %s {", proxy_name.c_str(),
                             base_interface_name.c_str()));
  text->AddLineWithOffset("public:", kScopeOffset);
  text->PushOffset(kBlockOffset);
  AddPropertySet(config, interface, text);
  AddConstructor(config, interface, proxy_name, text);
  AddDisallowCopyAndAssign(proxy_name, text);
  text->AddBlankLine();
  AddDestructor(proxy_name, text);
  for (const auto& signal : interface.signals) {
    AddSignalHandlerRegistration(signal, interface.name, false, text);
  }
  AddReleaseObjectProxy(text);
  AddGetObjectPath(text);
  AddGetObjectProxy(text);
  if (!interface.properties.empty()) {
    if (config.object_manager.name.empty())
      AddInitializeProperties(proxy_name, false, text);
    else
      AddSetPropertyChanged(proxy_name, false, text);
    AddGetProperties(text);
  }
  for (const auto& method : interface.methods) {
    AddMethodProxy(method, interface.name, false, text);
    AddAsyncMethodProxy(method, interface.name, false, text);
  }
  AddProperties(interface, false, text);

  text->PopOffset();
  text->AddBlankLine();
  text->AddLineWithOffset("private:", kScopeOffset);

  text->PushOffset(kBlockOffset);
  if (!config.object_manager.name.empty() && !interface.properties.empty())
    AddOnPropertyChanged(text);
  text->AddLine("scoped_refptr<dbus::Bus> bus_;");
  if (config.service_name.empty()) {
    text->AddLine("std::string service_name_;");
  } else {
    text->AddLine(StringPrintf("const std::string service_name_{\"%s\"};",
                               config.service_name.c_str()));
  }
  if (interface.path.empty()) {
    text->AddLine("dbus::ObjectPath object_path_;");
  } else {
    text->AddLine(StringPrintf("const dbus::ObjectPath object_path_{\"%s\"};",
                               interface.path.c_str()));
  }
  if (!config.object_manager.name.empty() && !interface.properties.empty()) {
    text->AddLine("PropertySet* property_set_;");
    text->AddLine(
        StringPrintf("base::Callback<void(%sInterface*, const std::string&)> "
                     "on_property_changed_;",
                     proxy_name.c_str()));
  }
  text->AddLine("dbus::ObjectProxy* dbus_object_proxy_;");
  if (config.object_manager.name.empty() && !interface.properties.empty())
    text->AddLine("std::unique_ptr<PropertySet> property_set_;");
  text->AddBlankLine();

  if (!config.object_manager.name.empty() && !interface.properties.empty()) {
    text->AddLine(StringPrintf(
        "friend class %s;",
        NameParser{config.object_manager.name}.MakeProxyName(true).c_str()));
  }
  text->PopOffset();
  text->AddLine("};");

  text->AddBlankLine();

  parser.AddCloseNamespaces(text, false);

  text->AddBlankLine();
}

void ProxyGenerator::GenerateInterfaceMock(const ServiceConfig& config,
                                           const Interface& interface,
                                           IndentedText* text) {
  NameParser parser{interface.name};
  string proxy_name = parser.MakeProxyName(false);
  string base_interface_name = proxy_name + "Interface";
  string mock_name = proxy_name + "Mock";

  parser.AddOpenNamespaces(text, false);
  text->AddBlankLine();

  text->AddLine(
      StringPrintf("// Mock object for %s.", base_interface_name.c_str()));
  text->AddLine(StringPrintf("class %s : public %s {", mock_name.c_str(),
                             base_interface_name.c_str()));
  text->AddLineWithOffset("public:", kScopeOffset);
  text->PushOffset(kBlockOffset);
  text->AddLine(StringPrintf("%s() = default;", mock_name.c_str()));
  AddDisallowCopyAndAssign(mock_name, text);
  text->AddBlankLine();

  for (const auto& method : interface.methods) {
    AddMethodMock(method, interface.name, text);
    AddAsyncMethodMock(method, interface.name, text);
  }
  for (const auto& signal : interface.signals) {
    AddSignalHandlerRegistrationMock(signal, text);
  }

  DBusSignature signature;
  for (const auto& prop : interface.properties) {
    auto parsed_type = signature.Parse(prop.type);
    CHECK(parsed_type && parsed_type->IsValidPropertyType());
    string type = parsed_type->GetInArgType(DBusType::Receiver::kProxy);
    string name = NameParser{prop.name}.MakeVariableName();
    text->AddLine(StringPrintf("MOCK_CONST_METHOD0(%s, %s());", name.c_str(),
                               type.c_str()));
    if (prop.access == "readwrite") {
      text->AddLine(
          StringPrintf("MOCK_METHOD2(set_%s, void(%s, "
                       "const base::Callback<bool>&));",
                       name.c_str(), type.c_str()));
    }
  }
  text->AddLine(
      "MOCK_CONST_METHOD0(GetObjectPath, const dbus::ObjectPath&());");
  text->AddLine("MOCK_CONST_METHOD0(GetObjectProxy, dbus::ObjectProxy*());");
  if (!interface.properties.empty()) {
    if (config.object_manager.name.empty()) {
      text->AddLineAndPushOffsetTo("MOCK_METHOD1(InitializeProperties,", 1,
                                   '(');
      text->AddLine(
          StringPrintf("void(const base::Callback<void(%sInterface*, "
                       "const std::string&)>&));",
                       proxy_name.c_str()));
      text->PopOffset();
    } else {
      text->AddLineAndPushOffsetTo("MOCK_METHOD1(SetPropertyChangedCallback,",
                                   1, '(');
      text->AddLine(
          StringPrintf("void(const base::Callback<void(%sInterface*, "
                       "const std::string&)>&));",
                       proxy_name.c_str()));
      text->PopOffset();
    }
  }

  text->PopOffset();
  text->AddLine("};");

  parser.AddCloseNamespaces(text, false);
  text->AddBlankLine();
}

void ProxyGenerator::AddConstructor(const ServiceConfig& config,
                                    const Interface& interface,
                                    const string& class_name,
                                    IndentedText* text) {
  IndentedText block;
  vector<ParamDef> args{{"scoped_refptr<dbus::Bus>", "bus", true}};
  if (config.service_name.empty())
    args.emplace_back("std::string", "service_name", true);
  if (interface.path.empty())
    args.emplace_back("dbus::ObjectPath", "object_path", true);
  if (!config.object_manager.name.empty() && !interface.properties.empty())
    args.emplace_back("PropertySet", "property_set", false);

  if (args.size() == 1) {
    block.AddLine(StringPrintf("%s(%s) :", class_name.c_str(),
                               GetParamString(args.front()).c_str()));
  } else {
    block.AddLine(StringPrintf("%s(", class_name.c_str()));
    block.PushOffset(kLineContinuationOffset);
    for (size_t i = 0; i < args.size() - 1; i++) {
      block.AddLine(StringPrintf("%s,", GetParamString(args[i]).c_str()));
    }
    block.AddLine(StringPrintf("%s) :", GetParamString(args.back()).c_str()));
  }
  block.PushOffset(kLineContinuationOffset);
  for (const auto& arg : args) {
    block.AddLine(StringPrintf("%s_{%s},", arg.name.c_str(), arg.name.c_str()));
  }
  block.AddLine("dbus_object_proxy_{");
  block.AddLineWithOffset(
      "bus_->GetObjectProxy(service_name_, object_path_)} {",
      kLineContinuationOffset);
  block.PopOffset();
  if (args.size() > 1)
    block.PopOffset();
  block.AddLine("}");
  block.AddBlankLine();
  text->AddBlock(block);
}

void ProxyGenerator::AddDestructor(const string& class_name,
                                   IndentedText* text) {
  IndentedText block;
  block.AddLine(StringPrintf("~%s() override {", class_name.c_str()));
  block.AddLine("}");
  text->AddBlock(block);
}

void ProxyGenerator::AddReleaseObjectProxy(IndentedText* text) {
  text->AddBlankLine();
  text->AddLine("void ReleaseObjectProxy(const base::Closure& callback) {");
  text->AddLineWithOffset(
      "bus_->RemoveObjectProxy(service_name_, object_path_, callback);",
      kBlockOffset);
  text->AddLine("}");
}

void ProxyGenerator::AddGetObjectPath(IndentedText* text) {
  text->AddBlankLine();
  text->AddLine("const dbus::ObjectPath& GetObjectPath() const override {");
  text->AddLineWithOffset("return object_path_;", kBlockOffset);
  text->AddLine("}");
}

void ProxyGenerator::AddGetObjectProxy(IndentedText* text) {
  text->AddBlankLine();
  text->AddLine("dbus::ObjectProxy* GetObjectProxy() const override {");
  text->AddLineWithOffset("return dbus_object_proxy_;", kBlockOffset);
  text->AddLine("}");
}

void ProxyGenerator::AddInitializeProperties(const string& class_name,
                                             bool declaration_only,
                                             IndentedText* text) {
  text->AddBlankLine();
  text->AddLine(StringPrintf("%svoid InitializeProperties(",
                             declaration_only ? "virtual " : ""));
  text->AddLineWithOffset(
      StringPrintf("const base::Callback<void(%sInterface*, "
                   "const std::string&)>& callback) %s",
                   class_name.c_str(),
                   declaration_only ? "= 0;" : "override {"),
      kLineContinuationOffset);
  if (!declaration_only) {
    IndentedText block;
    block.PushOffset(kBlockOffset);
    block.AddLine("property_set_.reset(");
    block.AddLineWithOffset(
        "new PropertySet(dbus_object_proxy_, base::Bind(callback, this)));",
        kLineContinuationOffset);
    block.AddLine("property_set_->ConnectSignals();");
    block.AddLine("property_set_->GetAll();");
    text->AddBlock(block);
    text->AddLine("}");
  }
}

void ProxyGenerator::AddSetPropertyChanged(const string& class_name,
                                           bool declaration_only,
                                           IndentedText* text) {
  text->AddBlankLine();
  text->AddLine(StringPrintf("%svoid SetPropertyChangedCallback(",
                             declaration_only ? "virtual " : ""));
  text->AddLineWithOffset(
      StringPrintf("const base::Callback<void(%sInterface*, "
                   "const std::string&)>& callback) %s",
                   class_name.c_str(),
                   declaration_only ? "= 0;" : "override {"),
      kLineContinuationOffset);
  if (!declaration_only) {
    text->AddLineWithOffset("on_property_changed_ = callback;", kBlockOffset);
    text->AddLine("}");
  }
}

void ProxyGenerator::AddGetProperties(IndentedText* text) {
  text->AddBlankLine();
  // Dereference and take the address since sometimes property_set_ is a raw
  // pointer and sometimes it is a std::unique_ptr.
  text->AddLine(
      "const PropertySet* GetProperties() const { "
      "return &(*property_set_); }");
  text->AddLine("PropertySet* GetProperties() { return &(*property_set_); }");
}

void ProxyGenerator::AddOnPropertyChanged(IndentedText* text) {
  text->AddLine("void OnPropertyChanged(const std::string& property_name) {");
  text->PushOffset(kBlockOffset);
  text->AddLine("if (!on_property_changed_.is_null())");
  text->PushOffset(kBlockOffset);
  text->AddLine("on_property_changed_.Run(this, property_name);");
  text->PopOffset();
  text->PopOffset();
  text->AddLine("}");
  text->AddBlankLine();
}

void ProxyGenerator::AddSignalHandlerRegistration(
    const Interface::Signal& signal,
    const string& interface_name,
    bool declaration_only,
    IndentedText* text) {
  IndentedText block;
  block.AddBlankLine();
  block.AddLine(StringPrintf("%svoid Register%sSignalHandler(",
                             declaration_only ? "virtual " : "",
                             signal.name.c_str()));
  block.PushOffset(kLineContinuationOffset);
  AddSignalCallbackArg(signal, false, &block);
  block.AddLine(StringPrintf(
      "dbus::ObjectProxy::OnConnectedCallback on_connected_callback)%s",
      declaration_only ? " = 0;" : " override {"));
  if (!declaration_only) {
    block.PopOffset();  // Method signature arguments
    block.PushOffset(kBlockOffset);
    block.AddLine("brillo::dbus_utils::ConnectToSignal(");
    block.PushOffset(kLineContinuationOffset);
    block.AddLine("dbus_object_proxy_,");
    block.AddLine(StringPrintf("\"%s\",", interface_name.c_str()));
    block.AddLine(StringPrintf("\"%s\",", signal.name.c_str()));
    block.AddLine("signal_callback,");
    block.AddLine("std::move(on_connected_callback));");
    block.PopOffset();  // Function call line continuation
    block.PopOffset();  // Method body
    block.AddLine("}");
  }
  text->AddBlock(block);
}

void ProxyGenerator::AddPropertySet(const ServiceConfig& config,
                                    const Interface& interface,
                                    IndentedText* text) {
  if (config.object_manager.name.empty() && interface.properties.empty())
    return;

  IndentedText block;
  block.AddLine("class PropertySet : public dbus::PropertySet {");
  block.AddLineWithOffset("public:", kScopeOffset);
  block.PushOffset(kBlockOffset);
  block.AddLineAndPushOffsetTo("PropertySet(dbus::ObjectProxy* object_proxy,",
                               1, '(');
  block.AddLine("const PropertyChangedCallback& callback)");
  block.PopOffset();
  block.PushOffset(kLineContinuationOffset);
  block.AddLineAndPushOffsetTo(": dbus::PropertySet{object_proxy,", 1, '{');
  block.AddLine(StringPrintf("\"%s\",", interface.name.c_str()));
  block.AddLine("callback} {");
  block.PopOffset();
  block.PopOffset();
  block.PushOffset(kBlockOffset);
  for (const auto& prop : interface.properties) {
    block.AddLine(
        StringPrintf("RegisterProperty(%sName(), &%s);", prop.name.c_str(),
                     NameParser{prop.name}.MakeVariableName().c_str()));
  }
  block.PopOffset();
  block.AddLine("}");
  AddDisallowCopyAndAssign("PropertySet", &block);
  block.AddBlankLine();

  DBusSignature signature;
  for (const auto& prop : interface.properties) {
    auto parsed_type = signature.Parse(prop.type);
    CHECK(parsed_type && parsed_type->IsValidPropertyType());
    string type = parsed_type->GetBaseType(DBusType::Direction::kExtract);
    block.AddLine(
        StringPrintf("brillo::dbus_utils::Property<%s> %s;", type.c_str(),
                     NameParser{prop.name}.MakeVariableName().c_str()));
  }
  block.AddBlankLine();

  block.PopOffset();
  block.AddLine("};");
  block.AddBlankLine();

  text->AddBlock(block);
}

void ProxyGenerator::AddProperties(const Interface& interface,
                                   bool declaration_only,
                                   IndentedText* text) {
  if (declaration_only && !interface.properties.empty())
    text->AddBlankLine();

  DBusSignature signature;
  for (const auto& prop : interface.properties) {
    if (declaration_only) {
      text->AddLine(
          StringPrintf("static const char* %sName() { return \"%s\"; }",
                       prop.name.c_str(), prop.name.c_str()));
    }
    auto parsed_type = signature.Parse(prop.type);
    CHECK(parsed_type && parsed_type->IsValidPropertyType());
    string type = parsed_type->GetInArgType(DBusType::Receiver::kProxy);
    string name = NameParser{prop.name}.MakeVariableName();
    if (!declaration_only)
      text->AddBlankLine();
    text->AddLine(StringPrintf(
        "%s%s %s() const%s", declaration_only ? "virtual " : "", type.c_str(),
        name.c_str(), declaration_only ? " = 0;" : " override {"));
    if (!declaration_only) {
      text->AddLineWithOffset(
          StringPrintf("return property_set_->%s.value();", name.c_str()),
          kBlockOffset);
      text->AddLine("}");
    }
    if (prop.access == "readwrite") {
      if (!declaration_only)
        text->AddBlankLine();
      text->AddLineAndPushOffsetTo(
          StringPrintf("%svoid set_%s(%s value,",
                       declaration_only ? "virtual " : "", name.c_str(),
                       type.c_str()),
          1, '(');
      text->AddLine(
          StringPrintf("const base::Callback<void(bool)>& callback)%s",
                       declaration_only ? " = 0;" : " override {"));
      text->PopOffset();
      if (!declaration_only) {
        text->AddLineWithOffset(
            StringPrintf("property_set_->%s.Set(value, callback);",
                         name.c_str()),
            kBlockOffset);
        text->AddLine("}");
      }
    }
  }
}

void ProxyGenerator::AddMethodProxy(const Interface::Method& method,
                                    const string& interface_name,
                                    bool declaration_only,
                                    IndentedText* text) {
  IndentedText block;
  DBusSignature signature;
  block.AddBlankLine();
  block.AddComments(method.doc_string);
  block.AddLine(StringPrintf("%sbool %s(", declaration_only ? "virtual " : "",
                             method.name.c_str()));
  block.PushOffset(kLineContinuationOffset);
  vector<string> argument_names;
  int argument_number = 0;
  for (const auto& argument : method.input_arguments) {
    auto type = signature.Parse(argument.type);
    CHECK(type);
    string argument_type = type->GetInArgType(DBusType::Receiver::kProxy);
    string argument_name = GetArgName("in", argument.name, ++argument_number);
    argument_names.push_back(argument_name);
    block.AddLine(
        StringPrintf("%s %s,", argument_type.c_str(), argument_name.c_str()));
  }
  vector<string> out_param_names{"response.get()", "error"};
  for (const auto& argument : method.output_arguments) {
    auto type = signature.Parse(argument.type);
    CHECK(type);
    string argument_type = type->GetOutArgType(DBusType::Receiver::kProxy);
    string argument_name = GetArgName("out", argument.name, ++argument_number);
    out_param_names.push_back(argument_name);
    block.AddLine(
        StringPrintf("%s %s,", argument_type.c_str(), argument_name.c_str()));
  }
  block.AddLine("brillo::ErrorPtr* error,");
  block.AddLine(
      StringPrintf("int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)%s",
                   declaration_only ? " = 0;" : " override {"));
  block.PopOffset();
  if (!declaration_only) {
    block.PushOffset(kBlockOffset);

    block.AddLine(
        "auto response = brillo::dbus_utils::CallMethodAndBlockWithTimeout(");
    block.PushOffset(kLineContinuationOffset);
    block.AddLine("timeout_ms,");
    block.AddLine("dbus_object_proxy_,");
    block.AddLine(StringPrintf("\"%s\",", interface_name.c_str()));
    block.AddLine(StringPrintf("\"%s\",", method.name.c_str()));
    string last_argument = "error";
    for (const auto& argument_name : argument_names) {
      block.AddLine(StringPrintf("%s,", last_argument.c_str()));
      last_argument = argument_name;
    }
    block.AddLine(StringPrintf("%s);", last_argument.c_str()));
    block.PopOffset();

    block.AddLine(
        "return response && "
        "brillo::dbus_utils::ExtractMethodCallResults(");
    block.PushOffset(kLineContinuationOffset);
    block.AddLine(base::JoinString(out_param_names, ", ") + ");");
    block.PopOffset();
    block.PopOffset();
    block.AddLine("}");
  }
  text->AddBlock(block);
}

void ProxyGenerator::AddAsyncMethodProxy(const Interface::Method& method,
                                         const string& interface_name,
                                         bool declaration_only,
                                         IndentedText* text) {
  IndentedText block;
  DBusSignature signature;
  block.AddBlankLine();
  block.AddComments(method.doc_string);
  block.AddLine(StringPrintf("%svoid %sAsync(",
                             declaration_only ? "virtual " : "",
                             method.name.c_str()));
  block.PushOffset(kLineContinuationOffset);
  vector<string> argument_names;
  int argument_number = 0;
  for (const auto& argument : method.input_arguments) {
    auto type = signature.Parse(argument.type);
    CHECK(type);
    string argument_type = type->GetInArgType(DBusType::Receiver::kProxy);
    string argument_name = GetArgName("in", argument.name, ++argument_number);
    argument_names.push_back(argument_name);
    block.AddLine(
        StringPrintf("%s %s,", argument_type.c_str(), argument_name.c_str()));
  }
  vector<string> out_params;
  for (const auto& argument : method.output_arguments) {
    auto type = signature.Parse(argument.type);
    CHECK(type);
    string argument_type = type->GetCallbackArgType();
    if (!argument.name.empty())
      base::StringAppendF(&argument_type, " /*%s*/", argument.name.c_str());
    out_params.push_back(argument_type);
  }
  block.AddLine(
      StringPrintf("const base::Callback<void(%s)>& success_callback,",
                   base::JoinString(out_params, ", ").c_str()));
  block.AddLine("const base::Callback<void(brillo::Error*)>& error_callback,");
  block.AddLine(
      StringPrintf("int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)%s",
                   declaration_only ? " = 0;" : " override {"));
  block.PopOffset();
  if (!declaration_only) {
    block.PushOffset(kBlockOffset);

    block.AddLine("brillo::dbus_utils::CallMethodWithTimeout(");
    block.PushOffset(kLineContinuationOffset);
    block.AddLine("timeout_ms,");
    block.AddLine("dbus_object_proxy_,");
    block.AddLine(StringPrintf("\"%s\",", interface_name.c_str()));
    block.AddLine(StringPrintf("\"%s\",", method.name.c_str()));
    block.AddLine("success_callback,");
    string last_argument = "error_callback";
    for (const auto& argument_name : argument_names) {
      block.AddLine(StringPrintf("%s,", last_argument.c_str()));
      last_argument = argument_name;
    }
    block.AddLine(StringPrintf("%s);", last_argument.c_str()));
    block.PopOffset();

    block.PopOffset();
    block.AddLine("}");
  }
  text->AddBlock(block);
}

void ProxyGenerator::AddMethodMock(const Interface::Method& method,
                                   const string& /* interface_name */,
                                   IndentedText* text) {
  DBusSignature signature;
  vector<string> arguments;
  for (const auto& argument : method.input_arguments) {
    auto type = signature.Parse(argument.type);
    CHECK(type);
    string argument_type = type->GetInArgType(DBusType::Receiver::kProxy);
    if (!argument.name.empty())
      base::StringAppendF(&argument_type, " /*in_%s*/", argument.name.c_str());
    arguments.push_back(argument_type);
  }
  for (const auto& argument : method.output_arguments) {
    auto type = signature.Parse(argument.type);
    CHECK(type);
    string argument_type = type->GetOutArgType(DBusType::Receiver::kProxy);
    if (!argument.name.empty())
      base::StringAppendF(&argument_type, " /*out_%s*/", argument.name.c_str());
    arguments.push_back(argument_type);
  }
  arguments.push_back("brillo::ErrorPtr* /*error*/");
  arguments.push_back("int /*timeout_ms*/");
  AddMockMethodDeclaration(method.name, "bool", arguments, text);
}

void ProxyGenerator::AddAsyncMethodMock(const Interface::Method& method,
                                        const string& /* interface_name */,
                                        IndentedText* text) {
  DBusSignature signature;
  vector<string> arguments;
  for (const auto& argument : method.input_arguments) {
    auto type = signature.Parse(argument.type);
    CHECK(type);
    string argument_type = type->GetInArgType(DBusType::Receiver::kProxy);
    if (!argument.name.empty())
      base::StringAppendF(&argument_type, " /*in_%s*/", argument.name.c_str());
    arguments.push_back(argument_type);
  }
  vector<string> out_params;
  for (const auto& argument : method.output_arguments) {
    auto type = signature.Parse(argument.type);
    CHECK(type);
    string argument_type = type->GetCallbackArgType();
    if (!argument.name.empty())
      base::StringAppendF(&argument_type, " /*%s*/", argument.name.c_str());
    out_params.push_back(argument_type);
  }
  arguments.push_back(
      StringPrintf("const base::Callback<void(%s)>& /*success_callback*/",
                   base::JoinString(out_params, ", ").c_str()));
  arguments.push_back(
      "const base::Callback<void(brillo::Error*)>& /*error_callback*/");
  arguments.push_back("int /*timeout_ms*/");
  AddMockMethodDeclaration(method.name + "Async", "void", arguments, text);
}

void ProxyGenerator::AddMockMethodDeclaration(const string& method_name,
                                              const string& return_type,
                                              const vector<string>& arguments,
                                              IndentedText* text) {
  IndentedText block;
  // GMOCK doesn't go all the way up to 11, so we need to handle methods with
  // 11 arguments or more in a different way.
  if (arguments.size() >= 11) {
    block.AddLineAndPushOffsetTo(
        StringPrintf("%s %s(%s,", return_type.c_str(), method_name.c_str(),
                     arguments.front().c_str()),
        1, '(');
    for (size_t i = 1; i < arguments.size() - 1; i++)
      block.AddLine(StringPrintf("%s,", arguments[i].c_str()));
    block.AddLine(StringPrintf("%s) override {", arguments.back().c_str()));
    block.PopOffset();
    block.PushOffset(kBlockOffset);
    block.AddLine(StringPrintf(
        "LOG(WARNING) << \"%s(): gmock can't handle methods with %" PRIuS
        " arguments. You can override this method in a subclass if you need"
        " to.\";",
        method_name.c_str(), arguments.size()));
    if (return_type == "void") {
      // No return added here.
    } else if (return_type == "bool") {
      block.AddLine("return false;");
    } else {
      LOG(FATAL) << "The return type is not supported.";
    }
    block.PopOffset();
    block.AddLine("}");
  } else {
    block.AddLineAndPushOffsetTo(
        StringPrintf("MOCK_METHOD%zu(%s,", arguments.size(),
                     method_name.c_str()),
        1, '(');
    block.AddLineAndPushOffsetTo(
        StringPrintf("%s(%s,", return_type.c_str(), arguments.front().c_str()),
        1, '(');
    for (size_t i = 1; i < arguments.size() - 1; i++)
      block.AddLine(StringPrintf("%s,", arguments[i].c_str()));
    block.AddLine(StringPrintf("%s));", arguments.back().c_str()));
    block.PopOffset();
    block.PopOffset();
  }
  text->AddBlock(block);
}

void ProxyGenerator::AddSignalHandlerRegistrationMock(
    const Interface::Signal& signal, IndentedText* text) {
  IndentedText callback_arg_text;
  IndentedText callback_arg_real;
  AddSignalCallbackArg(signal, true, &callback_arg_text);
  AddSignalCallbackArg(signal, false, &callback_arg_real);
  vector<string> arg_lines = callback_arg_text.GetLines();

  IndentedText wrapperBlock;
  wrapperBlock.AddLine(
      StringPrintf("void Register%sSignalHandler(", signal.name.c_str()));
  wrapperBlock.PushOffset(2);
  wrapperBlock.AddBlock(callback_arg_real);
  wrapperBlock.AddLine(
      "dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {");
  wrapperBlock.PopOffset();
  wrapperBlock.PushOffset(2);
  wrapperBlock.AddLine(StringPrintf(
      "DoRegister%sSignalHandler(signal_callback, &on_connected_callback);",
      signal.name.c_str()));
  wrapperBlock.PopOffset();
  wrapperBlock.AddLine("}");

  IndentedText mockBlock;
  mockBlock.AddLineAndPushOffsetTo(
      StringPrintf("MOCK_METHOD2(DoRegister%sSignalHandler,",
                   signal.name.c_str()),
      1, '(');
  for (size_t i = 0; i < arg_lines.size(); ++i) {
    if (i == 0)
      mockBlock.AddLineAndPushOffsetTo("void(" + arg_lines[i], 1, '(');
    else
      mockBlock.AddLine(arg_lines[i]);
  }
  mockBlock.AddLine(
      "dbus::ObjectProxy::OnConnectedCallback* /*on_connected_callback*/));");

  text->AddBlock(wrapperBlock);
  text->AddBlock(mockBlock);
}

void ProxyGenerator::AddSignalCallbackArg(const Interface::Signal& signal,
                                          bool comment_arg_name,
                                          IndentedText* block) {
  DBusSignature signature;
  string signal_callback =
      StringPrintf("%ssignal_callback%s", comment_arg_name ? "/*" : "",
                   comment_arg_name ? "*/" : "");
  if (signal.arguments.empty()) {
    block->AddLine(
        StringPrintf("const base::Closure& %s,", signal_callback.c_str()));
  } else {
    string last_argument;
    string prefix{"const base::Callback<void("};
    for (const auto& argument : signal.arguments) {
      if (!last_argument.empty()) {
        if (!prefix.empty()) {
          block->AddLineAndPushOffsetTo(
              StringPrintf("%s%s,", prefix.c_str(), last_argument.c_str()), 1,
              '(');
          prefix.clear();
        } else {
          block->AddLine(StringPrintf("%s,", last_argument.c_str()));
        }
      }
      auto type = signature.Parse(argument.type);
      CHECK(type);
      last_argument = type->GetCallbackArgType();
    }
    block->AddLine(StringPrintf("%s%s)>& %s,", prefix.c_str(),
                                last_argument.c_str(),
                                signal_callback.c_str()));
    if (prefix.empty()) {
      block->PopOffset();
    }
  }
}

// static
void ProxyGenerator::ObjectManager::GenerateProxy(
    const ServiceConfig& config,
    const std::vector<Interface>& interfaces,
    IndentedText* text) {
  if (config.object_manager.name.empty())
    return;

  NameParser object_manager{config.object_manager.name};
  object_manager.AddOpenNamespaces(text, false);
  text->AddBlankLine();

  string class_name = object_manager.type_name() + "Proxy";
  text->AddLine(
      StringPrintf("class %s : "
                   "public dbus::ObjectManager::Interface {",
                   class_name.c_str()));
  text->AddLineWithOffset("public:", kScopeOffset);
  text->PushOffset(kBlockOffset);

  AddConstructor(config, class_name, interfaces, text);
  AddDisallowCopyAndAssign(class_name, text);
  text->AddBlankLine();
  AddDestructor(class_name, interfaces, text);
  AddGetObjectManagerProxy(text);
  for (const auto& itf : interfaces) {
    AddInterfaceAccessors(itf, text);
  }
  text->PopOffset();

  text->AddLineWithOffset("private:", kScopeOffset);
  text->PushOffset(kBlockOffset);
  AddOnPropertyChanged(interfaces, text);
  AddObjectAdded(config, interfaces, text);
  AddObjectRemoved(interfaces, text);
  AddCreateProperties(interfaces, class_name, text);
  AddDataMembers(config, interfaces, class_name, text);

  text->PopOffset();
  text->AddLine("};");
  text->AddBlankLine();
  object_manager.AddCloseNamespaces(text, false);
  text->AddBlankLine();
}

// static
void ProxyGenerator::ObjectManager::AddConstructor(
    const ServiceConfig& config,
    const std::string& class_name,
    const std::vector<Interface>& interfaces,
    IndentedText* text) {
  if (config.service_name.empty()) {
    text->AddLineAndPushOffsetTo(
        StringPrintf("%s(const scoped_refptr<dbus::Bus>& bus,",
                     class_name.c_str()),
        1, '(');
    text->AddLine("const std::string& service_name)");
    text->PopOffset();
  } else {
    text->AddLine(StringPrintf("%s(const scoped_refptr<dbus::Bus>& bus)",
                               class_name.c_str()));
  }
  text->PushOffset(kLineContinuationOffset);
  text->AddLine(": bus_{bus},");
  text->PushOffset(kBlockOffset);
  if (config.service_name.empty()) {
    text->AddLine("service_name_{service_name},");
  }
  text->AddLine("dbus_object_manager_{bus->GetObjectManager(");
  text->PushOffset(kLineContinuationOffset);
  if (config.service_name.empty()) {
    text->AddLine("service_name,");
  } else {
    text->AddLine(StringPrintf("\"%s\",", config.service_name.c_str()));
  }
  text->AddLine(StringPrintf("dbus::ObjectPath{\"%s\"})} {",
                             config.object_manager.object_path.c_str()));
  text->PopOffset();
  text->PopOffset();
  text->PopOffset();
  text->PushOffset(kBlockOffset);
  for (const auto& itf : interfaces) {
    text->AddLine(
        StringPrintf("dbus_object_manager_->RegisterInterface(\"%s\", this);",
                     itf.name.c_str()));
  }
  text->PopOffset();
  text->AddLine("}");
  text->AddBlankLine();
}

// static
void ProxyGenerator::ObjectManager::AddDestructor(
    const std::string& class_name,
    const std::vector<Interface>& interfaces,
    IndentedText* text) {
  text->AddLine(StringPrintf("~%s() override {", class_name.c_str()));
  text->PushOffset(kBlockOffset);
  for (const auto& itf : interfaces) {
    text->AddLine(
        StringPrintf("dbus_object_manager_->UnregisterInterface(\"%s\");",
                     itf.name.c_str()));
  }
  text->PopOffset();
  text->AddLine("}");
  text->AddBlankLine();
}

// static
void ProxyGenerator::ObjectManager::AddGetObjectManagerProxy(
    IndentedText* text) {
  text->AddLine("dbus::ObjectManager* GetObjectManagerProxy() const {");
  text->AddLineWithOffset("return dbus_object_manager_;", kBlockOffset);
  text->AddLine("}");
  text->AddBlankLine();
}

// static
void ProxyGenerator::ObjectManager::AddInterfaceAccessors(
    const Interface& interface, IndentedText* text) {
  NameParser itf_name{interface.name};
  string map_name = itf_name.MakeVariableName() + "_instances_";

  // GetProxy().
  if (interface.path.empty()) {
    // We have no fixed path, so there could be multiple instances of this itf.
    text->AddLine(StringPrintf("%sInterface* Get%s(",
                               itf_name.MakeProxyName(true).c_str(),
                               itf_name.MakeProxyName(false).c_str()));
    text->PushOffset(kLineContinuationOffset);
    text->AddLine("const dbus::ObjectPath& object_path) {");
    text->PopOffset();
    text->PushOffset(kBlockOffset);
    text->AddLine(
        StringPrintf("auto p = %s.find(object_path);", map_name.c_str()));
    text->AddLine(StringPrintf("if (p != %s.end())", map_name.c_str()));
    text->PushOffset(kBlockOffset);
    text->AddLine("return p->second.get();");
    text->PopOffset();
    text->AddLine("return nullptr;");
    text->PopOffset();
    text->AddLine("}");
  } else {
    // We have a fixed path, so the object could be considered a "singleton".
    // Skip the object_path parameter and return the first available instance.
    text->AddLine(StringPrintf("%sInterface* Get%s() {",
                               itf_name.MakeProxyName(true).c_str(),
                               itf_name.MakeProxyName(false).c_str()));
    text->PushOffset(kBlockOffset);
    text->AddLine(StringPrintf("if (%s.empty())", map_name.c_str()));
    text->AddLineWithOffset("return nullptr;", kBlockOffset);
    text->AddLine(
        StringPrintf("return %s.begin()->second.get();", map_name.c_str()));
    text->PopOffset();
    text->AddLine("}");
  }

  // GetInstances().
  text->AddLine(StringPrintf(
      "std::vector<%sInterface*> Get%sInstances() const {",
      itf_name.MakeProxyName(true).c_str(), itf_name.type_name().c_str()));
  text->PushOffset(kBlockOffset);
  text->AddLine(StringPrintf("std::vector<%sInterface*> values;",
                             itf_name.MakeProxyName(true).c_str()));
  text->AddLine(StringPrintf("values.reserve(%s.size());", map_name.c_str()));
  text->AddLine(StringPrintf("for (const auto& pair : %s)", map_name.c_str()));
  text->AddLineWithOffset("values.push_back(pair.second.get());", kBlockOffset);
  text->AddLine("return values;");
  text->PopOffset();
  text->AddLine("}");

  // SetAddedCallback().
  text->AddLine(
      StringPrintf("void Set%sAddedCallback(", itf_name.type_name().c_str()));
  text->PushOffset(kLineContinuationOffset);
  text->AddLine(
      StringPrintf("const base::Callback<void(%sInterface*)>& callback) {",
                   itf_name.MakeProxyName(true).c_str()));
  text->PopOffset();
  text->PushOffset(kBlockOffset);
  text->AddLine(StringPrintf("on_%s_added_ = callback;",
                             itf_name.MakeVariableName().c_str()));
  text->PopOffset();
  text->AddLine("}");

  // SetRemovedCallback().
  text->AddLine(
      StringPrintf("void Set%sRemovedCallback(", itf_name.type_name().c_str()));
  text->PushOffset(kLineContinuationOffset);
  text->AddLine(
      "const base::Callback<void(const dbus::ObjectPath&)>& "
      "callback) {");
  text->PopOffset();
  text->PushOffset(kBlockOffset);
  text->AddLine(StringPrintf("on_%s_removed_ = callback;",
                             itf_name.MakeVariableName().c_str()));
  text->PopOffset();
  text->AddLine("}");

  text->AddBlankLine();
}

// static
void ProxyGenerator::ObjectManager::AddOnPropertyChanged(
    const std::vector<Interface>& interfaces, IndentedText* text) {
  // If there are no interfaces with properties, comment out parameter
  // names for OnPropertyChanged() to prevent compiler warnings on unused
  // function parameters.
  auto has_props = [](const Interface& itf) { return !itf.properties.empty(); };
  auto itf_with_props =
      std::find_if(interfaces.begin(), interfaces.end(), has_props);
  if (itf_with_props == interfaces.end()) {
    text->AddLineAndPushOffsetTo(
        "void OnPropertyChanged("
        "const dbus::ObjectPath& /* object_path */,",
        1, '(');
    text->AddLine("const std::string& /* interface_name */,");
    text->AddLine("const std::string& /* property_name */) {}");
    text->PopOffset();
    text->AddBlankLine();
    return;
  }
  text->AddLineAndPushOffsetTo(
      "void OnPropertyChanged("
      "const dbus::ObjectPath& object_path,",
      1, '(');
  text->AddLine("const std::string& interface_name,");
  text->AddLine("const std::string& property_name) {");
  text->PopOffset();
  text->PushOffset(kBlockOffset);
  for (const auto& itf : interfaces) {
    if (itf.properties.empty())
      continue;

    NameParser itf_name{itf.name};
    text->AddLine(
        StringPrintf("if (interface_name == \"%s\") {", itf.name.c_str()));
    text->PushOffset(kBlockOffset);
    string map_name = itf_name.MakeVariableName() + "_instances_";
    text->AddLine(
        StringPrintf("auto p = %s.find(object_path);", map_name.c_str()));
    text->AddLine(StringPrintf("if (p == %s.end())", map_name.c_str()));
    text->PushOffset(kBlockOffset);
    text->AddLine("return;");
    text->PopOffset();
    text->AddLine("p->second->OnPropertyChanged(property_name);");
    text->AddLine("return;");
    text->PopOffset();
    text->AddLine("}");
  }
  text->PopOffset();
  text->AddLine("}");
  text->AddBlankLine();
}

// static
void ProxyGenerator::ObjectManager::AddObjectAdded(
    const ServiceConfig& config,
    const std::vector<Interface>& interfaces,
    IndentedText* text) {
  text->AddLine("void ObjectAdded(");
  text->PushOffset(kLineContinuationOffset);
  text->AddLine("const dbus::ObjectPath& object_path,");
  text->AddLine("const std::string& interface_name) override {");
  text->PopOffset();
  text->PushOffset(kBlockOffset);
  for (const auto& itf : interfaces) {
    NameParser itf_name{itf.name};
    string var_name = itf_name.MakeVariableName();
    text->AddLine(
        StringPrintf("if (interface_name == \"%s\") {", itf.name.c_str()));
    text->PushOffset(kBlockOffset);
    if (!itf.properties.empty()) {
      text->AddLine("auto property_set =");
      text->PushOffset(kLineContinuationOffset);
      text->AddLine(StringPrintf("static_cast<%s::PropertySet*>(",
                                 itf_name.MakeProxyName(true).c_str()));
      text->PushOffset(kLineContinuationOffset);
      text->AddLine(
          "dbus_object_manager_->GetProperties(object_path, "
          "interface_name));");
      text->PopOffset();
      text->PopOffset();
    }
    text->AddLine(StringPrintf("std::unique_ptr<%s> %s_proxy{",
                               itf_name.MakeProxyName(true).c_str(),
                               var_name.c_str()));
    text->PushOffset(kBlockOffset);
    string new_instance =
        StringPrintf("new %s{bus_", itf_name.MakeProxyName(true).c_str());
    if (config.service_name.empty()) {
      new_instance += ", service_name_";
    }
    if (itf.path.empty())
      new_instance += ", object_path";
    if (!itf.properties.empty())
      new_instance += ", property_set";
    new_instance += "}";
    text->AddLine(new_instance);
    text->PopOffset();
    text->AddLine("};");
    text->AddLine(
        StringPrintf("auto p = %s_instances_.emplace(object_path, "
                     "std::move(%s_proxy));",
                     var_name.c_str(), var_name.c_str()));
    text->AddLine(
        StringPrintf("if (!on_%s_added_.is_null())", var_name.c_str()));
    text->PushOffset(kBlockOffset);
    text->AddLine(StringPrintf("on_%s_added_.Run(p.first->second.get());",
                               var_name.c_str()));
    text->PopOffset();
    text->AddLine("return;");
    text->PopOffset();
    text->AddLine("}");
  }
  text->PopOffset();
  text->AddLine("}");
  text->AddBlankLine();
}

// static
void ProxyGenerator::ObjectManager::AddObjectRemoved(
    const std::vector<Interface>& interfaces, IndentedText* text) {
  text->AddLine("void ObjectRemoved(");
  text->PushOffset(kLineContinuationOffset);
  text->AddLine("const dbus::ObjectPath& object_path,");
  text->AddLine("const std::string& interface_name) override {");
  text->PopOffset();
  text->PushOffset(kBlockOffset);
  for (const auto& itf : interfaces) {
    NameParser itf_name{itf.name};
    string var_name = itf_name.MakeVariableName();
    text->AddLine(
        StringPrintf("if (interface_name == \"%s\") {", itf.name.c_str()));
    text->PushOffset(kBlockOffset);
    text->AddLine(StringPrintf("auto p = %s_instances_.find(object_path);",
                               var_name.c_str()));
    text->AddLine(
        StringPrintf("if (p != %s_instances_.end()) {", var_name.c_str()));
    text->PushOffset(kBlockOffset);
    text->AddLine(
        StringPrintf("if (!on_%s_removed_.is_null())", var_name.c_str()));
    text->PushOffset(kBlockOffset);
    text->AddLine(
        StringPrintf("on_%s_removed_.Run(object_path);", var_name.c_str()));
    text->PopOffset();
    text->AddLine(StringPrintf("%s_instances_.erase(p);", var_name.c_str()));
    text->PopOffset();
    text->AddLine("}");
    text->AddLine("return;");
    text->PopOffset();
    text->AddLine("}");
  }
  text->PopOffset();
  text->AddLine("}");
  text->AddBlankLine();
}

// static
void ProxyGenerator::ObjectManager::AddCreateProperties(
    const std::vector<Interface>& interfaces,
    const std::string& class_name,
    IndentedText* text) {
  text->AddLine("dbus::PropertySet* CreateProperties(");
  text->PushOffset(kLineContinuationOffset);
  text->AddLine("dbus::ObjectProxy* object_proxy,");
  text->AddLine("const dbus::ObjectPath& object_path,");
  text->AddLine("const std::string& interface_name) override {");
  text->PopOffset();
  text->PushOffset(kBlockOffset);
  for (const auto& itf : interfaces) {
    NameParser itf_name{itf.name};
    text->AddLine(
        StringPrintf("if (interface_name == \"%s\") {", itf.name.c_str()));
    text->PushOffset(kBlockOffset);
    text->AddLine(StringPrintf("return new %s::PropertySet{",
                               itf_name.MakeProxyName(true).c_str()));
    text->PushOffset(kLineContinuationOffset);
    text->AddLine("object_proxy,");
    text->AddLineAndPushOffsetTo(
        StringPrintf("base::Bind(&%s::OnPropertyChanged,", class_name.c_str()),
        1, '(');
    text->AddLine("weak_ptr_factory_.GetWeakPtr(),");
    text->AddLine("object_path,");
    text->AddLine("interface_name)");
    text->PopOffset();
    text->PopOffset();
    text->AddLine("};");
    text->PopOffset();
    text->AddLine("}");
  }
  text->AddLineAndPushOffsetTo(
      "LOG(FATAL) << \"Creating properties for "
      "unsupported interface \"",
      1, ' ');
  text->AddLine("<< interface_name;");
  text->PopOffset();
  text->AddLine("return nullptr;");
  text->PopOffset();
  text->AddLine("}");
  text->AddBlankLine();
}

// static
void ProxyGenerator::ObjectManager::AddDataMembers(
    const ServiceConfig& config,
    const std::vector<Interface>& interfaces,
    const std::string& class_name,
    IndentedText* text) {
  text->AddLine("scoped_refptr<dbus::Bus> bus_;");
  if (config.service_name.empty()) {
    text->AddLine("std::string service_name_;");
  }
  text->AddLine("dbus::ObjectManager* dbus_object_manager_;");
  for (const auto& itf : interfaces) {
    NameParser itf_name{itf.name};
    string var_name = itf_name.MakeVariableName();
    text->AddLineAndPushOffsetTo("std::map<dbus::ObjectPath,", 1, '<');
    text->AddLine(StringPrintf("std::unique_ptr<%s>> %s_instances_;",
                               itf_name.MakeProxyName(true).c_str(),
                               var_name.c_str()));
    text->PopOffset();
    text->AddLine(
        StringPrintf("base::Callback<void(%sInterface*)> on_%s_added_;",
                     itf_name.MakeProxyName(true).c_str(), var_name.c_str()));
    text->AddLine(
        StringPrintf("base::Callback<void(const dbus::ObjectPath&)> "
                     "on_%s_removed_;",
                     var_name.c_str()));
  }
  text->AddLine(StringPrintf(
      "base::WeakPtrFactory<%s> weak_ptr_factory_{this};", class_name.c_str()));
}

string ProxyGenerator::GetHandlerNameForSignal(const string& signal) {
  return StringPrintf("On%sSignal", signal.c_str());
}

}  // namespace chromeos_dbus_bindings
