blob: ffa1cde75b6486dc67975fc2f85abd1da12b0a0a [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Copied and modified from
// https://chromium.googlesource.com/chromium/src/+/a3f9d4fac81fc86065d867ab08fa4912ddf662c7/headless/lib/browser/devtools_api/domain_cc.template
// Modifications include namespace and path.
#include "components/autofill_assistant/browser/devtools/devtools/domains/{{domain.domain | camelcase_to_hacker_style}}.h"
#include "base/bind.h"
#include "components/autofill_assistant/browser/devtools/error_reporter.h"
namespace autofill_assistant {
namespace {{domain.domain | camelcase_to_hacker_style}} {
ExperimentalDomain* Domain::GetExperimental() {
return static_cast<ExperimentalDomain*>(this);
}
{% if "events" in domain %}
void Domain::AddObserver(Observer* observer) {
RegisterEventHandlersIfNeeded();
observers_.AddObserver(observer);
}
void Domain::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
void Domain::RegisterEventHandlersIfNeeded() {
if (event_handlers_registered_)
return;
event_handlers_registered_ = true;
{# Register all events in this domain. #}
{% for event in domain.events %}
dispatcher_->RegisterEventHandler(
"{{domain.domain}}.{{event.name}}",
base::BindRepeating(&Domain::Dispatch{{event.name | to_title_case}}Event,
base::Unretained(this)));
{% endfor %}
}
{% endif %}
{% for command in domain.commands %}
{% set class_name = 'ExperimentalDomain' if command.experimental else 'Domain' %}
{% set method_name = command.name | sanitize_literal | to_title_case %}
void {{class_name}}::{{method_name}}(
std::unique_ptr<{{method_name}}Params> params,
base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)> callback) {
dispatcher_->SendMessage("{{domain.domain}}.{{command.name}}", params->Serialize(), base::BindOnce(&Domain::Handle{{method_name}}Response, std::move(callback)));
}
{# Generate convenience methods that take the required parameters directly. #}
{% if not "parameters" in command %}{% continue %}{% endif %}
{# Don't generate these for experimental commands. #}
{% if command.experimental %}{% continue %}{% endif %}
void {{class_name}}::{{method_name}}({##}
{% for parameter in command.parameters -%}
{% if parameter.get("optional", False) -%}
{% break %}
{% endif %}
{% if not loop.first %}, {% endif %}
{{resolve_type(parameter).pass_type}} {{parameter.name | camelcase_to_hacker_style -}}
{% endfor %}
{% if command.get("parameters", []) and not command.parameters[0].get("optional", False) %}, {% endif %}{# -#}
{% if command.get("returns", []) -%}
base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)> callback{##}
{% else -%}
base::OnceClosure callback{##}
{% endif %}) {
{# Build the parameters object. #}
std::unique_ptr<{{method_name}}Params> params = {{method_name}}Params::Builder()
{% for parameter in command.parameters -%}
{% if parameter.get("optional", False) -%}
{% break %}
{% endif %}
.Set{{parameter.name | to_title_case}}(std::move({{parameter.name | camelcase_to_hacker_style}}))
{% endfor %}
.Build();
{# Send the message. #}
{% if command.get("returns", []) -%}
dispatcher_->SendMessage("{{domain.domain}}.{{command.name}}", params->Serialize(), base::BindOnce(&Domain::Handle{{method_name}}Response, std::move(callback)));
{% else %}
dispatcher_->SendMessage("{{domain.domain}}.{{command.name}}", params->Serialize(), std::move(callback));
{% endif %}
}
{# If the command has no return value, generate a convenience method that #}
{# accepts a base::OnceClosure together with the parameters object. #}
{% if not command.get("returns", []) %}
void {{class_name}}::{{method_name}}(std::unique_ptr<{{method_name}}Params> params, base::OnceClosure callback) {
dispatcher_->SendMessage("{{domain.domain}}.{{command.name}}", params->Serialize(), std::move(callback));
}
{% endif %}
{% endfor %}
{# Generate response handlers for commands that need them. #}
{% for command in domain.commands %}
{% if not "returns" in command %}{% continue %}{% endif %}
{% set method_name = command.name | sanitize_literal | to_title_case %}
// static
void Domain::Handle{{method_name}}Response(
base::OnceCallback<void(const MessageDispatcher::ReplyStatus&, std::unique_ptr<{{method_name}}Result>)> callback,
const MessageDispatcher::ReplyStatus& reply_status,
const base::Value& response) {
if (callback.is_null())
return;
// This is an error response.
if (response.is_none()) {
std::move(callback).Run(reply_status, nullptr);
return;
}
ErrorReporter errors;
std::unique_ptr<{{method_name}}Result> result = {{method_name}}Result::Parse(response, &errors);
DCHECK(!errors.HasErrors()) << errors.ToString();
std::move(callback).Run(reply_status, std::move(result));
}
{% endfor %}
{% if "events" in domain %}
{% for event in domain.events %}
{# Generate dispatchers which call registered observers for an event. #}
void Domain::Dispatch{{event.name | to_title_case}}Event(const base::Value& params) {
ErrorReporter errors;
std::unique_ptr<{{event.name | to_title_case}}Params> parsed_params({{event.name | to_title_case}}Params::Parse(params, &errors));
DCHECK(!errors.HasErrors()) << errors.ToString();
for (ExperimentalObserver& observer : observers_) {
observer.On{{event.name | to_title_case}}(*parsed_params);
}
}
{% endfor %}
{% endif %}
Domain::Domain(MessageDispatcher* dispatcher)
: dispatcher_(dispatcher) {
}
Domain::~Domain() {}
ExperimentalDomain::ExperimentalDomain(MessageDispatcher* dispatcher)
: Domain(dispatcher) {}
ExperimentalDomain::~ExperimentalDomain() {}
{% if "events" in domain %}
void ExperimentalDomain::AddObserver(ExperimentalObserver* observer) {
RegisterEventHandlersIfNeeded();
observers_.AddObserver(observer);
}
void ExperimentalDomain::RemoveObserver(ExperimentalObserver* observer) {
observers_.RemoveObserver(observer);
}
{% endif %}
} // namespace {{domain.domain | camelcase_to_hacker_style}}
} // namespace autofill_assistant