#ifndef MOJO_PUBLIC_CPP_BASE_PROTO_WRAPPER_H_
#define MOJO_PUBLIC_CPP_BASE_PROTO_WRAPPER_H_
#include <optional>
#include <string>
#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/gtest_prod_util.h"
#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/base/proto_wrapper_passkeys.h"
#include "mojo/public/cpp/bindings/default_construct_tag.h"
namespace google::protobuf {
class MessageLite;
}
namespace mojo_base {
namespace mojom {
class ProtoWrapperDataView;
}
template <typename T>
concept IsProtoMessage =
!std::is_abstract<T>() &&
std::is_base_of<google::protobuf::MessageLite, T>::value;
class COMPONENT_EXPORT(MOJO_BASE_PROTOBUF_SUPPORT) ProtoWrapper {
public:
ProtoWrapper(ProtoWrapper&& other);
ProtoWrapper& operator=(ProtoWrapper&& other);
ProtoWrapper(const ProtoWrapper&) = delete;
ProtoWrapper& operator=(const ProtoWrapper&) = delete;
~ProtoWrapper();
explicit ProtoWrapper(mojo::DefaultConstruct::Tag passkey);
explicit ProtoWrapper(const google::protobuf::MessageLite& message);
explicit ProtoWrapper(base::span<const uint8_t> data,
std::string type_name,
base::PassKey<ProtoWrapperBytes> passkey);
template <IsProtoMessage ProtoMessage>
std::optional<ProtoMessage> As() const {
ProtoMessage message;
if (DeserializeToMessage(message)) {
return message;
}
return std::nullopt;
}
std::optional<base::span<const uint8_t>> byte_span(
base::PassKey<ProtoWrapperBytes> passkey) const {
if (!is_valid()) {
return std::nullopt;
}
return base::span(*bytes_);
}
private:
friend struct mojo::StructTraits<mojo_base::mojom::ProtoWrapperDataView,
mojo_base::ProtoWrapper>;
FRIEND_TEST_ALL_PREFIXES(ProtoWrapperTest, TraitsOk);
FRIEND_TEST_ALL_PREFIXES(ProtoWrapperTest, LargeMessage);
FRIEND_TEST_ALL_PREFIXES(ProtoWrapperTest, TraitsEquivilentMessages);
FRIEND_TEST_ALL_PREFIXES(ProtoWrapperTest, TraitsDistinctMessages);
FRIEND_TEST_ALL_PREFIXES(ProtoWrapperTest, ToFromBytes);
ProtoWrapper();
bool is_valid() const { return bytes_.has_value(); }
bool DeserializeToMessage(google::protobuf::MessageLite& message) const;
std::string proto_name_;
std::optional<BigBuffer> bytes_;
};
}
#endif