tools: update inspector_protocol to 69d69dd

PR-URL: https://github.com/nodejs/node/pull/58900
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
Shelley Vohr 2025-07-02 21:57:10 +02:00 committed by GitHub
parent 46508d9dd8
commit ec4168668b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 161 additions and 309 deletions

View file

@ -1,34 +1,95 @@
# Copyright 2019 the V8 project authors. All rights reserved.
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
static_library("encoding") {
# This BUILD.gn file is specific to the standalone project. Do not
# copy this downstream.
import("//testing/test.gni")
static_library("crdtp") {
sources = [
"encoding/encoding.cc",
"encoding/encoding.h",
"crdtp/cbor.cc",
"crdtp/cbor.h",
"crdtp/dispatch.cc",
"crdtp/dispatch.h",
"crdtp/error_support.cc",
"crdtp/error_support.h",
"crdtp/export.h",
"crdtp/find_by_first.h",
"crdtp/frontend_channel.h",
"crdtp/glue.h",
"crdtp/json.cc",
"crdtp/json.h",
"crdtp/parser_handler.h",
"crdtp/protocol_core.cc",
"crdtp/protocol_core.h",
"crdtp/serializable.cc",
"crdtp/serializable.h",
"crdtp/span.cc",
"crdtp/span.h",
"crdtp/status.cc",
"crdtp/status.h",
]
deps = [ ":crdtp_platform" ]
}
# A small adapter library which only :crdtp may depend on.
static_library("crdtp_platform") {
sources = [
"crdtp/json_platform.cc",
"crdtp/json_platform.h",
]
}
# encoding_test is part of the unittests, defined in
# test/unittests/BUILD.gn.
# In this (upstream) standalone package, we declare crdtp_test, and a
# few minimal files in testing (accessed via test_platform.{h,cc}) to
# make it look like Chromium's testing package. In Chromium,
# we run these tests as part of the content_unittests, declared in
# content/test/BUILD.gn, and in V8, we run them via unittests, declared
# in test/unittests/BUILD.gn.
import("../../gni/v8.gni")
v8_source_set("encoding_test") {
test("crdtp_test") {
sources = [
"encoding/encoding_test.cc",
"encoding/encoding_test_helper.h",
]
configs = [
"../..:external_config",
"../..:internal_config_base",
"crdtp/cbor_test.cc",
"crdtp/dispatch_test.cc",
"crdtp/error_support_test.cc",
"crdtp/find_by_first_test.cc",
"crdtp/json_test.cc",
"crdtp/protocol_core_test.cc",
"crdtp/serializable_test.cc",
"crdtp/span_test.cc",
"crdtp/status_test.cc",
"crdtp/status_test_support.cc",
"crdtp/status_test_support.h",
"crdtp/test_string_traits.cc",
"crdtp/test_string_traits.h",
]
include_dirs = [ "." ]
deps = [
":encoding",
"../..:v8_libbase",
"../../src/inspector:inspector_string_conversions",
"//testing/gmock",
"//testing/gtest",
":crdtp",
":crdtp_test_platform",
]
}
# A small adapter library which only :crdtp_test may depend on.
static_library("crdtp_test_platform") {
sources = [
"crdtp/test_platform.cc",
"crdtp/test_platform.h",
]
testonly = true
include_dirs = [ "." ]
public_deps = [
"//base",
"//testing/gmock",
"//testing/gtest",
"//testing/gtest:gtest_main",
]
}
# A command line utility for converting between JSON and CBOR.
executable("transcode") {
sources = [ "crdtp/transcode.cc" ]
deps = [ ":crdtp" ]
}

View file

@ -1,4 +1,4 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Copyright 2016 The Chromium Authors.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are

View file

@ -2,7 +2,7 @@ Name: inspector protocol
Short Name: inspector_protocol
URL: https://chromium.googlesource.com/deps/inspector_protocol/
Version: 0
Revision: 64cc2301620c04f0fe0313ae94a9319f003603cf
Revision: 69d69ddf3aa698b171886551a4a672c5af1ad902
License: BSD
License File: LICENSE
Security Critical: no

View file

@ -147,7 +147,7 @@ def dash_to_camelcase(word):
def to_snake_case(name):
name = re.sub(r"([A-Z]{2,})([A-Z][a-z])", r"\1_\2", name)
return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name, sys.maxsize).lower()
return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name, count=sys.maxsize).lower()
def to_method_case(config, name):
@ -542,6 +542,12 @@ class Protocol(object):
return wrap_array_definition(self.resolve_type(prop["items"]))
return self.type_definitions[prop["type"]]
def optional_type(self, prop):
type = self.resolve_type(prop)
template = ("std::optional<{}>" if type.get('is_primitive', False)
else "std::unique_ptr<{}>")
return template.format(type.get("raw_type"))
def generate_command(self, domain, command):
if not self.config.protocol.options:
return domain in self.generate_domains

