// 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/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);
  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->AddLine(StringPrintf("DISALLOW_COPY_AND_ASSIGN(%s);",
                             proxy_name.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()));
  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->AddBlankLine();
  text->AddLineWithOffset("private:", kScopeOffset);
  text->AddLineWithOffset(StringPrintf("DISALLOW_COPY_AND_ASSIGN(%s);",
                                       mock_name.c_str()),
                          kBlockOffset);
  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("}");
  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.AddLineWithOffset("private:", kScopeOffset);
  block.AddLineWithOffset("DISALLOW_COPY_AND_ASSIGN(PropertySet);",
                          kBlockOffset);
  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);
  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->AddLine(StringPrintf("DISALLOW_COPY_AND_ASSIGN(%s);",
                              class_name.c_str()));
  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()));
  text->AddBlankLine();
}

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

}  // namespace chromeos_dbus_bindings
