From 5dffb59630f42374811553b9844e8de5d1930358 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Tue, 12 Feb 2019 11:00:13 -0800 Subject: [PATCH] DevTools: roll third_party/inspector_protocol, wire binary operation. Bug: chromium:929862 Change-Id: I8c23be1d22f70d1143d570050514c36ecfb30fc7 Reviewed-on: https://chromium-review.googlesource.com/c/1466003 Reviewed-by: Alexei Filippov Commit-Queue: Pavel Feldman Commit-Queue: Alexei Filippov Cr-Commit-Position: refs/heads/master@{#59541} --- src/inspector/custom-preview.cc | 2 +- src/inspector/injected-script.cc | 2 +- src/inspector/string-util.cc | 20 +++++++ src/inspector/string-util.h | 21 +++++++ src/inspector/v8-inspector-session-impl.cc | 49 +++++++++++----- src/inspector/v8-inspector-session-impl.h | 3 +- third_party/inspector_protocol/README.v8 | 2 +- .../lib/DispatcherBase_cpp.template | 57 +++++++++++++------ .../lib/DispatcherBase_h.template | 41 ++++++++----- .../lib/FrontendChannel_h.template | 11 +++- .../lib/Values_cpp.template | 30 +++++----- .../inspector_protocol/lib/Values_h.template | 25 +++++--- .../lib/base_string_adapter_cc.template | 22 ++++++- .../lib/base_string_adapter_h.template | 5 +- .../templates/Exported_h.template | 2 + .../templates/Imported_h.template | 24 ++++++-- .../templates/TypeBuilder_cpp.template | 29 +++++++--- .../templates/TypeBuilder_h.template | 8 ++- 18 files changed, 262 insertions(+), 91 deletions(-) diff --git a/src/inspector/custom-preview.cc b/src/inspector/custom-preview.cc index 63d1d74ab8..f56562341c 100644 --- a/src/inspector/custom-preview.cc +++ b/src/inspector/custom-preview.cc @@ -120,7 +120,7 @@ bool substituteObjectTags(int sessionId, const String16& groupName, return false; } v8::Local jsonWrapper; - String16 serialized = wrapper->serialize(); + String16 serialized = wrapper->toJSON(); if (!v8::JSON::Parse(context, toV8String(isolate, serialized)) .ToLocal(&jsonWrapper)) { reportError(context, tryCatch, "cannot wrap value"); diff --git a/src/inspector/injected-script.cc b/src/inspector/injected-script.cc index f1eb4fecf3..cae56d0082 100644 --- a/src/inspector/injected-script.cc +++ b/src/inspector/injected-script.cc @@ -585,7 +585,7 @@ Response InjectedScript::resolveCallArgument( if (callArgument->hasValue() || callArgument->hasUnserializableValue()) { String16 value; if (callArgument->hasValue()) { - value = "(" + callArgument->getValue(nullptr)->serialize() + ")"; + value = "(" + callArgument->getValue(nullptr)->toJSONString() + ")"; } else { String16 unserializableValue = callArgument->getUnserializableValue(""); // Protect against potential identifier resolution for NaN and Infinity. diff --git a/src/inspector/string-util.cc b/src/inspector/string-util.cc index 2992f08530..ea8c62f1af 100644 --- a/src/inspector/string-util.cc +++ b/src/inspector/string-util.cc @@ -122,6 +122,26 @@ std::unique_ptr StringUtil::parseJSON(const String16& string) { static_cast(string.length())); } +// static +std::unique_ptr StringUtil::parseProtocolMessage( + const ProtocolMessage& message) { + return parseJSON(message.json); +} + +// static +ProtocolMessage StringUtil::jsonToMessage(String message) { + ProtocolMessage result; + result.json = std::move(message); + return result; +} + +// static +ProtocolMessage StringUtil::binaryToMessage(std::vector message) { + ProtocolMessage result; + result.binary = std::move(message); + return result; +} + // static void StringUtil::builderAppendQuotedString(StringBuilder& builder, const String& str) { diff --git a/src/inspector/string-util.h b/src/inspector/string-util.h index 4ab39bd6d1..4bceeb5d99 100644 --- a/src/inspector/string-util.h +++ b/src/inspector/string-util.h @@ -22,6 +22,10 @@ class Value; using String = v8_inspector::String16; using StringBuilder = v8_inspector::String16Builder; +struct ProtocolMessage { + String json; + std::vector binary; +}; class StringUtil { public: @@ -59,6 +63,10 @@ class StringUtil { } static std::unique_ptr parseJSON(const String16& json); static std::unique_ptr parseJSON(const StringView& json); + static std::unique_ptr parseProtocolMessage( + const ProtocolMessage&); + static ProtocolMessage jsonToMessage(String message); + static ProtocolMessage binaryToMessage(std::vector message); }; // A read-only sequence of uninterpreted bytes with reference-counted storage. @@ -101,6 +109,19 @@ class StringBufferImpl : public StringBuffer { DISALLOW_COPY_AND_ASSIGN(StringBufferImpl); }; +class BinaryStringBuffer : public StringBuffer { + public: + explicit BinaryStringBuffer(std::vector data) + : m_data(std::move(data)), m_string(m_data.data(), m_data.size()) {} + const StringView& string() override { return m_string; } + + private: + std::vector m_data; + StringView m_string; + + DISALLOW_COPY_AND_ASSIGN(BinaryStringBuffer); +}; + String16 debuggerIdToString(const std::pair& debuggerId); String16 stackTraceIdToString(uintptr_t id); diff --git a/src/inspector/v8-inspector-session-impl.cc b/src/inspector/v8-inspector-session-impl.cc index db05b24102..a3c1ed2511 100644 --- a/src/inspector/v8-inspector-session-impl.cc +++ b/src/inspector/v8-inspector-session-impl.cc @@ -137,41 +137,53 @@ namespace { class MessageBuffer : public StringBuffer { public: static std::unique_ptr create( - std::unique_ptr message) { + std::unique_ptr message, bool binary) { return std::unique_ptr( - new MessageBuffer(std::move(message))); + new MessageBuffer(std::move(message), binary)); } const StringView& string() override { if (!m_serialized) { - m_serialized = StringBuffer::create(toStringView(m_message->serialize())); + if (m_binary) { + // Encode binary response as an 8bit string buffer. + m_serialized.reset( + new BinaryStringBuffer(m_message->serializeToBinary())); + } else { + m_serialized = + StringBuffer::create(toStringView(m_message->serializeToJSON())); + } m_message.reset(nullptr); } return m_serialized->string(); } private: - explicit MessageBuffer(std::unique_ptr message) - : m_message(std::move(message)) {} + explicit MessageBuffer(std::unique_ptr message, + bool binary) + : m_message(std::move(message)), m_binary(binary) {} std::unique_ptr m_message; std::unique_ptr m_serialized; + bool m_binary; }; } // namespace void V8InspectorSessionImpl::sendProtocolResponse( int callId, std::unique_ptr message) { - m_channel->sendResponse(callId, MessageBuffer::create(std::move(message))); + m_channel->sendResponse( + callId, MessageBuffer::create(std::move(message), use_binary_protocol_)); } void V8InspectorSessionImpl::sendProtocolNotification( std::unique_ptr message) { - m_channel->sendNotification(MessageBuffer::create(std::move(message))); + m_channel->sendNotification( + MessageBuffer::create(std::move(message), use_binary_protocol_)); } -void V8InspectorSessionImpl::fallThrough(int callId, const String16& method, - const String16& message) { +void V8InspectorSessionImpl::fallThrough( + int callId, const String16& method, + const protocol::ProtocolMessage& message) { // There's no other layer to handle the command. UNREACHABLE(); } @@ -316,19 +328,28 @@ void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) { void V8InspectorSessionImpl::dispatchProtocolMessage( const StringView& message) { + bool binary_protocol = + message.is8Bit() && message.length() && message.characters8()[0] == 0xDA; + if (binary_protocol) use_binary_protocol_ = true; int callId; + std::unique_ptr parsed_message; + if (binary_protocol) { + parsed_message = protocol::Value::parseBinary( + message.characters8(), static_cast(message.length())); + } else { + parsed_message = protocol::StringUtil::parseJSON(message); + } String16 method; - std::unique_ptr parsedMessage = - protocol::StringUtil::parseJSON(message); - if (m_dispatcher.parseCommand(parsedMessage.get(), &callId, &method)) { + if (m_dispatcher.parseCommand(parsed_message.get(), &callId, &method)) { // Pass empty string instead of the actual message to save on a conversion. // We're allowed to do so because fall-through is not implemented. - m_dispatcher.dispatch(callId, method, std::move(parsedMessage), ""); + m_dispatcher.dispatch(callId, method, std::move(parsed_message), + protocol::ProtocolMessage()); } } std::unique_ptr V8InspectorSessionImpl::stateJSON() { - String16 json = m_state->serialize(); + String16 json = m_state->toJSONString(); return StringBufferImpl::adopt(json); } diff --git a/src/inspector/v8-inspector-session-impl.h b/src/inspector/v8-inspector-session-impl.h index 461cc0a2f0..8834b56f5d 100644 --- a/src/inspector/v8-inspector-session-impl.h +++ b/src/inspector/v8-inspector-session-impl.h @@ -102,7 +102,7 @@ class V8InspectorSessionImpl : public V8InspectorSession, void sendProtocolNotification( std::unique_ptr message) override; void fallThrough(int callId, const String16& method, - const String16& message) override; + const protocol::ProtocolMessage& message) override; void flushProtocolNotifications() override; int m_contextGroupId; @@ -122,6 +122,7 @@ class V8InspectorSessionImpl : public V8InspectorSession, std::unique_ptr m_schemaAgent; std::vector> m_inspectedObjects; + bool use_binary_protocol_ = false; DISALLOW_COPY_AND_ASSIGN(V8InspectorSessionImpl); }; diff --git a/third_party/inspector_protocol/README.v8 b/third_party/inspector_protocol/README.v8 index 177c08a4a3..189bbd149b 100644 --- a/third_party/inspector_protocol/README.v8 +++ b/third_party/inspector_protocol/README.v8 @@ -2,7 +2,7 @@ Name: inspector protocol Short Name: inspector_protocol URL: https://chromium.googlesource.com/deps/inspector_protocol/ Version: 0 -Revision: 8515c2a1c5c016646b61221586cd4e5839f425ee +Revision: e8a0de7351b5d72aadde777e2ad9b412d1431ffa License: BSD License File: LICENSE Security Critical: no diff --git a/third_party/inspector_protocol/lib/DispatcherBase_cpp.template b/third_party/inspector_protocol/lib/DispatcherBase_cpp.template index 8ab681dacb..11843f4330 100644 --- a/third_party/inspector_protocol/lib/DispatcherBase_cpp.template +++ b/third_party/inspector_protocol/lib/DispatcherBase_cpp.template @@ -70,7 +70,7 @@ DispatcherBase::WeakPtr::~WeakPtr() m_dispatcher->m_weakPtrs.erase(this); } -DispatcherBase::Callback::Callback(std::unique_ptr backendImpl, int callId, const String& method, const String& message) +DispatcherBase::Callback::Callback(std::unique_ptr backendImpl, int callId, const String& method, const ProtocolMessage& message) : m_backendImpl(std::move(backendImpl)) , m_callId(callId) , m_method(method) @@ -142,18 +142,14 @@ public: return std::unique_ptr(new ProtocolError(code, errorMessage)); } - String serialize() override + String serializeToJSON() override { - std::unique_ptr error = DictionaryValue::create(); - error->setInteger("code", m_code); - error->setString("message", m_errorMessage); - if (m_data.length()) - error->setString("data", m_data); - std::unique_ptr message = DictionaryValue::create(); - message->setObject("error", std::move(error)); - if (m_hasCallId) - message->setInteger("id", m_callId); - return message->serialize(); + return serialize()->serializeToJSON(); + } + + std::vector serializeToBinary() override + { + return serialize()->serializeToBinary(); } ~ProtocolError() override {} @@ -165,6 +161,19 @@ private: { } + std::unique_ptr serialize() { + std::unique_ptr error = DictionaryValue::create(); + error->setInteger("code", m_code); + error->setString("message", m_errorMessage); + if (m_data.length()) + error->setString("data", m_data); + std::unique_ptr message = DictionaryValue::create(); + message->setObject("error", std::move(error)); + if (m_hasCallId) + message->setInteger("id", m_callId); + return message; + } + DispatchResponse::ErrorCode m_code; String m_errorMessage; String m_data; @@ -275,7 +284,7 @@ bool UberDispatcher::canDispatch(const String& in_method) return !!findDispatcher(method); } -void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_ptr parsedMessage, const String& rawMessage) +void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_ptr parsedMessage, const ProtocolMessage& rawMessage) { String method = in_method; auto redirectIt = m_redirects.find(method); @@ -304,18 +313,32 @@ std::unique_ptr InternalResponse::createNotification(const Str return std::unique_ptr(new InternalResponse(0, notification, std::move(params))); } -String InternalResponse::serialize() +String InternalResponse::serializeToJSON() { std::unique_ptr result = DictionaryValue::create(); std::unique_ptr params(m_params ? std::move(m_params) : DictionaryValue::create()); if (m_notification.length()) { result->setString("method", m_notification); - result->setValue("params", SerializedValue::create(params->serialize())); + result->setValue("params", SerializedValue::fromJSON(params->serializeToJSON())); } else { result->setInteger("id", m_callId); - result->setValue("result", SerializedValue::create(params->serialize())); + result->setValue("result", SerializedValue::fromJSON(params->serializeToJSON())); } - return result->serialize(); + return result->serializeToJSON(); +} + +std::vector InternalResponse::serializeToBinary() +{ + std::unique_ptr result = DictionaryValue::create(); + std::unique_ptr params(m_params ? std::move(m_params) : DictionaryValue::create()); + if (m_notification.length()) { + result->setString("method", m_notification); + result->setValue("params", SerializedValue::fromBinary(params->serializeToBinary())); + } else { + result->setInteger("id", m_callId); + result->setValue("result", SerializedValue::fromBinary(params->serializeToBinary())); + } + return result->serializeToBinary(); } InternalResponse::InternalResponse(int callId, const String& notification, std::unique_ptr params) diff --git a/third_party/inspector_protocol/lib/DispatcherBase_h.template b/third_party/inspector_protocol/lib/DispatcherBase_h.template index a69d022053..7d859c4f27 100644 --- a/third_party/inspector_protocol/lib/DispatcherBase_h.template +++ b/third_party/inspector_protocol/lib/DispatcherBase_h.template @@ -68,7 +68,7 @@ public: class {{config.lib.export_macro}} Callback { public: - Callback(std::unique_ptr backendImpl, int callId, const String& method, const String& message); + Callback(std::unique_ptr backendImpl, int callId, const String& method, const ProtocolMessage& message); virtual ~Callback(); void dispose(); @@ -80,14 +80,14 @@ public: std::unique_ptr m_backendImpl; int m_callId; String m_method; - String m_message; + ProtocolMessage m_message; }; explicit DispatcherBase(FrontendChannel*); virtual ~DispatcherBase(); virtual bool canDispatch(const String& method) = 0; - virtual void dispatch(int callId, const String& method, const String& rawMessage, std::unique_ptr messageObject) = 0; + virtual void dispatch(int callId, const String& method, const ProtocolMessage& rawMessage, std::unique_ptr messageObject) = 0; FrontendChannel* channel() { return m_frontendChannel; } void sendResponse(int callId, const DispatchResponse&, std::unique_ptr result); @@ -111,7 +111,7 @@ public: void setupRedirects(const std::unordered_map&); bool parseCommand(Value* message, int* callId, String* method); bool canDispatch(const String& method); - void dispatch(int callId, const String& method, std::unique_ptr message, const String& rawMessage); + void dispatch(int callId, const String& method, std::unique_ptr message, const ProtocolMessage& rawMessage); FrontendChannel* channel() { return m_frontendChannel; } virtual ~UberDispatcher(); @@ -128,7 +128,8 @@ public: static std::unique_ptr createResponse(int callId, std::unique_ptr params); static std::unique_ptr createNotification(const String& notification, std::unique_ptr params = nullptr); - String serialize() override; + String serializeToJSON() override; + std::vector serializeToBinary() override; ~InternalResponse() override {} @@ -142,24 +143,36 @@ private: class InternalRawNotification : public Serializable { public: - static std::unique_ptr create(const String& notification) + static std::unique_ptr fromJSON(String notification) { - return std::unique_ptr(new InternalRawNotification(notification)); + return std::unique_ptr(new InternalRawNotification(std::move(notification))); } + + static std::unique_ptr fromBinary(std::vector notification) + { + return std::unique_ptr(new InternalRawNotification(std::move(notification))); + } + ~InternalRawNotification() override {} - String serialize() override + String serializeToJSON() override { - return m_notification; + return std::move(m_jsonNotification); + } + + std::vector serializeToBinary() override + { + return std::move(m_binaryNotification); } private: - explicit InternalRawNotification(const String& notification) - : m_notification(notification) - { - } + explicit InternalRawNotification(String notification) + : m_jsonNotification(std::move(notification)) { } + explicit InternalRawNotification(std::vector notification) + : m_binaryNotification(std::move(notification)) { } - String m_notification; + String m_jsonNotification; + std::vector m_binaryNotification; }; {% for namespace in config.protocol.namespace %} diff --git a/third_party/inspector_protocol/lib/FrontendChannel_h.template b/third_party/inspector_protocol/lib/FrontendChannel_h.template index cb04beceaa..df104debad 100644 --- a/third_party/inspector_protocol/lib/FrontendChannel_h.template +++ b/third_party/inspector_protocol/lib/FrontendChannel_h.template @@ -13,7 +13,14 @@ namespace {{namespace}} { class {{config.lib.export_macro}} Serializable { public: - virtual String serialize() = 0; + ProtocolMessage serialize(bool binary) { + if (binary) + return StringUtil::binaryToMessage(serializeToBinary()); + else + return StringUtil::jsonToMessage(serializeToJSON()); + } + virtual String serializeToJSON() = 0; + virtual std::vector serializeToBinary() = 0; virtual ~Serializable() = default; }; @@ -22,7 +29,7 @@ public: virtual ~FrontendChannel() { } virtual void sendProtocolResponse(int callId, std::unique_ptr message) = 0; virtual void sendProtocolNotification(std::unique_ptr message) = 0; - virtual void fallThrough(int callId, const String& method, const String& message) = 0; + virtual void fallThrough(int callId, const String& method, const ProtocolMessage& message) = 0; virtual void flushProtocolNotifications() = 0; }; diff --git a/third_party/inspector_protocol/lib/Values_cpp.template b/third_party/inspector_protocol/lib/Values_cpp.template index 06b888818e..17753d3cf0 100644 --- a/third_party/inspector_protocol/lib/Values_cpp.template +++ b/third_party/inspector_protocol/lib/Values_cpp.template @@ -62,6 +62,11 @@ void escapeStringForJSONInternal(const Char* str, unsigned len, } // anonymous namespace +// static +std::unique_ptr Value::parseBinary(const uint8_t* data, unsigned size) { + return nullptr; +} + bool Value::asBoolean(bool*) const { return false; @@ -82,11 +87,6 @@ bool Value::asString(String*) const return false; } -bool Value::asSerialized(String*) const -{ - return false; -} - void Value::writeJSON(StringBuilder* output) const { DCHECK(m_type == TypeNull); @@ -98,7 +98,7 @@ std::unique_ptr Value::clone() const return Value::null(); } -String Value::serialize() +String Value::toJSONString() const { StringBuilder result; StringUtil::builderReserve(result, 512); @@ -106,6 +106,14 @@ String Value::serialize() return StringUtil::builderToString(result); } +String Value::serializeToJSON() { + return toJSONString(); +} + +std::vector Value::serializeToBinary() { + return std::vector(); +} + bool FundamentalValue::asBoolean(bool* output) const { if (type() != TypeBoolean) @@ -183,21 +191,15 @@ std::unique_ptr StringValue::clone() const return StringValue::create(m_stringValue); } -bool SerializedValue::asSerialized(String* output) const -{ - *output = m_serializedValue; - return true; -} - void SerializedValue::writeJSON(StringBuilder* output) const { DCHECK(type() == TypeSerialized); - StringUtil::builderAppend(*output, m_serializedValue); + StringUtil::builderAppend(*output, m_serializedJSON); } std::unique_ptr SerializedValue::clone() const { - return SerializedValue::create(m_serializedValue); + return std::unique_ptr(new SerializedValue(m_serializedJSON, m_serializedBinary)); } DictionaryValue::~DictionaryValue() diff --git a/third_party/inspector_protocol/lib/Values_h.template b/third_party/inspector_protocol/lib/Values_h.template index 69dde07d1d..20ba0429c5 100644 --- a/third_party/inspector_protocol/lib/Values_h.template +++ b/third_party/inspector_protocol/lib/Values_h.template @@ -28,6 +28,8 @@ public: return std::unique_ptr(new Value()); } + static std::unique_ptr parseBinary(const uint8_t*data, unsigned size); + enum ValueType { TypeNull = 0, TypeBoolean, @@ -47,11 +49,13 @@ public: virtual bool asDouble(double* output) const; virtual bool asInteger(int* output) const; virtual bool asString(String* output) const; - virtual bool asSerialized(String* output) const; virtual void writeJSON(StringBuilder* output) const; virtual std::unique_ptr clone() const; - String serialize() override; + String toJSONString() const; + String serializeToJSON() override; + std::vector serializeToBinary() override; + protected: Value() : m_type(TypeNull) { } @@ -124,19 +128,26 @@ private: class {{config.lib.export_macro}} SerializedValue : public Value { public: - static std::unique_ptr create(const String& value) + static std::unique_ptr fromJSON(const String& value) { return std::unique_ptr(new SerializedValue(value)); } - bool asSerialized(String* output) const override; + static std::unique_ptr fromBinary(std::vector value) + { + return std::unique_ptr(new SerializedValue(std::move(value))); + } + void writeJSON(StringBuilder* output) const override; std::unique_ptr clone() const override; private: - explicit SerializedValue(const String& value) : Value(TypeSerialized), m_serializedValue(value) { } - - String m_serializedValue; + explicit SerializedValue(const String& json) : Value(TypeSerialized), m_serializedJSON(json) { } + explicit SerializedValue(std::vector binary) : Value(TypeSerialized), m_serializedBinary(std::move(binary)) { } + SerializedValue(const String& json, const std::vector& binary) + : Value(TypeSerialized), m_serializedJSON(json), m_serializedBinary(binary) { } + String m_serializedJSON; + std::vector m_serializedBinary; }; class {{config.lib.export_macro}} DictionaryValue : public Value { diff --git a/third_party/inspector_protocol/lib/base_string_adapter_cc.template b/third_party/inspector_protocol/lib/base_string_adapter_cc.template index 5ce0f6882d..1576cd7e06 100644 --- a/third_party/inspector_protocol/lib/base_string_adapter_cc.template +++ b/third_party/inspector_protocol/lib/base_string_adapter_cc.template @@ -128,12 +128,28 @@ std::unique_ptr toBaseValue(Value* value, int depth) { } // static -std::unique_ptr StringUtil::parseJSON( - const std::string& json) { - std::unique_ptr value = base::JSONReader::Read(json); +std::unique_ptr StringUtil::parseMessage( + const std::string& message, bool binary) { + if (binary) { + return Value::parseBinary( + reinterpret_cast(message.data()), + message.length()); + } + std::unique_ptr value = base::JSONReader::Read(message); return toProtocolValue(value.get(), 1000); } +// static +ProtocolMessage StringUtil::jsonToMessage(String message) { + return message; +} + +// static +ProtocolMessage StringUtil::binaryToMessage(std::vector message) { + // TODO(pfeldman): figure out what to do with this copy. + return std::string(reinterpret_cast(message.data()), message.size()); +} + StringBuilder::StringBuilder() {} StringBuilder::~StringBuilder() {} diff --git a/third_party/inspector_protocol/lib/base_string_adapter_h.template b/third_party/inspector_protocol/lib/base_string_adapter_h.template index 0c57998de7..d28c7cd882 100644 --- a/third_party/inspector_protocol/lib/base_string_adapter_h.template +++ b/third_party/inspector_protocol/lib/base_string_adapter_h.template @@ -30,6 +30,7 @@ namespace {{namespace}} { class Value; using String = std::string; +using ProtocolMessage = std::string; class {{config.lib.export_macro}} StringBuilder { public: @@ -90,7 +91,9 @@ class {{config.lib.export_macro}} StringUtil { return std::vector(str.begin(), str.end()); } - static std::unique_ptr parseJSON(const String&); + static std::unique_ptr parseMessage(const std::string& message, bool binary); + static ProtocolMessage jsonToMessage(String message); + static ProtocolMessage binaryToMessage(std::vector message); }; // A read-only sequence of uninterpreted bytes with reference-counted storage. diff --git a/third_party/inspector_protocol/templates/Exported_h.template b/third_party/inspector_protocol/templates/Exported_h.template index a8c3d73f7c..a37afa8636 100644 --- a/third_party/inspector_protocol/templates/Exported_h.template +++ b/third_party/inspector_protocol/templates/Exported_h.template @@ -51,8 +51,10 @@ namespace {{param.name | to_title_case}}Enum { class {{config.exported.export_macro}} {{type.id}} { public: virtual {{config.exported.string_out}} toJSONString() const = 0; + virtual std::vector toBinary() const = 0; virtual ~{{type.id}}() { } static std::unique_ptr fromJSONString(const {{config.exported.string_in}}& json); + static std::unique_ptr fromBinary(std::vector binary); }; {% endfor %} diff --git a/third_party/inspector_protocol/templates/Imported_h.template b/third_party/inspector_protocol/templates/Imported_h.template index 396c6902f0..00bdad80a8 100644 --- a/third_party/inspector_protocol/templates/Imported_h.template +++ b/third_party/inspector_protocol/templates/Imported_h.template @@ -28,8 +28,17 @@ struct ValueConversions<{{"::".join(config.imported.namespace)}}::{{domain.domai errors->addError("value expected"); return nullptr; } - String json = value->serialize(); - auto result = {{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}::fromJSONString({{config.imported.to_imported_string % "json"}}); + + // TODO(pfeldman): toggle to true and delete the json branch when binary is ready. + bool binary_protocol = false; + std::unique_ptr<{{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}> result; + if (binary_protocol) { + std::vector binary = value->serializeToBinary(); + result = {{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}::fromBinary(std::move(binary)); + } else { + String json = value->serializeToJSON(); + result = {{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}::fromJSONString({{config.imported.to_imported_string % "json"}}); + } if (!result) errors->addError("cannot parse"); return result; @@ -37,8 +46,15 @@ struct ValueConversions<{{"::".join(config.imported.namespace)}}::{{domain.domai static std::unique_ptr toValue(const {{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}* value) { - auto json = value->toJSONString(); - return SerializedValue::create({{config.imported.from_imported_string % "std::move(json)"}}); + // TODO(pfeldman): toggle to true and delete the json branch when binary is ready. + bool binary_protocol = false; + if (binary_protocol) { + return SerializedValue::fromBinary(value->toBinary()); + } else { + auto json = value->toJSONString(); + String local_json = ({{config.imported.from_imported_string % "std::move(json)"}}); + return SerializedValue::fromJSON(local_json); + } } static std::unique_ptr toValue(const std::unique_ptr<{{"::".join(config.imported.namespace)}}::{{domain.domain}}::API::{{type.id}}>& value) diff --git a/third_party/inspector_protocol/templates/TypeBuilder_cpp.template b/third_party/inspector_protocol/templates/TypeBuilder_cpp.template index b6a297cfb4..bece358fd7 100644 --- a/third_party/inspector_protocol/templates/TypeBuilder_cpp.template +++ b/third_party/inspector_protocol/templates/TypeBuilder_cpp.template @@ -101,10 +101,15 @@ std::unique_ptr<{{type.id}}> {{type.id}}::clone() const {{config.exported.string_out}} {{type.id}}::toJSONString() const { - String json = toValue()->serialize(); + String json = toValue()->serializeToJSON(); return {{config.exported.to_string_out % "json"}}; } +std::vector {{type.id}}::toBinary() const +{ + return toValue()->serializeToBinary(); +} + // static std::unique_ptr API::{{type.id}}::fromJSONString(const {{config.exported.string_in}}& json) { @@ -114,6 +119,7 @@ std::unique_ptr API::{{type.id}}::fromJSONString(const {{confi return nullptr; return protocol::{{domain.domain}}::{{type.id}}::fromValue(value.get(), &errors); } + {% endif %} {% endfor %} @@ -187,9 +193,14 @@ void Frontend::flush() m_frontendChannel->flushProtocolNotifications(); } -void Frontend::sendRawNotification(const String& notification) +void Frontend::sendRawNotification(String notification) { - m_frontendChannel->sendProtocolNotification(InternalRawNotification::create(notification)); + m_frontendChannel->sendProtocolNotification(InternalRawNotification::fromJSON(std::move(notification))); +} + +void Frontend::sendRawNotification(std::vector notification) +{ + m_frontendChannel->sendProtocolNotification(InternalRawNotification::fromBinary(std::move(notification))); } // --------------------- Dispatcher. @@ -210,11 +221,11 @@ public: } ~DispatcherImpl() override { } bool canDispatch(const String& method) override; - void dispatch(int callId, const String& method, const String& message, std::unique_ptr messageObject) override; + void dispatch(int callId, const String& method, const ProtocolMessage& message, std::unique_ptr messageObject) override; std::unordered_map& redirects() { return m_redirects; } protected: - using CallHandler = void (DispatcherImpl::*)(int callId, const String& method, const String& message, std::unique_ptr messageObject, ErrorSupport* errors); + using CallHandler = void (DispatcherImpl::*)(int callId, const String& method, const ProtocolMessage& message, std::unique_ptr messageObject, ErrorSupport* errors); using DispatchMap = std::unordered_map; DispatchMap m_dispatchMap; std::unordered_map m_redirects; @@ -222,7 +233,7 @@ protected: {% for command in domain.commands %} {% if "redirect" in command %}{% continue %}{% endif %} {% if not protocol.generate_command(domain.domain, command.name) %}{% continue %}{% endif %} - void {{command.name}}(int callId, const String& method, const String& message, std::unique_ptr requestMessageObject, ErrorSupport*); + void {{command.name}}(int callId, const String& method, const ProtocolMessage& message, std::unique_ptr requestMessageObject, ErrorSupport*); {% endfor %} Backend* m_backend; @@ -232,7 +243,7 @@ bool DispatcherImpl::canDispatch(const String& method) { return m_dispatchMap.find(method) != m_dispatchMap.end(); } -void DispatcherImpl::dispatch(int callId, const String& method, const String& message, std::unique_ptr messageObject) +void DispatcherImpl::dispatch(int callId, const String& method, const ProtocolMessage& message, std::unique_ptr messageObject) { std::unordered_map::iterator it = m_dispatchMap.find(method); DCHECK(it != m_dispatchMap.end()); @@ -248,7 +259,7 @@ void DispatcherImpl::dispatch(int callId, const String& method, const String& me class {{command_name_title}}CallbackImpl : public Backend::{{command_name_title}}Callback, public DispatcherBase::Callback { public: - {{command_name_title}}CallbackImpl(std::unique_ptr backendImpl, int callId, const String& method, const String& message) + {{command_name_title}}CallbackImpl(std::unique_ptr backendImpl, int callId, const String& method, const ProtocolMessage& message) : DispatcherBase::Callback(std::move(backendImpl), callId, method, message) { } void sendSuccess( @@ -286,7 +297,7 @@ public: }; {% endif %} -void DispatcherImpl::{{command.name}}(int callId, const String& method, const String& message, std::unique_ptr requestMessageObject, ErrorSupport* errors) +void DispatcherImpl::{{command.name}}(int callId, const String& method, const ProtocolMessage& message, std::unique_ptr requestMessageObject, ErrorSupport* errors) { {% if "parameters" in command %} // Prepare input parameters. diff --git a/third_party/inspector_protocol/templates/TypeBuilder_h.template b/third_party/inspector_protocol/templates/TypeBuilder_h.template index cb9ab3137e..c5e95d7777 100644 --- a/third_party/inspector_protocol/templates/TypeBuilder_h.template +++ b/third_party/inspector_protocol/templates/TypeBuilder_h.template @@ -100,10 +100,13 @@ public: {% endfor %} std::unique_ptr toValue() const; - String serialize() override { return toValue()->serialize(); } + String serializeToJSON() override { return toValue()->serializeToJSON(); } + std::vector serializeToBinary() override { return toValue()->serializeToBinary(); } + String toJSON() const { return toValue()->toJSONString(); } std::unique_ptr<{{type.id}}> clone() const; {% if protocol.is_exported(domain.domain, type.id) %} {{config.exported.string_out}} toJSONString() const override; + std::vector toBinary() const override; {% endif %} template @@ -266,7 +269,8 @@ public: {% endfor %} void flush(); - void sendRawNotification(const String&); + void sendRawNotification(String); + void sendRawNotification(std::vector); private: FrontendChannel* m_frontendChannel; };