View file

@ -51,10 +51,10 @@ to fetch the package (and dependencies) and build and run the tests:
ninja -C out/Release crdtp_test
out/Release/crdtp_test
You'll probably also need to install g++, since Clang uses this to find the
You'll probably also need to install libstdc++, since Clang uses this to find the
standard C++ headers. E.g.,
sudo apt-get install g++-8
sudo apt-get install libstdc++-14-dev
# Purpose of the tests

View file

@ -255,7 +255,8 @@ class CRDTP_EXPORT CBORTokenizer {
span<uint8_t> GetString8() const;
// Wire representation for STRING16 is low byte first (little endian).
// To be called only if ::TokenTag() == CBORTokenTag::STRING16.
// To be called only if ::TokenTag() == CBORTokenTag::STRING16. The result is
// guaranteed to have even length.
span<uint8_t> GetString16WireRep() const;
// To be called only if ::TokenTag() == CBORTokenTag::BINARY.

View file

@ -169,10 +169,11 @@ TEST(DispatchableTest, MessageWithUnknownProperty) {
}
TEST(DispatchableTest, DuplicateMapKey) {
for (const std::string& json :
{"{\"id\":42,\"id\":42}", "{\"params\":null,\"params\":null}",
"{\"method\":\"foo\",\"method\":\"foo\"}",
"{\"sessionId\":\"42\",\"sessionId\":\"42\"}"}) {
const std::array<std::string, 4> jsons = {
{"{\"id\":42,\"id\":42}", "{\"params\":null,\"params\":null}",
"{\"method\":\"foo\",\"method\":\"foo\"}",
"{\"sessionId\":\"42\",\"sessionId\":\"42\"}"}};
for (const std::string& json : jsons) {
SCOPED_TRACE("json = " + json);
std::vector<uint8_t> cbor;
ASSERT_TRUE(json::ConvertJSONToCBOR(SpanFrom(json), &cbor).ok());
@ -185,11 +186,12 @@ TEST(DispatchableTest, DuplicateMapKey) {
}
TEST(DispatchableTest, ValidMessageParsesOK_NoParams) {
for (const std::string& json :
{"{\"id\":42,\"method\":\"Foo.executeBar\",\"sessionId\":"
"\"f421ssvaz4\"}",
"{\"id\":42,\"method\":\"Foo.executeBar\",\"sessionId\":\"f421ssvaz4\","
"\"params\":null}"}) {
const std::array<std::string, 2> jsons = {
{"{\"id\":42,\"method\":\"Foo.executeBar\",\"sessionId\":"
"\"f421ssvaz4\"}",
"{\"id\":42,\"method\":\"Foo.executeBar\",\"sessionId\":\"f421ssvaz4\","
"\"params\":null}"}};
for (const std::string& json : jsons) {
SCOPED_TRACE("json = " + json);
std::vector<uint8_t> cbor;
ASSERT_TRUE(json::ConvertJSONToCBOR(SpanFrom(json), &cbor).ok());

View file

@ -24,7 +24,7 @@ class CRDTP_EXPORT FrontendChannel {
// responses may be sent from an untrusted source to a trusted process (e.g.
// from Chromium's renderer (blink) to the browser process), which needs
// to be able to match the response to an earlier request without parsing the
// messsage.
// message.
virtual void SendProtocolResponse(int call_id,
std::unique_ptr<Serializable> message) = 0;
virtual void SendProtocolNotification(

View file

@ -704,15 +704,16 @@ using ContainerTestTypes = ::testing::Types<std::vector<uint8_t>, std::string>;
TYPED_TEST_SUITE(ConvertJSONToCBORTest, ContainerTestTypes);
TYPED_TEST(ConvertJSONToCBORTest, RoundTripValidJson) {
for (const std::string& json_in : {
"{\"msg\":\"Hello, world.\",\"lst\":[1,2,3]}",
"3.1415",
"false",
"true",
"\"Hello, world.\"",
"[1,2,3]",
"[]",
}) {
const std::array<std::string, 7> jsons = {{
"{\"msg\":\"Hello, world.\",\"lst\":[1,2,3]}",
"3.1415",
"false",
"true",
"\"Hello, world.\"",
"[1,2,3]",
"[]",
}};
for (const std::string& json_in : jsons) {
SCOPED_TRACE(json_in);
TypeParam json(json_in.begin(), json_in.end());
std::vector<uint8_t> cbor;

View file

@ -1,154 +0,0 @@
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CRDTP_MAYBE_H_
#define CRDTP_MAYBE_H_
#include <cassert>
#include <memory>
namespace crdtp {
// =============================================================================
// detail::PtrMaybe, detail::ValueMaybe, templates for optional
// pointers / values which are used in ../lib/Forward_h.template.
// =============================================================================
namespace detail {
template <typename T>
class PtrMaybe {
public:
PtrMaybe() = default;
PtrMaybe(std::unique_ptr<T> value) : value_(std::move(value)) {}
PtrMaybe(PtrMaybe&& other) noexcept : value_(std::move(other.value_)) {}
void operator=(std::unique_ptr<T> value) { value_ = std::move(value); }
// std::optional<>-compatible accessors (preferred).
bool has_value() const { return !!value_; }
operator bool() const { return has_value(); }
const T& value() const& {
assert(has_value());
return *value_;
}
T& value() & {
assert(has_value());
return *value_;
}
T&& value() && {
assert(has_value());
return std::move(*value_);
}
const T& value_or(const T& default_value) const {
return has_value() ? *value_ : default_value;
}
T* operator->() { return &value(); }
const T* operator->() const { return &value(); }
T& operator*() & { return value(); }
const T& operator*() const& { return value(); }
T&& operator*() && { return std::move(value()); }
// Legacy Maybe<> accessors (deprecated).
T* fromJust() const {
assert(value_);
return value_.get();
}
T* fromMaybe(T* default_value) const {
return value_ ? value_.get() : default_value;
}
bool isJust() const { return value_ != nullptr; }
private:
std::unique_ptr<T> value_;
};
template <typename T>
class ValueMaybe {
public:
ValueMaybe() : is_just_(false), value_() {}
ValueMaybe(T value) : is_just_(true), value_(std::move(value)) {}
ValueMaybe(ValueMaybe&& other) noexcept
: is_just_(other.is_just_), value_(std::move(other.value_)) {}
void operator=(T value) {
value_ = std::move(value);
is_just_ = true;
}
// std::optional<>-compatible accessors (preferred).
bool has_value() const { return is_just_; }
operator bool() const { return has_value(); }
const T& value() const& {
assert(is_just_);
return value_;
}
T& value() & {
assert(is_just_);
return value_;
}
T&& value() && {
assert(is_just_);
return *std::move(value_);
}
template <typename U>
T value_or(U&& default_value) const& {
return is_just_ ? value_ : std::forward<U>(default_value);
}
template <typename U>
T value_or(U&& default_value) && {
return is_just_ ? std::move(value_) : std::forward<U>(default_value);
}
T* operator->() { return &value(); }
const T* operator->() const { return &value(); }
T& operator*() & { return value(); }
const T& operator*() const& { return value(); }
T&& operator*() && { return std::move(value()); }
// Legacy Maybe<> accessors (deprecated).
const T& fromJust() const {
assert(is_just_);
return value_;
}
const T& fromMaybe(const T& default_value) const {
return is_just_ ? value_ : default_value;
}
bool isJust() const { return is_just_; }
private:
bool is_just_;
T value_;
};
template <typename T>
struct MaybeTypedef {
typedef PtrMaybe<T> type;
};
template <>
struct MaybeTypedef<bool> {
typedef ValueMaybe<bool> type;
};
template <>
struct MaybeTypedef<int> {
typedef ValueMaybe<int> type;
};
template <>
struct MaybeTypedef<double> {
typedef ValueMaybe<double> type;
};
template <>
struct MaybeTypedef<std::string> {
typedef ValueMaybe<std::string> type;
};
} // namespace detail
template <typename T>
using Maybe = typename detail::MaybeTypedef<T>::type;
} // namespace crdtp
#endif // CRDTP_MAYBE_H_

View file

@ -1,44 +0,0 @@
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "maybe.h"
#include <string>
#include <vector>
#include "test_platform.h"
namespace crdtp {
// =============================================================================
// detail::PtrMaybe, detail::ValueMaybe, templates for optional
// pointers / values which are used in ../lib/Forward_h.template.
// =============================================================================
TEST(PtrMaybeTest, SmokeTest) {
detail::PtrMaybe<std::vector<uint32_t>> example;
EXPECT_FALSE(example.has_value());
std::unique_ptr<std::vector<uint32_t>> v(new std::vector<uint32_t>);
v->push_back(42);
v->push_back(21);
example = std::move(v);
EXPECT_TRUE(example.has_value());
EXPECT_THAT(example.value(), testing::ElementsAre(42, 21));
std::vector<uint32_t> out = *std::move(example);
EXPECT_TRUE(example.has_value());
EXPECT_THAT(*example, testing::IsEmpty());
EXPECT_THAT(out, testing::ElementsAre(42, 21));
}
TEST(ValueMaybeTest, SmokeTest) {
detail::ValueMaybe<int32_t> example;
EXPECT_FALSE(example.has_value());
EXPECT_EQ(-1, example.value_or(-1));
example = 42;
EXPECT_TRUE(example.has_value());
EXPECT_EQ(42, example.value());
int32_t out = *std::move(example);
EXPECT_EQ(out, 42);
}
} // namespace crdtp

View file

@ -280,10 +280,10 @@ bool ProtocolTypeTraits<std::unique_ptr<DeferredMessage>>::Deserialize(
return true;
}
void ProtocolTypeTraits<std::unique_ptr<DeferredMessage>>::Serialize(
const std::unique_ptr<DeferredMessage>& value,
void ProtocolTypeTraits<DeferredMessage>::Serialize(
const DeferredMessage& value,
std::vector<uint8_t>* bytes) {
value->AppendSerialized(bytes);
value.AppendSerialized(bytes);
}
} // namespace crdtp

View file

@ -8,12 +8,12 @@
#include <sys/types.h>
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <vector>
#include "cbor.h"
#include "maybe.h"
#include "serializable.h"
#include "span.h"
#include "status.h"
@ -84,7 +84,7 @@ class CRDTP_EXPORT ContainerSerializer {
ProtocolTypeTraits<T>::Serialize(value, bytes_);
}
template <typename T>
void AddField(span<char> field_name, const detail::ValueMaybe<T>& value) {
void AddField(span<char> field_name, const std::optional<T>& value) {
if (!value.has_value()) {
return;
}
@ -92,11 +92,11 @@ class CRDTP_EXPORT ContainerSerializer {
}
template <typename T>
void AddField(span<char> field_name, const detail::PtrMaybe<T>& value) {
if (!value.has_value()) {
void AddField(span<char> field_name, const std::unique_ptr<T>& value) {
if (!value) {
return;
}
AddField(field_name, value.value());
AddField(field_name, *value);
}
void EncodeStop();
@ -209,14 +209,18 @@ template <>
struct CRDTP_EXPORT ProtocolTypeTraits<std::unique_ptr<DeferredMessage>> {
static bool Deserialize(DeserializerState* state,
std::unique_ptr<DeferredMessage>* value);
static void Serialize(const std::unique_ptr<DeferredMessage>& value,
};
template <>
struct CRDTP_EXPORT ProtocolTypeTraits<DeferredMessage> {
static void Serialize(const DeferredMessage& value,
std::vector<uint8_t>* bytes);
};
template <typename T>
struct ProtocolTypeTraits<detail::ValueMaybe<T>> {
struct ProtocolTypeTraits<std::optional<T>> {
static bool Deserialize(DeserializerState* state,
detail::ValueMaybe<T>* value) {
std::optional<T>* value) {
T res;
if (!ProtocolTypeTraits<T>::Deserialize(state, &res))
return false;
@ -224,24 +228,7 @@ struct ProtocolTypeTraits<detail::ValueMaybe<T>> {
return true;
}
static void Serialize(const detail::ValueMaybe<T>& value,
std::vector<uint8_t>* bytes) {
ProtocolTypeTraits<T>::Serialize(value.value(), bytes);
}
};
template <typename T>
struct ProtocolTypeTraits<detail::PtrMaybe<T>> {
static bool Deserialize(DeserializerState* state,
detail::PtrMaybe<T>* value) {
std::unique_ptr<T> res;
if (!ProtocolTypeTraits<std::unique_ptr<T>>::Deserialize(state, &res))
return false;
*value = std::move(res);
return true;
}
static void Serialize(const detail::PtrMaybe<T>& value,
static void Serialize(const std::optional<T>& value,
std::vector<uint8_t>* bytes) {
ProtocolTypeTraits<T>::Serialize(value.value(), bytes);
}

View file

@ -7,7 +7,6 @@
#include <memory>
#include "cbor.h"
#include "maybe.h"
#include "status_test_support.h"
#include "test_platform.h"
#include "test_string_traits.h"
@ -359,10 +358,9 @@ class TestTypeOptional : public ProtocolObject<TestTypeOptional> {
const std::string& GetStrField() const { return str_field_.value(); }
void SetStrField(std::string value) { str_field_ = std::move(value); }
bool HasTestTypeBasicField() { return test_type_basic_field_.has_value(); }
bool HasTestTypeBasicField() { return !!test_type_basic_field_; }
const TestTypeBasic* GetTestTypeBasicField() const {
return test_type_basic_field_.has_value() ? &test_type_basic_field_.value()
: nullptr;
return test_type_basic_field_.get();
}
void SetTestTypeBasicField(std::unique_ptr<TestTypeBasic> value) {
test_type_basic_field_ = std::move(value);
@ -371,9 +369,9 @@ class TestTypeOptional : public ProtocolObject<TestTypeOptional> {
private:
DECLARE_SERIALIZATION_SUPPORT();
Maybe<int> int_field_;
Maybe<std::string> str_field_;
Maybe<TestTypeBasic> test_type_basic_field_;
std::optional<int> int_field_;
std::optional<std::string> str_field_;
std::unique_ptr<TestTypeBasic> test_type_basic_field_;
};
// clang-format off

View file

@ -2,11 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
declare_args() {
# Where jinja2 is located, in chromium it is //third_party.
jinja_dir = "//third_party"
}
# This template will generate inspector protocol source code. The code will
# not be compiled, use get_target_outputs(<name>) to compile them.
#
@ -24,6 +19,9 @@ declare_args() {
#
# inputs (optional)
# Extra inputs specified by the config file.
#
# jinja_dir (optional)
# Custom path to jinja (defaults to "//third_party").
template("inspector_protocol_generate") {
assert(defined(invoker.config_file))
assert(defined(invoker.out_dir))
@ -32,6 +30,12 @@ template("inspector_protocol_generate") {
inspector_protocol_dir = invoker.inspector_protocol_dir
use_embedder_types =
defined(invoker.use_embedder_types) && invoker.use_embedder_types
if (defined(invoker.jinja_dir)) {
jinja_dir = invoker.jinja_dir
} else {
jinja_dir = "//third_party"
}
action(target_name) {
script = "$inspector_protocol_dir/code_generator.py"

View file

@ -54,12 +54,6 @@ class StringValue;
class Value;
{% endif %}
using {{config.crdtp.namespace}}::detail::PtrMaybe;
using {{config.crdtp.namespace}}::detail::ValueMaybe;
template<typename T>
using Maybe = {{config.crdtp.namespace}}::Maybe<T>;
namespace detail {
template <typename T>

View file

@ -87,8 +87,7 @@ class ValueParserHandler : public ParserHandler {
}
void HandleBinary(span<uint8_t> bytes) override {
AddValueToParent(
BinaryValue::create(Binary::fromSpan(bytes.data(), bytes.size())));
AddValueToParent(BinaryValue::create(Binary::fromSpan(bytes)));
}
void HandleDouble(double value) override {

View file

@ -116,7 +116,7 @@ const char* {{ literal | to_title_case}} = "{{literal}}";
void Frontend::{{event.name | to_method_case}}(
{%- for parameter in event.parameters %}
{% if "optional" in parameter -%}
Maybe<{{protocol.resolve_type(parameter).raw_type}}>
{{protocol.optional_type(parameter)}}
{%- else -%}
{{protocol.resolve_type(parameter).pass_type}}
{%- endif %} {{parameter.name}}{%- if not loop.last -%}, {% endif -%}
@ -215,7 +215,7 @@ public:
void sendSuccess(
{%- for parameter in command.returns -%}
{%- if "optional" in parameter -%}
Maybe<{{protocol.resolve_type(parameter).raw_type}}> {{parameter.name}}
{{protocol.optional_type(parameter)}} {{parameter.name}}
{%- else -%}
{{protocol.resolve_type(parameter).pass_type}} {{parameter.name}}
{%- endif -%}
@ -249,7 +249,7 @@ struct {{command.name}}Params : public {{config.crdtp.namespace}}::Deserializabl
{% for parameter in command.parameters %}
{% set parameter_type = protocol.resolve_type(parameter) %}
{% if parameter.optional %}
Maybe<{{parameter_type.raw_type}}> {{parameter.name}};
{{protocol.optional_type(parameter)}} {{parameter.name}};
{% else %}
{{parameter_type.type}} {{parameter.name}};
{% endif %}
@ -286,7 +286,7 @@ void DomainDispatcherImpl::{{command.name}}(const {{config.crdtp.namespace}}::Di
// Declare output parameters.
{% for parameter in command.returns %}
{% if "optional" in parameter %}
Maybe<{{protocol.resolve_type(parameter).raw_type}}> out_{{parameter.name}};
{{protocol.optional_type(parameter)}} out_{{parameter.name}};
{% else %}
{{protocol.resolve_type(parameter).type}} out_{{parameter.name}};
{% endif %}

View file

@ -89,16 +89,19 @@ public:
{% endif %}
{% if property.optional %}
bool {{"has" | to_method_case}}{{property_name}}() { return {{property_field}}.has_value(); }
bool {{"has" | to_method_case}}{{property_name}}() { return !!{{property_field}}; }
{% if property_type.is_primitive %}
{{property_type.raw_return_type}} {{"get" | to_method_case}}{{property_name}}({{property_type.raw_pass_type}} defaultValue) const {
return {{property_field}}.value_or(defaultValue);
}
{% else %}
{{property_type.raw_return_type}} {{"get" | to_method_case}}{{property_name}}({{property_type.raw_pass_type}} defaultValue) {
return {{property_field}}.has_value() ? &{{property_field}}.value() : defaultValue;
return {{property_field}} ? {{property_field}}.get() : defaultValue;
}
{% endif %}
const {{protocol.optional_type(property)}}& {{"get" | to_method_case}}{{property_name}}() const {
return {{property_field}};
}
{% else %}
{{property_type.raw_return_type}} {{"get" | to_method_case}}{{property_name}}() { return {{property_type.to_raw_type % property_field}}; }
{% endif %}
@ -175,7 +178,7 @@ private:
{% for property in type.properties %}
{% if property.optional %}
Maybe<{{protocol.resolve_type(property).raw_type}}> m_{{property.name}};
{{protocol.optional_type(property)}} m_{{property.name}};
{% else %}
{{protocol.resolve_type(property).type}} m_{{property.name}};
{% endif %}
@ -199,7 +202,7 @@ public:
virtual void sendSuccess(
{%- for parameter in command.returns -%}
{%- if "optional" in parameter -%}
Maybe<{{protocol.resolve_type(parameter).raw_type}}> {{parameter.name}}
{{protocol.optional_type(parameter)}} {{parameter.name}}
{%- else -%}
{{protocol.resolve_type(parameter).pass_type}} {{parameter.name}}
{%- endif -%}
@ -219,7 +222,7 @@ public:
{%- for parameter in command.parameters -%}
{%- if not loop.first -%}, {% endif -%}
{%- if "optional" in parameter -%}
Maybe<{{protocol.resolve_type(parameter).raw_type}}> in_{{parameter.name}}
{{protocol.optional_type(parameter)}} in_{{parameter.name}}
{%- else -%}
{{protocol.resolve_type(parameter).pass_type}} in_{{parameter.name}}
{%- endif -%}
@ -231,7 +234,7 @@ public:
{%- for parameter in command.returns -%}
{%- if (not loop.first) or command.parameters -%}, {% endif -%}
{%- if "optional" in parameter -%}
Maybe<{{protocol.resolve_type(parameter).raw_type}}>* out_{{parameter.name}}
{{protocol.optional_type(parameter)}}* out_{{parameter.name}}
{%- else -%}
{{protocol.resolve_type(parameter).type}}* out_{{parameter.name}}
{%- endif -%}
@ -258,7 +261,7 @@ public:
void {{event.name | to_method_case}}(
{%- for parameter in event.parameters -%}
{%- if "optional" in parameter -%}
Maybe<{{protocol.resolve_type(parameter).raw_type}}> {{parameter.name}} = Maybe<{{protocol.resolve_type(parameter).raw_type}}>()
{{protocol.optional_type(parameter)}} {{parameter.name}} = {}
{%- else -%}
{{protocol.resolve_type(parameter).pass_type}} {{parameter.name}}
{%- endif -%}{%- if not loop.last -%}, {% endif -%}