Index: third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template |
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template |
index 7864402d4a9538d594429bd3395e0815db2b6d8b..88e5c9735c99cbea5e80b39279e2735e0c34a926 100644 |
--- a/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template |
+++ b/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template |
@@ -6,13 +6,19 @@ |
#include "platform/inspector_protocol/{{class_name}}.h" |
+#include "platform/inspector_protocol/DispatcherBase.h" |
+ |
namespace blink { |
namespace protocol { |
+static const char kInvalidRequest[] = "Invalid request"; |
+ |
// ------------- Enum values from types. |
{% for domain in api.domains %} |
namespace {{domain.domain}} { |
+ |
+const char Metainfo::domainName[] = "{{domain.domain}}"; |
{% for type in domain.types %} |
{% if "enum" in type %} |
@@ -80,16 +86,13 @@ std::unique_ptr<{{type.id}}> {{type.id}}::clone() const |
return parse(serialize().get(), &errors); |
} |
{% endfor %} |
-} // {{domain.domain}} |
-{% endfor %} |
// ------------- Enum values from params. |
-{% for domain in api.domains %} |
+ |
{% for command in join_arrays(domain, ["commands", "events"]) %} |
{% for param in join_arrays(command, ["parameters", "returns"]) %} |
{% if "enum" in param %} |
-namespace {{domain.domain}} { |
namespace {{command.name | to_title_case}} { |
namespace {{param.name | to_title_case}}Enum { |
{% for literal in param.enum %} |
@@ -97,10 +100,206 @@ const char* {{ literal | to_title_case}} = "{{literal}}"; |
{% endfor %} |
} // {{param.name | to_title_case}}Enum |
} // {{command.name | to_title_case }} |
-} // {{domain.domain}} |
{% endif %} |
{% endfor %} |
{% endfor %} |
+ |
+// ------------- Frontend notifications. |
+ {% for event in domain.events %} |
+ {% if "handlers" in event and not ("renderer" in event["handlers"]) %}{% continue %}{% endif %} |
+ |
+void Frontend::{{event.name}}( |
+ {%- for parameter in event.parameters %} |
+ {% if "optional" in parameter -%} |
+ const Maybe<{{resolve_type(parameter).raw_type}}>& |
+ {%- else -%} |
+ {{resolve_type(parameter).pass_type}} |
+ {%- endif %} {{parameter.name}}{%- if not loop.last -%}, {% endif -%} |
+ {% endfor -%}) |
+{ |
+ std::unique_ptr<protocol::DictionaryValue> jsonMessage = DictionaryValue::create(); |
+ jsonMessage->setString("method", "{{domain.domain}}.{{event.name}}"); |
+ std::unique_ptr<protocol::DictionaryValue> paramsObject = DictionaryValue::create(); |
+ {% for parameter in event.parameters %} |
+ {% if "optional" in parameter %} |
+ if ({{parameter.name}}.isJust()) |
+ paramsObject->setValue("{{parameter.name}}", toValue({{parameter.name}}.fromJust())); |
+ {% else %} |
+ paramsObject->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).to_raw_type % parameter.name}})); |
+ {% endif %} |
+ {% endfor %} |
+ jsonMessage->setObject("params", std::move(paramsObject)); |
+ if (m_frontendChannel) |
+ m_frontendChannel->sendProtocolNotification(jsonMessage->toJSONString()); |
+} |
+ {% endfor %} |
+ |
+// --------------------- Dispatcher. |
+ |
+class DispatcherImpl : public protocol::DispatcherBase { |
+public: |
+ DispatcherImpl(FrontendChannel* frontendChannel, Backend* backend) |
+ : DispatcherBase(frontendChannel) |
+ , m_backend(backend) { |
+ {% for command in domain.commands %} |
+ {% if "redirect" in command %}{% continue %}{% endif %} |
+ {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %} |
+ m_dispatchMap.set("{{domain.domain}}.{{command.name}}", &DispatcherImpl::{{command.name}}); |
+ {% endfor %} |
+ } |
+ ~DispatcherImpl() override { } |
+ void dispatch(int callId, const String16& method, std::unique_ptr<protocol::DictionaryValue> messageObject) override; |
+ |
+protected: |
+ using CallHandler = void (DispatcherImpl::*)(int callId, std::unique_ptr<DictionaryValue> messageObject, ErrorSupport* errors); |
+ using DispatchMap = protocol::HashMap<String16, CallHandler>; |
+ DispatchMap m_dispatchMap; |
+ |
+ {% for command in domain.commands %} |
+ {% if "redirect" in command %}{% continue %}{% endif %} |
+ {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %} |
+ void {{command.name}}(int callId, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport*); |
+ {% endfor %} |
+ |
+ Backend* m_backend; |
+}; |
+ |
+void DispatcherImpl::dispatch(int callId, const String16& method, std::unique_ptr<protocol::DictionaryValue> messageObject) |
+{ |
+ protocol::HashMap<String16, CallHandler>::iterator it = m_dispatchMap.find(method); |
+ if (it == m_dispatchMap.end()) { |
+ reportProtocolError(callId, MethodNotFound, "'" + method + "' wasn't found", nullptr); |
+ return; |
+ } |
+ |
+ protocol::ErrorSupport errors; |
+ ((*this).*(*it->second))(callId, std::move(messageObject), &errors); |
+} |
+ |
+ {% for command in domain.commands %} |
+ {% if "redirect" in command %}{% continue %}{% endif %} |
+ {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %} |
+ {% if "async" in command %} |
+ |
+class PLATFORM_EXPORT {{command.name | to_title_case}}CallbackImpl : public Backend::{{command.name | to_title_case}}Callback, public DispatcherBase::Callback { |
+public: |
+ {{command.name | to_title_case}}CallbackImpl(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId) |
+ : DispatcherBase::Callback(std::move(backendImpl), callId) { } |
+ |
+ void sendSuccess( |
+ {%- for parameter in command.returns -%} |
+ {%- if "optional" in parameter -%} |
+ const Maybe<{{resolve_type(parameter).raw_type}}>& {{parameter.name}} |
+ {%- else -%} |
+ {{resolve_type(parameter).pass_type}} {{parameter.name}} |
+ {%- endif -%} |
+ {%- if not loop.last -%}, {% endif -%} |
+ {%- endfor -%}) override |
+ { |
+ std::unique_ptr<protocol::DictionaryValue> resultObject = DictionaryValue::create(); |
+ {% for parameter in command.returns %} |
+ {% if "optional" in parameter %} |
+ if ({{parameter.name}}.isJust()) |
+ resultObject->setValue("{{parameter.name}}", toValue({{parameter.name}}.fromJust())); |
+ {% else %} |
+ resultObject->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).to_raw_type % parameter.name}})); |
+ {% endif %} |
+ {% endfor %} |
+ sendIfActive(std::move(resultObject), ErrorString()); |
+ } |
+ |
+ void sendFailure(const ErrorString& error) override |
+ { |
+ DCHECK(error.length()); |
+ sendIfActive(nullptr, error); |
+ } |
+ |
+}; |
+ {% endif %} |
+ |
+void DispatcherImpl::{{command.name}}(int callId, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport* errors) |
+{ |
+ {% if "parameters" in command %} |
+ // Prepare input parameters. |
+ protocol::DictionaryValue* object = DictionaryValue::cast(requestMessageObject->get("params")); |
+ errors->push(); |
+ {% for property in command.parameters %} |
+ protocol::Value* {{property.name}}Value = object ? object->get("{{property.name}}") : nullptr; |
+ {% if property.optional %} |
+ Maybe<{{resolve_type(property).raw_type}}> in_{{property.name}}; |
+ if ({{property.name}}Value) { |
+ errors->setName("{{property.name}}"); |
+ in_{{property.name}} = FromValue<{{resolve_type(property).raw_type}}>::parse({{property.name}}Value, errors); |
+ } |
+ {% else %} |
+ errors->setName("{{property.name}}"); |
+ {{resolve_type(property).type}} in_{{property.name}} = FromValue<{{resolve_type(property).raw_type}}>::parse({{property.name}}Value, errors); |
+ {% endif %} |
+ {% endfor %} |
+ errors->pop(); |
+ if (errors->hasErrors()) { |
+ reportProtocolError(callId, InvalidParams, kInvalidRequest, errors); |
+ return; |
+ } |
+ {% endif %} |
+ {% if "async" in command %} |
+ std::unique_ptr<{{command.name | to_title_case}}CallbackImpl> callback(new {{command.name | to_title_case}}CallbackImpl(weakPtr(), callId)); |
+ {% elif "returns" in command %} |
+ // Declare output parameters. |
+ std::unique_ptr<protocol::DictionaryValue> result = DictionaryValue::create(); |
+ {% for property in command.returns %} |
+ {% if "optional" in property %} |
+ Maybe<{{resolve_type(property).raw_type}}> out_{{property.name}}; |
+ {% else %} |
+ {{resolve_type(property).type}} out_{{property.name}}; |
+ {% endif %} |
+ {% endfor %} |
+ {% endif %} |
+ |
+ std::unique_ptr<DispatcherBase::WeakPtr> weak = weakPtr(); |
+ ErrorString error; |
+ m_backend->{{command.name}}(&error |
+ {%- for property in command.parameters -%} |
+ {%- if "optional" in property -%} |
+ , in_{{property.name}} |
+ {%- else -%} |
+ , {{resolve_type(property).to_pass_type % ("in_" + property.name)}} |
+ {%- endif -%} |
+ {%- endfor %} |
+ {%- if "async" in command -%} |
+ , std::move(callback) |
+ {%- elif "returns" in command %} |
+ {%- for property in command.returns -%} |
+ , &out_{{property.name}} |
+ {%- endfor %} |
+ {% endif %}); |
+ {% if "returns" in command and not("async" in command) %} |
+ if (!error.length()) { |
+ {% for parameter in command.returns %} |
+ {% if "optional" in parameter %} |
+ if (out_{{parameter.name}}.isJust()) |
+ result->setValue("{{parameter.name}}", toValue(out_{{parameter.name}}.fromJust())); |
+ {% else %} |
+ result->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).to_raw_type % ("out_" + parameter.name)}})); |
+ {% endif %} |
+ {% endfor %} |
+ } |
+ if (weak->get()) |
+ weak->get()->sendResponse(callId, error, std::move(result)); |
+ {% elif not("async" in command) %} |
+ if (weak->get()) |
+ weak->get()->sendResponse(callId, error); |
+ {% endif %} |
+} |
+ {% endfor %} |
+ |
+// static |
+void Dispatcher::wire(UberDispatcher* dispatcher, Backend* backend) |
+{ |
+ dispatcher->registerBackend("{{domain.domain}}", wrapUnique(new DispatcherImpl(dispatcher->channel(), backend))); |
+} |
+ |
+} // {{domain.domain}} |
{% endfor %} |
} // namespace protocol |