14a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart// Copyright 2014 The Chromium OS Authors. All rights reserved.
24a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart// Use of this source code is governed by a BSD-style license that can be
34a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart// found in the LICENSE file.
44a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart
56ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko#include <memory>
64a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart#include <string>
74a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart
84a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart#include <base/command_line.h>
92b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart#include <base/files/file_path.h>
106ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko#include <base/files/file_util.h>
116ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko#include <base/json/json_reader.h>
124a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart#include <base/logging.h>
13c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko#include <base/strings/string_util.h>
146ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko#include <base/values.h>
15be6240db3b8a0981ce0f800247105154ff8e4960Alex Vakulenko#include <brillo/syslog_logging.h>
164a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart
17b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart#include "chromeos-dbus-bindings/adaptor_generator.h"
18154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart#include "chromeos-dbus-bindings/method_name_generator.h"
191dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart#include "chromeos-dbus-bindings/proxy_generator.h"
202b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart#include "chromeos-dbus-bindings/xml_interface_parser.h"
212b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart
22fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenkousing chromeos_dbus_bindings::AdaptorGenerator;
23fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenkousing chromeos_dbus_bindings::MethodNameGenerator;
24fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenkousing chromeos_dbus_bindings::ProxyGenerator;
256ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkousing chromeos_dbus_bindings::ServiceConfig;
26fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenko
274a4c706fa989e4643cb5b3d675656586b42d895Paul Stewartnamespace switches {
284a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart
294a4c706fa989e4643cb5b3d675656586b42d895Paul Stewartstatic const char kHelp[] = "help";
30154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewartstatic const char kMethodNames[] = "method-names";
31b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewartstatic const char kAdaptor[] = "adaptor";
321dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewartstatic const char kProxy[] = "proxy";
33008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenkostatic const char kMock[] = "mock";
34a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wileystatic const char kProxyPathForMocks[] = "proxy-path-in-mocks";
356ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkostatic const char kServiceConfig[] = "service-config";
364a4c706fa989e4643cb5b3d675656586b42d895Paul Stewartstatic const char kHelpMessage[] = "\n"
37c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko    "generate-chromeos-dbus-bindings itf1.xml [itf2.xml...] [switches]\n"
38c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko    "    itf1.xml, ... = the input interface file(s) [mandatory].\n"
394a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart    "Available Switches: \n"
40154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart    "  --method-names=<method name header filename>\n"
41b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart    "    The output header file with string constants for each method name.\n"
42b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart    "  --adaptor=<adaptor header filename>\n"
431dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart    "    The output header file name containing the DBus adaptor class.\n"
441dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart    "  --proxy=<proxy header filename>\n"
456ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    "    The output header file name containing the DBus proxy class.\n"
46008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko    "  --mock=<mock header filename>\n"
47008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko    "    The output header file name containing the DBus proxy mock class.\n"
486ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    "  --service-config=<config.json>\n"
496ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    "    The DBus service configuration file for the generator.\n";
504a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart
514a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart}  // namespace switches
524a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart
536ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkonamespace {
546ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// GYP sometimes enclosed the target file name in extra set of quotes like:
556ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko//    generate-chromeos-dbus-bindings in.xml "--adaptor=\"out.h\""
566ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// So, this function helps us to remove them.
576ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkobase::FilePath RemoveQuotes(const std::string& path) {
586ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  std::string unquoted;
596ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  base::TrimString(path, "\"'", &unquoted);
606ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  return base::FilePath{unquoted};
616ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko}
626ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko
636ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// Makes a canonical path by making the path absolute and by removing any
646ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// '..' which makes base::ReadFileToString() to fail.
656ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkobase::FilePath SanitizeFilePath(const std::string& path) {
666ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  base::FilePath path_in = RemoveQuotes(path);
676ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  base::FilePath path_out = base::MakeAbsoluteFilePath(path_in);
686ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  if (path_out.value().empty()) {
696ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    LOG(WARNING) << "Failed to canonicalize '" << path << "'";
706ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    path_out = path_in;
716ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  }
726ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  return path_out;
736ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko}
746ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko
756ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko
766ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko// Load the service configuration from the provided JSON file.
776ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenkobool LoadConfig(const base::FilePath& path, ServiceConfig *config) {
786ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  std::string contents;
796ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  if (!base::ReadFileToString(path, &contents))
806ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    return false;
816ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko
820bd7dd71a61171d9609ecc7722e8fd87e0afdda2Alex Vakulenko  std::unique_ptr<base::Value> json{base::JSONReader::Read(contents).release()};
836ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  if (!json)
846ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    return false;
856ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko
866ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  base::DictionaryValue* dict = nullptr;  // Aliased with |json|.
876ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  if (!json->GetAsDictionary(&dict))
886ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    return false;
896ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko
906ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  dict->GetStringWithoutPathExpansion("service_name", &config->service_name);
9199e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko
9299e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko  base::DictionaryValue* om_dict = nullptr;  // Owned by |dict|.
9399e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko  if (dict->GetDictionaryWithoutPathExpansion("object_manager", &om_dict)) {
9499e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko    if (!om_dict->GetStringWithoutPathExpansion("name",
9599e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko                                                &config->object_manager.name) &&
9699e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko        !config->service_name.empty()) {
9799e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko      config->object_manager.name = config->service_name + ".ObjectManager";
9899e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko    }
9999e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko    om_dict->GetStringWithoutPathExpansion("object_path",
10099e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko                                           &config->object_manager.object_path);
101e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko    if (config->object_manager.name.empty()) {
102e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko      LOG(ERROR) << "Object manager name is missing.";
103e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko      return false;
104e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko    }
105e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko  }
106e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko
107e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko  base::ListValue* list = nullptr;  // Owned by |dict|.
108e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko  if (dict->GetListWithoutPathExpansion("ignore_interfaces", &list)) {
109e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko    config->ignore_interfaces.reserve(list->GetSize());
110e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko    for (base::Value* item : *list) {
111e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko      std::string interface_name;
112e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko      if (!item->GetAsString(&interface_name)) {
113e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko        LOG(ERROR) << "Invalid interface name in [ignore_interfaces] section";
114e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko        return false;
115e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko      }
116e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko      config->ignore_interfaces.push_back(interface_name);
117e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko    }
11899e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko  }
11999e8fb04c1176e856026f14fd9ffc04b66115e0cAlex Vakulenko
1206ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko  return true;
1216ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko}
1226ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko
1236ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko}   // anonymous namespace
1246ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko
1254a4c706fa989e4643cb5b3d675656586b42d895Paul Stewartint main(int argc, char** argv) {
126b000aae2c03cc3fa6980f57993a52a81363b3518Alex Vakulenko  base::CommandLine::Init(argc, argv);
127b000aae2c03cc3fa6980f57993a52a81363b3518Alex Vakulenko  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
1284a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart
129cc0b8b16d1e2b5d286ef2bad41be978fa4a887efAlex Deymo  // Setup logging to stderr. This also parses some implicit flags using the
130cc0b8b16d1e2b5d286ef2bad41be978fa4a887efAlex Deymo  // CommandLine singleton.
131be6240db3b8a0981ce0f800247105154ff8e4960Alex Vakulenko  brillo::InitLog(brillo::kLogToStderr | brillo::kLogHeader);
132cc0b8b16d1e2b5d286ef2bad41be978fa4a887efAlex Deymo
1334a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart  if (cl->HasSwitch(switches::kHelp)) {
1344a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart    LOG(INFO) << switches::kHelpMessage;
1354a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart    return 0;
1364a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart  }
1374a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart
138c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko  auto input_files = cl->GetArgs();
139c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko  if (input_files.empty()) {
140c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko    LOG(ERROR) << "At least one file must be specified.";
1414a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart    LOG(ERROR) << switches::kHelpMessage;
1424a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart    return 1;
1434a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart  }
1444a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart
145e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko  ServiceConfig config;
146e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko  if (cl->HasSwitch(switches::kServiceConfig)) {
147e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko    std::string config_file = cl->GetSwitchValueASCII(switches::kServiceConfig);
148e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko    if (!config_file.empty() &&
149e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko        !LoadConfig(SanitizeFilePath(config_file), &config)) {
150e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko      LOG(ERROR) << "Failed to load DBus service config file " << config_file;
151e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko      return 1;
152e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko    }
153e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko  }
154e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko
1552b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart  chromeos_dbus_bindings::XmlInterfaceParser parser;
156c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko  for (const auto& input : input_files) {
1576ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    std::string contents;
1586ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    if (!base::ReadFileToString(SanitizeFilePath(input), &contents)) {
1596ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko      LOG(ERROR) << "Failed to read file " << input;
1606ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko      return 1;
1616ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    }
162e2a3338c9b7a772c2e7a2ab7d41551262f00cfebAlex Vakulenko    if (!parser.ParseXmlInterfaceFile(contents, config.ignore_interfaces)) {
163824b5246a3ab5c70d32938ed9c3b982f5624dfe9Christopher Wiley      LOG(ERROR) << "Failed to parse interface file " << input;
164c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko      return 1;
165c95f06bd6f672f408c5f77948781392098f52a86Alex Vakulenko    }
1662b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart  }
1672b1c6124a7c74225e231132a68e1a92723a26da9Paul Stewart
168b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart  if (cl->HasSwitch(switches::kMethodNames)) {
169154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart    std::string method_name_file =
170154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart        cl->GetSwitchValueASCII(switches::kMethodNames);
171cc0b8b16d1e2b5d286ef2bad41be978fa4a887efAlex Deymo    VLOG(1) << "Outputting method names to " << method_name_file;
172fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenko    if (!MethodNameGenerator::GenerateMethodNames(
173fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenko            parser.interfaces(),
1746ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko            RemoveQuotes(method_name_file))) {
175154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart      LOG(ERROR) << "Failed to output method names.";
176154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart      return 1;
177fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenko    }
178154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart  }
179154cad5f50f22e473237bb2ead8b5789180cfe2fPaul Stewart
180b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart  if (cl->HasSwitch(switches::kAdaptor)) {
181b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart    std::string adaptor_file = cl->GetSwitchValueASCII(switches::kAdaptor);
182cc0b8b16d1e2b5d286ef2bad41be978fa4a887efAlex Deymo    VLOG(1) << "Outputting adaptor to " << adaptor_file;
183fafef1300f94cada37c4fac0e0c7ba46aeee5ad1Alex Vakulenko    if (!AdaptorGenerator::GenerateAdaptors(parser.interfaces(),
1846ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko                                            RemoveQuotes(adaptor_file))) {
185b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart      LOG(ERROR) << "Failed to output adaptor.";
186b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart      return 1;
187b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart     }
188b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart  }
189b9b3f9d3654f15b221f47f5f24bd874102a27ed2Paul Stewart
190008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko  base::FilePath proxy_path;  // Used by both Proxy and Mock generation.
1911dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart  if (cl->HasSwitch(switches::kProxy)) {
1921dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart    std::string proxy_file = cl->GetSwitchValueASCII(switches::kProxy);
193008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko    proxy_path = RemoveQuotes(proxy_file);
194008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko    base::NormalizeFilePath(proxy_path, &proxy_path);
195008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko    VLOG(1) << "Outputting proxy to " << proxy_path.value();
1966ef2d737ce25f4c0debcf87d5f5909289ce15adfAlex Vakulenko    if (!ProxyGenerator::GenerateProxies(config, parser.interfaces(),
197008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko                                         proxy_path)) {
1981dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart      LOG(ERROR) << "Failed to output proxy.";
1991dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart      return 1;
2001dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart     }
2011dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart  }
2021dce1ae6ca266668e37d6bc4009692bbc12e2bb6Paul Stewart
203a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley  base::FilePath proxy_include_path = proxy_path;
204a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley  bool use_literal_include_path = false;
205a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley  if (cl->HasSwitch(switches::kProxyPathForMocks)) {
206a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley    std::string proxy_file_in_mocks =
207a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley        cl->GetSwitchValueASCII(switches::kProxyPathForMocks);
208a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley    proxy_include_path = RemoveQuotes(proxy_file_in_mocks);
209a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley    use_literal_include_path = true;
210a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley  }
211a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley
212008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko  if (cl->HasSwitch(switches::kMock)) {
213008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko    std::string mock_file = cl->GetSwitchValueASCII(switches::kMock);
214008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko    base::FilePath mock_path = RemoveQuotes(mock_file);
215008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko    base::NormalizeFilePath(mock_path, &mock_path);
216008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko    VLOG(1) << "Outputting mock to " << mock_path.value();
217008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko    if (!ProxyGenerator::GenerateMocks(config, parser.interfaces(), mock_path,
218a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley                                       proxy_include_path,
219a30e09dde8bde67a44a2275b58d3f9d058207e57Christopher Wiley                                       use_literal_include_path)) {
220008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko      LOG(ERROR) << "Failed to output mock.";
221008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko      return 1;
222008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko     }
223008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko  }
224008e19dd69bfc8439454a14df159b5a829881956Alex Vakulenko
2254a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart  return 0;
2264a4c706fa989e4643cb5b3d675656586b42d895Paul Stewart}
227