Skip to content

Commit

Permalink
inspector: roll inspector_protocol
Browse files Browse the repository at this point in the history
Roll the inspector_protocol library to match V8's inspector_protocol
revision.

Update the node inspector to use the new `crdtp` protocol library.

PR-URL: #56649
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
  • Loading branch information
legendecas authored and aduh95 committed Jan 31, 2025
1 parent 007fe10 commit f2ed5ea
Show file tree
Hide file tree
Showing 86 changed files with 10,879 additions and 6,231 deletions.
12 changes: 8 additions & 4 deletions src/inspector/network_agent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ void NetworkAgent::Wire(UberDispatcher* dispatcher) {

DispatchResponse NetworkAgent::enable() {
inspector_->Enable();
return DispatchResponse::OK();
return DispatchResponse::Success();
}

DispatchResponse NetworkAgent::disable() {
inspector_->Disable();
return DispatchResponse::OK();
return DispatchResponse::Success();
}

void NetworkAgent::requestWillBeSent(
Expand All @@ -76,9 +76,11 @@ void NetworkAgent::requestWillBeSent(
request->getString("method", &method);

ErrorSupport errors;
errors.Push();
errors.SetName("headers");
auto headers =
Network::Headers::fromValue(request->getObject("headers"), &errors);
if (errors.hasErrors()) {
if (!errors.Errors().empty()) {
headers = std::make_unique<Network::Headers>(DictionaryValue::create());
}

Expand All @@ -105,9 +107,11 @@ void NetworkAgent::responseReceived(
response->getString("statusText", &statusText);

ErrorSupport errors;
errors.Push();
errors.SetName("headers");
auto headers =
Network::Headers::fromValue(response->getObject("headers"), &errors);
if (errors.hasErrors()) {
if (!errors.Errors().empty()) {
headers = std::make_unique<Network::Headers>(DictionaryValue::create());
}

Expand Down
42 changes: 29 additions & 13 deletions src/inspector/node_inspector.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
'src/inspector_socket_server.h',
'src/inspector/main_thread_interface.cc',
'src/inspector/main_thread_interface.h',
'src/inspector/node_json.cc',
'src/inspector/node_json.h',
'src/inspector/node_string.cc',
'src/inspector/node_string.h',
'src/inspector/runtime_agent.cc',
Expand All @@ -29,6 +31,30 @@
'src/inspector/network_agent.h',
'src/inspector/worker_inspector.cc',
'src/inspector/worker_inspector.h',

'<(protocol_tool_path)/crdtp/cbor.cc',
'<(protocol_tool_path)/crdtp/cbor.h',
'<(protocol_tool_path)/crdtp/dispatch.cc',
'<(protocol_tool_path)/crdtp/dispatch.h',
'<(protocol_tool_path)/crdtp/error_support.cc',
'<(protocol_tool_path)/crdtp/error_support.h',
'<(protocol_tool_path)/crdtp/export.h',
'<(protocol_tool_path)/crdtp/find_by_first.h',
'<(protocol_tool_path)/crdtp/frontend_channel.h',
'<(protocol_tool_path)/crdtp/json.cc',
'<(protocol_tool_path)/crdtp/json.h',
'<(protocol_tool_path)/crdtp/json_platform.cc',
'<(protocol_tool_path)/crdtp/json_platform.h',
'<(protocol_tool_path)/crdtp/maybe.h',
'<(protocol_tool_path)/crdtp/parser_handler.h',
'<(protocol_tool_path)/crdtp/protocol_core.cc',
'<(protocol_tool_path)/crdtp/protocol_core.h',
'<(protocol_tool_path)/crdtp/serializable.cc',
'<(protocol_tool_path)/crdtp/serializable.h',
'<(protocol_tool_path)/crdtp/span.cc',
'<(protocol_tool_path)/crdtp/span.h',
'<(protocol_tool_path)/crdtp/status.cc',
'<(protocol_tool_path)/crdtp/status.h',
],
'node_inspector_generated_sources': [
'<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/Forward.h',
Expand All @@ -44,23 +70,11 @@
'<(SHARED_INTERMEDIATE_DIR)/src/node/inspector/protocol/Network.h',
],
'node_protocol_files': [
'<(protocol_tool_path)/lib/Allocator_h.template',
'<(protocol_tool_path)/lib/base_string_adapter_cc.template',
'<(protocol_tool_path)/lib/base_string_adapter_h.template',
'<(protocol_tool_path)/lib/DispatcherBase_cpp.template',
'<(protocol_tool_path)/lib/DispatcherBase_h.template',
'<(protocol_tool_path)/lib/encoding_cpp.template',
'<(protocol_tool_path)/lib/encoding_h.template',
'<(protocol_tool_path)/lib/ErrorSupport_cpp.template',
'<(protocol_tool_path)/lib/ErrorSupport_h.template',
'<(protocol_tool_path)/lib/Forward_h.template',
'<(protocol_tool_path)/lib/FrontendChannel_h.template',
'<(protocol_tool_path)/lib/Maybe_h.template',
'<(protocol_tool_path)/lib/Object_cpp.template',
'<(protocol_tool_path)/lib/Object_h.template',
'<(protocol_tool_path)/lib/Parser_cpp.template',
'<(protocol_tool_path)/lib/Parser_h.template',
'<(protocol_tool_path)/lib/Protocol_cpp.template',
'<(protocol_tool_path)/lib/ValueConversions_cpp.template',
'<(protocol_tool_path)/lib/ValueConversions_h.template',
'<(protocol_tool_path)/lib/Values_cpp.template',
'<(protocol_tool_path)/lib/Values_h.template',
Expand All @@ -77,6 +91,7 @@
'<@(node_inspector_sources)',
],
'include_dirs': [
'<(protocol_tool_path)',
'<(SHARED_INTERMEDIATE_DIR)/include', # for inspector
'<(SHARED_INTERMEDIATE_DIR)',
'<(SHARED_INTERMEDIATE_DIR)/src', # for inspector
Expand Down Expand Up @@ -112,6 +127,7 @@
'action': [
'<(python)',
'tools/inspector_protocol/code_generator.py',
'--inspector_protocol_dir', 'tools/inspector_protocol/',
'--jinja_dir', '<@(protocol_tool_path)',
'--output_base', '<(SHARED_INTERMEDIATE_DIR)/src/',
'--config', 'src/inspector/node_protocol_config.json',
Expand Down
190 changes: 190 additions & 0 deletions src/inspector/node_json.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#include "node_json.h"

#include "crdtp/json.h"

namespace node {
namespace inspector {

using crdtp::ParserHandler;
using crdtp::span;
using crdtp::Status;
using protocol::Binary;
using protocol::BinaryValue;
using protocol::DictionaryValue;
using protocol::FundamentalValue;
using protocol::ListValue;
using protocol::String;
using protocol::StringUtil;
using protocol::StringValue;
using protocol::Value;

namespace {

// Uses the parsing events received from driver of `ParserHandler`
// (e.g. crdtp::json::ParseJSON) into a protocol::Value instance.
class ValueParserHandler : public ParserHandler {
public:
// Provides the parsed protocol::Value.
std::unique_ptr<Value> ReleaseRoot() { return std::move(root_); }

// The first parsing error encountered; `status().ok()` is the default.
Status status() const { return status_; }

private:
// Implementation of `ParserHandler`.
void HandleMapBegin() override {
if (!status_.ok()) return;
std::unique_ptr<DictionaryValue> dict = DictionaryValue::create();
DictionaryValue* dict_ptr = dict.get();
AddValueToParent(std::move(dict));
stack_.emplace_back(dict_ptr);
}

void HandleMapEnd() override {
if (!status_.ok()) return;
DCHECK(!stack_.empty());
DCHECK(stack_.back().is_dict);
stack_.pop_back();
}

void HandleArrayBegin() override {
if (!status_.ok()) return;
std::unique_ptr<ListValue> list = ListValue::create();
ListValue* list_ptr = list.get();
AddValueToParent(std::move(list));
stack_.emplace_back(list_ptr);
}

void HandleArrayEnd() override {
if (!status_.ok()) return;
DCHECK(!stack_.empty());
DCHECK(!stack_.back().is_dict);
stack_.pop_back();
}

void HandleString8(span<uint8_t> chars) override {
AddStringToParent(StringUtil::fromUTF8(chars.data(), chars.size()));
}

void HandleString16(span<uint16_t> chars) override {
AddStringToParent(StringUtil::fromUTF16(chars.data(), chars.size()));
}

void HandleBinary(span<uint8_t> bytes) override {
AddValueToParent(
BinaryValue::create(Binary::fromSpan(bytes.data(), bytes.size())));
}

void HandleDouble(double value) override {
AddValueToParent(FundamentalValue::create(value));
}

void HandleInt32(int32_t value) override {
AddValueToParent(FundamentalValue::create(value));
}

void HandleBool(bool value) override {
AddValueToParent(FundamentalValue::create(value));
}

void HandleNull() override { AddValueToParent(Value::null()); }

void HandleError(Status error) override { status_ = error; }

// Adding strings and values to the parent value.
// Strings are handled separately because they can be keys for
// dictionary values.
void AddStringToParent(String str) {
if (!status_.ok()) return;
if (!root_) {
DCHECK(!key_is_pending_);
root_ = StringValue::create(str);
} else if (stack_.back().is_dict) {
// If we already have a pending key, then this is the value of the
// key/value pair. Otherwise, it's the new pending key.
if (key_is_pending_) {
stack_.back().dict->setString(pending_key_, str);
key_is_pending_ = false;
} else {
pending_key_ = std::move(str);
key_is_pending_ = true;
}
} else { // Top of the stack is a list.
DCHECK(!key_is_pending_);
stack_.back().list->pushValue(StringValue::create(str));
}
}

void AddValueToParent(std::unique_ptr<Value> value) {
if (!status_.ok()) return;
if (!root_) {
DCHECK(!key_is_pending_);
root_ = std::move(value);
} else if (stack_.back().is_dict) {
DCHECK(key_is_pending_);
stack_.back().dict->setValue(pending_key_, std::move(value));
key_is_pending_ = false;
} else { // Top of the stack is a list.
DCHECK(!key_is_pending_);
stack_.back().list->pushValue(std::move(value));
}
}

// `status_.ok()` is the default; if we receive an error event
// we keep the first one and stop modifying any other state.
Status status_;

// The root of the parsed protocol::Value tree.
std::unique_ptr<Value> root_;

// If root_ is a list or a dictionary, this stack keeps track of
// the container we're currently parsing as well as its ancestors.
struct ContainerState {
explicit ContainerState(DictionaryValue* dict)
: is_dict(true), dict(dict) {}
explicit ContainerState(ListValue* list) : is_dict(false), list(list) {}

bool is_dict;
union {
DictionaryValue* dict;
ListValue* list;
};
};
std::vector<ContainerState> stack_;

// For maps, keys and values are alternating events, so we keep the
// key around and process it when the value arrives.
bool key_is_pending_ = false;
String pending_key_;
};
} // anonymous namespace

std::unique_ptr<Value> JsonUtil::ParseJSON(const uint8_t* chars, size_t size) {
ValueParserHandler handler;
crdtp::json::ParseJSON(span<uint8_t>(chars, size), &handler);
if (handler.status().ok()) return handler.ReleaseRoot();
return nullptr;
}

std::unique_ptr<Value> JsonUtil::ParseJSON(const uint16_t* chars, size_t size) {
ValueParserHandler handler;
crdtp::json::ParseJSON(span<uint16_t>(chars, size), &handler);
if (handler.status().ok()) return handler.ReleaseRoot();
return nullptr;
}

std::unique_ptr<Value> JsonUtil::parseJSON(const std::string_view string) {
if (string.empty()) return nullptr;

return ParseJSON(reinterpret_cast<const uint8_t*>(string.data()),
string.size());
}

std::unique_ptr<Value> JsonUtil::parseJSON(v8_inspector::StringView string) {
if (string.length() == 0) return nullptr;
if (string.is8Bit()) return ParseJSON(string.characters8(), string.length());
return ParseJSON(string.characters16(), string.length());
}

} // namespace inspector
} // namespace node
24 changes: 24 additions & 0 deletions src/inspector/node_json.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef SRC_INSPECTOR_NODE_JSON_H_
#define SRC_INSPECTOR_NODE_JSON_H_

#include "node/inspector/protocol/Protocol.h"

namespace node {
namespace inspector {

struct JsonUtil {
// Parse s JSON string into protocol::Value.
static std::unique_ptr<protocol::Value> ParseJSON(const uint8_t* chars,
size_t size);
static std::unique_ptr<protocol::Value> ParseJSON(const uint16_t* chars,
size_t size);

static std::unique_ptr<protocol::Value> parseJSON(const std::string_view);
static std::unique_ptr<protocol::Value> parseJSON(
v8_inspector::StringView view);
};

} // namespace inspector
} // namespace node

#endif // SRC_INSPECTOR_NODE_JSON_H_
5 changes: 4 additions & 1 deletion src/inspector/node_protocol_config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"protocol": {
"path": "node_protocol.json",
"path": "node_protocol.pdl",
"package": "src/node/inspector/protocol",
"output": "node/inspector/protocol",
"namespace": ["node", "inspector", "protocol"]
Expand All @@ -18,5 +18,8 @@
"package": "src/node/inspector/protocol",
"output": "node/inspector/protocol",
"string_header": "inspector/node_string.h"
},
"crdtp": {
"dir": "crdtp"
}
}
Loading

0 comments on commit f2ed5ea

Please sign in to comment.