Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inspector: roll inspector_protocol to match v8's #56649

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
inspector: roll inspector_protocol
Roll the inspector_protocol library to match V8's inspector_protocol
revision.

Update the node inspector to use the new `crdtp` protocol library.
  • Loading branch information
legendecas committed Jan 25, 2025
commit 416b4e514820c1daf8ddef3ffd6cfa0f08300fb5
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