#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
#endif
#include "services/device/public/mojom/hid.mojom-blink.h"
#include <math.h>
#include <stdint.h>
#include <utility>
#include "base/debug/alias.h"
#include "base/hash/md5_constexpr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/typed_macros.h"
#include "mojo/public/cpp/bindings/features.h"
#include "mojo/public/cpp/bindings/lib/default_construct_tag_internal.h"
#include "mojo/public/cpp/bindings/lib/generated_code_util.h"
#include "mojo/public/cpp/bindings/lib/message_internal.h"
#include "mojo/public/cpp/bindings/lib/proxy_to_responder.h"
#include "mojo/public/cpp/bindings/lib/send_message_helper.h"
#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/cpp/bindings/lib/unserialized_message_context.h"
#include "mojo/public/cpp/bindings/lib/validate_params.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/mojo_buildflags.h"
#include "mojo/public/cpp/bindings/urgent_message_scope.h"
#include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
#include "services/device/public/mojom/hid.mojom-params-data.h"
#include "services/device/public/mojom/hid.mojom-shared-message-ids.h"
#include "services/device/public/mojom/hid.mojom-blink-import-headers.h"
#include "services/device/public/mojom/hid.mojom-blink-test-utils.h"
#include "mojo/public/cpp/bindings/lib/wtf_serialization.h"
namespace device::mojom::blink {
HidUsageAndPage::HidUsageAndPage()
: … { … }
HidUsageAndPage::HidUsageAndPage(
uint16_t usage_in,
uint16_t usage_page_in)
: … { … }
HidUsageAndPage::~HidUsageAndPage() = default;
size_t HidUsageAndPage::Hash(size_t seed) const { … }
void HidUsageAndPage::WriteIntoTrace(
perfetto::TracedValue traced_context) const { … }
bool HidUsageAndPage::Validate(
const void* data,
mojo::internal::ValidationContext* validation_context) { … }
HidReportItem::HidReportItem()
: … { … }
HidReportItem::HidReportItem(
bool is_range_in,
bool is_constant_in,
bool is_variable_in,
bool is_relative_in,
bool wrap_in,
bool is_non_linear_in,
bool no_preferred_state_in,
bool has_null_position_in,
bool is_volatile_in,
bool is_buffered_bytes_in,
WTF::Vector<HidUsageAndPagePtr> usages_in,
HidUsageAndPagePtr usage_minimum_in,
HidUsageAndPagePtr usage_maximum_in,
uint32_t designator_minimum_in,
uint32_t designator_maximum_in,
uint32_t string_minimum_in,
uint32_t string_maximum_in,
int32_t logical_minimum_in,
int32_t logical_maximum_in,
int32_t physical_minimum_in,
int32_t physical_maximum_in,
uint32_t unit_exponent_in,
uint32_t unit_in,
uint32_t report_size_in,
uint32_t report_count_in)
: … { … }
HidReportItem::~HidReportItem() = default;
void HidReportItem::WriteIntoTrace(
perfetto::TracedValue traced_context) const { … }
bool HidReportItem::Validate(
const void* data,
mojo::internal::ValidationContext* validation_context) { … }
HidReportDescription::HidReportDescription()
: … { … }
HidReportDescription::HidReportDescription(
uint8_t report_id_in,
WTF::Vector<HidReportItemPtr> items_in)
: … { … }
HidReportDescription::~HidReportDescription() = default;
void HidReportDescription::WriteIntoTrace(
perfetto::TracedValue traced_context) const { … }
bool HidReportDescription::Validate(
const void* data,
mojo::internal::ValidationContext* validation_context) { … }
HidCollectionInfo::HidCollectionInfo()
: … { … }
HidCollectionInfo::HidCollectionInfo(
HidUsageAndPagePtr usage_in,
WTF::Vector<uint8_t> report_ids_in,
uint32_t collection_type_in,
WTF::Vector<HidReportDescriptionPtr> input_reports_in,
WTF::Vector<HidReportDescriptionPtr> output_reports_in,
WTF::Vector<HidReportDescriptionPtr> feature_reports_in,
WTF::Vector<HidCollectionInfoPtr> children_in)
: … { … }
HidCollectionInfo::~HidCollectionInfo() = default;
void HidCollectionInfo::WriteIntoTrace(
perfetto::TracedValue traced_context) const { … }
bool HidCollectionInfo::Validate(
const void* data,
mojo::internal::ValidationContext* validation_context) { … }
HidDeviceInfo::HidDeviceInfo()
: … { … }
HidDeviceInfo::HidDeviceInfo(
const WTF::String& guid_in,
const WTF::String& physical_device_id_in,
uint16_t vendor_id_in,
uint16_t product_id_in,
const WTF::String& product_name_in,
const WTF::String& serial_number_in,
HidBusType bus_type_in,
WTF::Vector<uint8_t> report_descriptor_in,
WTF::Vector<HidCollectionInfoPtr> collections_in,
bool has_report_id_in,
uint64_t max_input_report_size_in,
uint64_t max_output_report_size_in,
uint64_t max_feature_report_size_in,
const WTF::String& device_node_in)
: … { … }
HidDeviceInfo::HidDeviceInfo(
const WTF::String& guid_in,
const WTF::String& physical_device_id_in,
uint16_t vendor_id_in,
uint16_t product_id_in,
const WTF::String& product_name_in,
const WTF::String& serial_number_in,
HidBusType bus_type_in,
WTF::Vector<uint8_t> report_descriptor_in,
WTF::Vector<HidCollectionInfoPtr> collections_in,
bool has_report_id_in,
uint64_t max_input_report_size_in,
uint64_t max_output_report_size_in,
uint64_t max_feature_report_size_in,
const WTF::String& device_node_in,
std::optional<WTF::Vector<uint8_t>> protected_input_report_ids_in,
std::optional<WTF::Vector<uint8_t>> protected_output_report_ids_in,
std::optional<WTF::Vector<uint8_t>> protected_feature_report_ids_in)
: … { … }
HidDeviceInfo::HidDeviceInfo(
const WTF::String& guid_in,
const WTF::String& physical_device_id_in,
uint16_t vendor_id_in,
uint16_t product_id_in,
const WTF::String& product_name_in,
const WTF::String& serial_number_in,
HidBusType bus_type_in,
WTF::Vector<uint8_t> report_descriptor_in,
WTF::Vector<HidCollectionInfoPtr> collections_in,
bool has_report_id_in,
uint64_t max_input_report_size_in,
uint64_t max_output_report_size_in,
uint64_t max_feature_report_size_in,
const WTF::String& device_node_in,
std::optional<WTF::Vector<uint8_t>> protected_input_report_ids_in,
std::optional<WTF::Vector<uint8_t>> protected_output_report_ids_in,
std::optional<WTF::Vector<uint8_t>> protected_feature_report_ids_in,
bool is_excluded_by_blocklist_in)
: … { … }
HidDeviceInfo::~HidDeviceInfo() = default;
void HidDeviceInfo::WriteIntoTrace(
perfetto::TracedValue traced_context) const { … }
bool HidDeviceInfo::Validate(
const void* data,
mojo::internal::ValidationContext* validation_context) { … }
const char HidManagerClient::Name_[] = …;
constexpr base::Token HidManagerClient::Uuid_;
HidManagerClient::IPCStableHashFunction HidManagerClient::MessageToMethodInfo_(mojo::Message& message) { … }
const char* HidManagerClient::MessageToMethodName_(mojo::Message& message) { … }
#if !BUILDFLAG(IS_FUCHSIA)
uint32_t HidManagerClient::DeviceAdded_Sym::IPCStableHash() { … }
uint32_t HidManagerClient::DeviceRemoved_Sym::IPCStableHash() { … }
uint32_t HidManagerClient::DeviceChanged_Sym::IPCStableHash() { … }
# endif
HidManagerClientProxy::HidManagerClientProxy(mojo::MessageReceiverWithResponder* receiver)
: … { … }
void HidManagerClientProxy::DeviceAdded(
HidDeviceInfoPtr in_device_info) { … }
void HidManagerClientProxy::DeviceRemoved(
HidDeviceInfoPtr in_device_info) { … }
void HidManagerClientProxy::DeviceChanged(
HidDeviceInfoPtr in_device_info) { … }
bool HidManagerClientStubDispatch::Accept(
HidManagerClient* impl,
mojo::Message* message) { … }
bool HidManagerClientStubDispatch::AcceptWithResponder(
HidManagerClient* impl,
mojo::Message* message,
std::unique_ptr<mojo::MessageReceiverWithStatus> responder) { … }
namespace {
}
static const mojo::internal::GenericValidationInfo kHidManagerClientValidationInfo[] = …;
bool HidManagerClientRequestValidator::Accept(mojo::Message* message) { … }
const char HidManager::Name_[] = …;
constexpr base::Token HidManager::Uuid_;
HidManager::IPCStableHashFunction HidManager::MessageToMethodInfo_(mojo::Message& message) { … }
const char* HidManager::MessageToMethodName_(mojo::Message& message) { … }
#if !BUILDFLAG(IS_FUCHSIA)
uint32_t HidManager::GetDevicesAndSetClient_Sym::IPCStableHash() { … }
uint32_t HidManager::GetDevices_Sym::IPCStableHash() { … }
uint32_t HidManager::Connect_Sym::IPCStableHash() { … }
uint32_t HidManager::AddReceiver_Sym::IPCStableHash() { … }
# endif
class HidManager_GetDevicesAndSetClient_ForwardToCallback
: public mojo::MessageReceiver { … };
class HidManager_GetDevices_ForwardToCallback
: public mojo::MessageReceiver { … };
class HidManager_Connect_ForwardToCallback
: public mojo::MessageReceiver { … };
HidManagerProxy::HidManagerProxy(mojo::MessageReceiverWithResponder* receiver)
: … { … }
void HidManagerProxy::GetDevicesAndSetClient(
::mojo::PendingAssociatedRemote<HidManagerClient> in_client, GetDevicesAndSetClientCallback callback) { … }
void HidManagerProxy::GetDevices(
GetDevicesCallback callback) { … }
void HidManagerProxy::Connect(
const WTF::String& in_device_guid, ::mojo::PendingRemote<HidConnectionClient> in_connection_client, ::mojo::PendingRemote<HidConnectionWatcher> in_watcher, bool in_allow_protected_reports, bool in_allow_fido_reports, ConnectCallback callback) { … }
void HidManagerProxy::AddReceiver(
::mojo::PendingReceiver<HidManager> in_receiver) { … }
class HidManager_GetDevicesAndSetClient_ProxyToResponder : public ::mojo::internal::ProxyToResponder { … };
bool HidManager_GetDevicesAndSetClient_ForwardToCallback::Accept(
mojo::Message* message) { … }
void HidManager_GetDevicesAndSetClient_ProxyToResponder::Run(
WTF::Vector<HidDeviceInfoPtr> in_devices) { … }
class HidManager_GetDevices_ProxyToResponder : public ::mojo::internal::ProxyToResponder { … };
bool HidManager_GetDevices_ForwardToCallback::Accept(
mojo::Message* message) { … }
void HidManager_GetDevices_ProxyToResponder::Run(
WTF::Vector<HidDeviceInfoPtr> in_devices) { … }
class HidManager_Connect_ProxyToResponder : public ::mojo::internal::ProxyToResponder { … };
bool HidManager_Connect_ForwardToCallback::Accept(
mojo::Message* message) { … }
void HidManager_Connect_ProxyToResponder::Run(
::mojo::PendingRemote<HidConnection> in_connection) { … }
bool HidManagerStubDispatch::Accept(
HidManager* impl,
mojo::Message* message) { … }
bool HidManagerStubDispatch::AcceptWithResponder(
HidManager* impl,
mojo::Message* message,
std::unique_ptr<mojo::MessageReceiverWithStatus> responder) { … }
namespace {
}
static const mojo::internal::GenericValidationInfo kHidManagerValidationInfo[] = …;
bool HidManagerRequestValidator::Accept(mojo::Message* message) { … }
bool HidManagerResponseValidator::Accept(mojo::Message* message) { … }
const char HidConnection::Name_[] = …;
constexpr base::Token HidConnection::Uuid_;
HidConnection::IPCStableHashFunction HidConnection::MessageToMethodInfo_(mojo::Message& message) { … }
const char* HidConnection::MessageToMethodName_(mojo::Message& message) { … }
#if !BUILDFLAG(IS_FUCHSIA)
uint32_t HidConnection::Read_Sym::IPCStableHash() { … }
uint32_t HidConnection::Write_Sym::IPCStableHash() { … }
uint32_t HidConnection::GetFeatureReport_Sym::IPCStableHash() { … }
uint32_t HidConnection::SendFeatureReport_Sym::IPCStableHash() { … }
# endif
class HidConnection_Read_ForwardToCallback
: public mojo::MessageReceiver { … };
class HidConnection_Write_ForwardToCallback
: public mojo::MessageReceiver { … };
class HidConnection_GetFeatureReport_ForwardToCallback
: public mojo::MessageReceiver { … };
class HidConnection_SendFeatureReport_ForwardToCallback
: public mojo::MessageReceiver { … };
HidConnectionProxy::HidConnectionProxy(mojo::MessageReceiverWithResponder* receiver)
: … { … }
void HidConnectionProxy::Read(
ReadCallback callback) { … }
void HidConnectionProxy::Write(
uint8_t in_report_id, const WTF::Vector<uint8_t>& in_buffer, WriteCallback callback) { … }
void HidConnectionProxy::GetFeatureReport(
uint8_t in_report_id, GetFeatureReportCallback callback) { … }
void HidConnectionProxy::SendFeatureReport(
uint8_t in_report_id, const WTF::Vector<uint8_t>& in_buffer, SendFeatureReportCallback callback) { … }
class HidConnection_Read_ProxyToResponder : public ::mojo::internal::ProxyToResponder { … };
bool HidConnection_Read_ForwardToCallback::Accept(
mojo::Message* message) { … }
void HidConnection_Read_ProxyToResponder::Run(
bool in_success, uint8_t in_report_id, const std::optional<WTF::Vector<uint8_t>>& in_buffer) { … }
class HidConnection_Write_ProxyToResponder : public ::mojo::internal::ProxyToResponder { … };
bool HidConnection_Write_ForwardToCallback::Accept(
mojo::Message* message) { … }
void HidConnection_Write_ProxyToResponder::Run(
bool in_success) { … }
class HidConnection_GetFeatureReport_ProxyToResponder : public ::mojo::internal::ProxyToResponder { … };
bool HidConnection_GetFeatureReport_ForwardToCallback::Accept(
mojo::Message* message) { … }
void HidConnection_GetFeatureReport_ProxyToResponder::Run(
bool in_success, const std::optional<WTF::Vector<uint8_t>>& in_buffer) { … }
class HidConnection_SendFeatureReport_ProxyToResponder : public ::mojo::internal::ProxyToResponder { … };
bool HidConnection_SendFeatureReport_ForwardToCallback::Accept(
mojo::Message* message) { … }
void HidConnection_SendFeatureReport_ProxyToResponder::Run(
bool in_success) { … }
bool HidConnectionStubDispatch::Accept(
HidConnection* impl,
mojo::Message* message) { … }
bool HidConnectionStubDispatch::AcceptWithResponder(
HidConnection* impl,
mojo::Message* message,
std::unique_ptr<mojo::MessageReceiverWithStatus> responder) { … }
namespace {
}
static const mojo::internal::GenericValidationInfo kHidConnectionValidationInfo[] = …;
bool HidConnectionRequestValidator::Accept(mojo::Message* message) { … }
bool HidConnectionResponseValidator::Accept(mojo::Message* message) { … }
const char HidConnectionClient::Name_[] = …;
constexpr base::Token HidConnectionClient::Uuid_;
HidConnectionClient::IPCStableHashFunction HidConnectionClient::MessageToMethodInfo_(mojo::Message& message) { … }
const char* HidConnectionClient::MessageToMethodName_(mojo::Message& message) { … }
#if !BUILDFLAG(IS_FUCHSIA)
uint32_t HidConnectionClient::OnInputReport_Sym::IPCStableHash() { … }
# endif
HidConnectionClientProxy::HidConnectionClientProxy(mojo::MessageReceiverWithResponder* receiver)
: … { … }
void HidConnectionClientProxy::OnInputReport(
uint8_t in_report_id, const WTF::Vector<uint8_t>& in_buffer) { … }
bool HidConnectionClientStubDispatch::Accept(
HidConnectionClient* impl,
mojo::Message* message) { … }
bool HidConnectionClientStubDispatch::AcceptWithResponder(
HidConnectionClient* impl,
mojo::Message* message,
std::unique_ptr<mojo::MessageReceiverWithStatus> responder) { … }
namespace {
}
static const mojo::internal::GenericValidationInfo kHidConnectionClientValidationInfo[] = …;
bool HidConnectionClientRequestValidator::Accept(mojo::Message* message) { … }
const char HidConnectionWatcher::Name_[] = …;
constexpr base::Token HidConnectionWatcher::Uuid_;
HidConnectionWatcher::IPCStableHashFunction HidConnectionWatcher::MessageToMethodInfo_(mojo::Message& message) { … }
const char* HidConnectionWatcher::MessageToMethodName_(mojo::Message& message) { … }
#if !BUILDFLAG(IS_FUCHSIA)
# endif
HidConnectionWatcherProxy::HidConnectionWatcherProxy(mojo::MessageReceiverWithResponder* receiver)
: … { … }
bool HidConnectionWatcherStubDispatch::Accept(
HidConnectionWatcher* impl,
mojo::Message* message) { … }
bool HidConnectionWatcherStubDispatch::AcceptWithResponder(
HidConnectionWatcher* impl,
mojo::Message* message,
std::unique_ptr<mojo::MessageReceiverWithStatus> responder) { … }
namespace {
}
bool HidConnectionWatcherRequestValidator::Accept(mojo::Message* message) { … }
}
namespace mojo {
bool StructTraits<::device::mojom::blink::HidUsageAndPage::DataView, ::device::mojom::blink::HidUsageAndPagePtr>::Read(
::device::mojom::blink::HidUsageAndPage::DataView input,
::device::mojom::blink::HidUsageAndPagePtr* output) { … }
bool StructTraits<::device::mojom::blink::HidReportItem::DataView, ::device::mojom::blink::HidReportItemPtr>::Read(
::device::mojom::blink::HidReportItem::DataView input,
::device::mojom::blink::HidReportItemPtr* output) { … }
bool StructTraits<::device::mojom::blink::HidReportDescription::DataView, ::device::mojom::blink::HidReportDescriptionPtr>::Read(
::device::mojom::blink::HidReportDescription::DataView input,
::device::mojom::blink::HidReportDescriptionPtr* output) { … }
bool StructTraits<::device::mojom::blink::HidCollectionInfo::DataView, ::device::mojom::blink::HidCollectionInfoPtr>::Read(
::device::mojom::blink::HidCollectionInfo::DataView input,
::device::mojom::blink::HidCollectionInfoPtr* output) { … }
bool StructTraits<::device::mojom::blink::HidDeviceInfo::DataView, ::device::mojom::blink::HidDeviceInfoPtr>::Read(
::device::mojom::blink::HidDeviceInfo::DataView input,
::device::mojom::blink::HidDeviceInfoPtr* output) { … }
}
namespace device::mojom::blink {
void HidManagerClientInterceptorForTesting::DeviceAdded(HidDeviceInfoPtr device_info) { … }
void HidManagerClientInterceptorForTesting::DeviceRemoved(HidDeviceInfoPtr device_info) { … }
void HidManagerClientInterceptorForTesting::DeviceChanged(HidDeviceInfoPtr device_info) { … }
HidManagerClientAsyncWaiter::HidManagerClientAsyncWaiter(
HidManagerClient* proxy) : … { … }
HidManagerClientAsyncWaiter::~HidManagerClientAsyncWaiter() = default;
void HidManagerInterceptorForTesting::GetDevicesAndSetClient(::mojo::PendingAssociatedRemote<HidManagerClient> client, GetDevicesAndSetClientCallback callback) { … }
void HidManagerInterceptorForTesting::GetDevices(GetDevicesCallback callback) { … }
void HidManagerInterceptorForTesting::Connect(const WTF::String& device_guid, ::mojo::PendingRemote<HidConnectionClient> connection_client, ::mojo::PendingRemote<HidConnectionWatcher> watcher, bool allow_protected_reports, bool allow_fido_reports, ConnectCallback callback) { … }
void HidManagerInterceptorForTesting::AddReceiver(::mojo::PendingReceiver<HidManager> receiver) { … }
HidManagerAsyncWaiter::HidManagerAsyncWaiter(
HidManager* proxy) : … { … }
HidManagerAsyncWaiter::~HidManagerAsyncWaiter() = default;
void HidManagerAsyncWaiter::GetDevicesAndSetClient(
::mojo::PendingAssociatedRemote<HidManagerClient> client, WTF::Vector<HidDeviceInfoPtr>* out_devices) { … }
WTF::Vector<HidDeviceInfoPtr> HidManagerAsyncWaiter::GetDevicesAndSetClient(
::mojo::PendingAssociatedRemote<HidManagerClient> client) { … }
void HidManagerAsyncWaiter::GetDevices(
WTF::Vector<HidDeviceInfoPtr>* out_devices) { … }
WTF::Vector<HidDeviceInfoPtr> HidManagerAsyncWaiter::GetDevices(
) { … }
void HidManagerAsyncWaiter::Connect(
const WTF::String& device_guid, ::mojo::PendingRemote<HidConnectionClient> connection_client, ::mojo::PendingRemote<HidConnectionWatcher> watcher, bool allow_protected_reports, bool allow_fido_reports, ::mojo::PendingRemote<HidConnection>* out_connection) { … }
::mojo::PendingRemote<HidConnection> HidManagerAsyncWaiter::Connect(
const WTF::String& device_guid, ::mojo::PendingRemote<HidConnectionClient> connection_client, ::mojo::PendingRemote<HidConnectionWatcher> watcher, bool allow_protected_reports, bool allow_fido_reports) { … }
void HidConnectionInterceptorForTesting::Read(ReadCallback callback) { … }
void HidConnectionInterceptorForTesting::Write(uint8_t report_id, const WTF::Vector<uint8_t>& buffer, WriteCallback callback) { … }
void HidConnectionInterceptorForTesting::GetFeatureReport(uint8_t report_id, GetFeatureReportCallback callback) { … }
void HidConnectionInterceptorForTesting::SendFeatureReport(uint8_t report_id, const WTF::Vector<uint8_t>& buffer, SendFeatureReportCallback callback) { … }
HidConnectionAsyncWaiter::HidConnectionAsyncWaiter(
HidConnection* proxy) : … { … }
HidConnectionAsyncWaiter::~HidConnectionAsyncWaiter() = default;
void HidConnectionAsyncWaiter::Read(
bool* out_success, uint8_t* out_report_id, std::optional<WTF::Vector<uint8_t>>* out_buffer) { … }
void HidConnectionAsyncWaiter::Write(
uint8_t report_id, const WTF::Vector<uint8_t>& buffer, bool* out_success) { … }
bool HidConnectionAsyncWaiter::Write(
uint8_t report_id, const WTF::Vector<uint8_t>& buffer) { … }
void HidConnectionAsyncWaiter::GetFeatureReport(
uint8_t report_id, bool* out_success, std::optional<WTF::Vector<uint8_t>>* out_buffer) { … }
void HidConnectionAsyncWaiter::SendFeatureReport(
uint8_t report_id, const WTF::Vector<uint8_t>& buffer, bool* out_success) { … }
bool HidConnectionAsyncWaiter::SendFeatureReport(
uint8_t report_id, const WTF::Vector<uint8_t>& buffer) { … }
void HidConnectionClientInterceptorForTesting::OnInputReport(uint8_t report_id, const WTF::Vector<uint8_t>& buffer) { … }
HidConnectionClientAsyncWaiter::HidConnectionClientAsyncWaiter(
HidConnectionClient* proxy) : … { … }
HidConnectionClientAsyncWaiter::~HidConnectionClientAsyncWaiter() = default;
HidConnectionWatcherAsyncWaiter::HidConnectionWatcherAsyncWaiter(
HidConnectionWatcher* proxy) : … { … }
HidConnectionWatcherAsyncWaiter::~HidConnectionWatcherAsyncWaiter() = default;
}
#if defined(__clang__)
#pragma clang diagnostic pop
#endif