// 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/stringprintf.h>
#include <brillo/strings/string_utils.h>

#include "chromeos-dbus-bindings/dbus_signature.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

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

// static
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<base::FilePath::StringType> src_components;
      mock_file.DirName().GetComponents(&src_components);
      std::vector<base::FilePath::StringType> dest_components;
      proxy_file.DirName().GetComponents(&dest_components);

      // Find the common root.

      // I wish we had C++14 and its 4-parameter version of std::mismatch()...
      auto src_end = src_components.end();
      if (src_components.size() > dest_components.size())
        src_end = src_components.begin() + dest_components.size();

      auto mismatch_pair = std::mismatch(src_components.begin(), src_end,
                                         dest_components.begin());

      // 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<base::FilePath::StringType> 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);
}

// static
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;");
  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();
}

// static
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();
}

// static
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) {
    string type;
    CHECK(signature.Parse(prop.type, &type));
    MakeConstReferenceIfNeeded(&type);
    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&());");
  if (!config.object_manager.name.empty() && !interface.properties.empty()) {
    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();
}

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

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

// static
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("}");
}

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

// static
void ProxyGenerator::AddGetObjectProxy(IndentedText* text) {
  text->AddBlankLine();
  text->AddLine("dbus::ObjectProxy* GetObjectProxy() const { "
                "return dbus_object_proxy_; }");
}

// static
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("}");
  }
}

// static
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("}");
  }
}

// static
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_); }");
}

// static
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("on_connected_callback);");
    block.PopOffset();  // Function call line continuation
    block.PopOffset();  // Method body
    block.AddLine("}");
  }
  text->AddBlock(block);
}

// static
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) {
    string type;
    CHECK(signature.Parse(prop.type, &type));
    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);
}

// static
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()));
    }
    string type;
    CHECK(signature.Parse(prop.type, &type));
    MakeConstReferenceIfNeeded(&type);
    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("}");
      }
    }
  }
}

// static
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) {
    string argument_type;
    CHECK(signature.Parse(argument.type, &argument_type));
    MakeConstReferenceIfNeeded(&argument_type);
    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) {
    string argument_type;
    CHECK(signature.Parse(argument.type, &argument_type));
    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(brillo::string_utils::Join(", ", out_param_names) + ");");
    block.PopOffset();
    block.PopOffset();
    block.AddLine("}");
  }
  text->AddBlock(block);
}

// static
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) {
    string argument_type;
    CHECK(signature.Parse(argument.type, &argument_type));
    MakeConstReferenceIfNeeded(&argument_type);
    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) {
    string argument_type;
    CHECK(signature.Parse(argument.type, &argument_type));
    MakeConstReferenceIfNeeded(&argument_type);
    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,",
      brillo::string_utils::Join(", ", 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);
}

// static
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) {
    string argument_type;
    CHECK(signature.Parse(argument.type, &argument_type));
    MakeConstReferenceIfNeeded(&argument_type);
    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) {
    string argument_type;
    CHECK(signature.Parse(argument.type, &argument_type));
    argument_type += '*';
    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);
}

// static
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) {
    string argument_type;
    CHECK(signature.Parse(argument.type, &argument_type));
    MakeConstReferenceIfNeeded(&argument_type);
    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) {
    string argument_type;
    CHECK(signature.Parse(argument.type, &argument_type));
    MakeConstReferenceIfNeeded(&argument_type);
    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*/",
      brillo::string_utils::Join(", ", 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);
}

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

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

// static
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()));
        }
      }
      CHECK(signature.Parse(argument.type, &last_argument));
      MakeConstReferenceIfNeeded(&last_argument);
    }
    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();
}

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();
}

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();
}

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

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();
}

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();
}

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();
}

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();
}

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();
}

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();
}

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

}  // namespace chromeos_dbus_bindings
