Skip to content

Commit

Permalink
some refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
huangminghuang committed Jan 22, 2024
1 parent d13785e commit 48f67d4
Show file tree
Hide file tree
Showing 9 changed files with 351 additions and 374 deletions.
32 changes: 16 additions & 16 deletions include/google/protobuf/compiler/plugin.pb.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,34 @@
namespace google::protobuf::compiler {

auto pb_meta(const Version &) -> std::tuple<
hpp::proto::field_meta<1, &Version::major, hpp::proto::encoding_rule::defaulted, hpp::proto::vint64_t>,
hpp::proto::field_meta<2, &Version::minor, hpp::proto::encoding_rule::defaulted, hpp::proto::vint64_t>,
hpp::proto::field_meta<3, &Version::patch, hpp::proto::encoding_rule::defaulted, hpp::proto::vint64_t>,
hpp::proto::field_meta<4, &Version::suffix, hpp::proto::encoding_rule::defaulted>>;
hpp::proto::field_meta<1, &Version::major, hpp::proto::field_option::none, hpp::proto::vint64_t>,
hpp::proto::field_meta<2, &Version::minor, hpp::proto::field_option::none, hpp::proto::vint64_t>,
hpp::proto::field_meta<3, &Version::patch, hpp::proto::field_option::none, hpp::proto::vint64_t>,
hpp::proto::field_meta<4, &Version::suffix, hpp::proto::field_option::none>>;

constexpr auto pb_message_name(const Version&) { return "google.protobuf.compiler.Version"_cts; }

auto pb_meta(const CodeGeneratorRequest &) -> std::tuple<
hpp::proto::field_meta<1, &CodeGeneratorRequest::file_to_generate, hpp::proto::encoding_rule::unpacked_repeated>,
hpp::proto::field_meta<2, &CodeGeneratorRequest::parameter, hpp::proto::encoding_rule::defaulted>,
hpp::proto::field_meta<15, &CodeGeneratorRequest::proto_file, hpp::proto::encoding_rule::unpacked_repeated>,
hpp::proto::field_meta<17, &CodeGeneratorRequest::source_file_descriptors, hpp::proto::encoding_rule::unpacked_repeated>,
hpp::proto::field_meta<3, &CodeGeneratorRequest::compiler_version, hpp::proto::encoding_rule::explicit_presence>>;
hpp::proto::field_meta<1, &CodeGeneratorRequest::file_to_generate, hpp::proto::field_option::unpacked_repeated>,
hpp::proto::field_meta<2, &CodeGeneratorRequest::parameter, hpp::proto::field_option::none>,
hpp::proto::field_meta<15, &CodeGeneratorRequest::proto_file, hpp::proto::field_option::unpacked_repeated>,
hpp::proto::field_meta<17, &CodeGeneratorRequest::source_file_descriptors, hpp::proto::field_option::unpacked_repeated>,
hpp::proto::field_meta<3, &CodeGeneratorRequest::compiler_version, hpp::proto::field_option::explicit_presence>>;

constexpr auto pb_message_name(const CodeGeneratorRequest&) { return "google.protobuf.compiler.CodeGeneratorRequest"_cts; }

auto pb_meta(const CodeGeneratorResponse &) -> std::tuple<
hpp::proto::field_meta<1, &CodeGeneratorResponse::error, hpp::proto::encoding_rule::defaulted>,
hpp::proto::field_meta<2, &CodeGeneratorResponse::supported_features, hpp::proto::encoding_rule::defaulted, hpp::proto::vuint64_t>,
hpp::proto::field_meta<15, &CodeGeneratorResponse::file, hpp::proto::encoding_rule::unpacked_repeated>>;
hpp::proto::field_meta<1, &CodeGeneratorResponse::error, hpp::proto::field_option::none>,
hpp::proto::field_meta<2, &CodeGeneratorResponse::supported_features, hpp::proto::field_option::none, hpp::proto::vuint64_t>,
hpp::proto::field_meta<15, &CodeGeneratorResponse::file, hpp::proto::field_option::unpacked_repeated>>;

constexpr auto pb_message_name(const CodeGeneratorResponse&) { return "google.protobuf.compiler.CodeGeneratorResponse"_cts; }

auto pb_meta(const CodeGeneratorResponse::File &) -> std::tuple<
hpp::proto::field_meta<1, &CodeGeneratorResponse::File::name, hpp::proto::encoding_rule::defaulted>,
hpp::proto::field_meta<2, &CodeGeneratorResponse::File::insertion_point, hpp::proto::encoding_rule::defaulted>,
hpp::proto::field_meta<15, &CodeGeneratorResponse::File::content, hpp::proto::encoding_rule::defaulted>,
hpp::proto::field_meta<16, &CodeGeneratorResponse::File::generated_code_info, hpp::proto::encoding_rule::explicit_presence>>;
hpp::proto::field_meta<1, &CodeGeneratorResponse::File::name, hpp::proto::field_option::none>,
hpp::proto::field_meta<2, &CodeGeneratorResponse::File::insertion_point, hpp::proto::field_option::none>,
hpp::proto::field_meta<15, &CodeGeneratorResponse::File::content, hpp::proto::field_option::none>,
hpp::proto::field_meta<16, &CodeGeneratorResponse::File::generated_code_info, hpp::proto::field_option::explicit_presence>>;

constexpr auto pb_message_name(const CodeGeneratorResponse::File&) { return "google.protobuf.compiler.CodeGeneratorResponse.File"_cts; }

Expand Down
320 changes: 160 additions & 160 deletions include/google/protobuf/descriptor.pb.hpp

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions include/hpp_proto/dynamic_serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ struct Any {
std::string type_url = {};
std::vector<std::byte> value = {};
};
auto pb_meta(const Any &) -> std::tuple<hpp::proto::field_meta<1, &Any::type_url, hpp::proto::encoding_rule::defaulted>,
hpp::proto::field_meta<2, &Any::value, hpp::proto::encoding_rule::defaulted>>;
auto pb_meta(const Any &) -> std::tuple<hpp::proto::field_meta<1, &Any::type_url, hpp::proto::field_option::none>,
hpp::proto::field_meta<2, &Any::value, hpp::proto::field_option::none>>;

struct Duration {
constexpr static bool glaze_reflect = false;
Expand All @@ -49,8 +49,8 @@ struct Duration {
};

auto pb_meta(const Duration &) -> std::tuple<
hpp::proto::field_meta<1, &Duration::seconds, hpp::proto::encoding_rule::defaulted, hpp::proto::vint64_t>,
hpp::proto::field_meta<2, &Duration::nanos, hpp::proto::encoding_rule::defaulted, hpp::proto::vint64_t>>;
hpp::proto::field_meta<1, &Duration::seconds, hpp::proto::field_option::none, hpp::proto::vint64_t>,
hpp::proto::field_meta<2, &Duration::nanos, hpp::proto::field_option::none, hpp::proto::vint64_t>>;

struct Timestamp {
constexpr static bool glaze_reflect = false;
Expand All @@ -59,16 +59,16 @@ struct Timestamp {
};

auto pb_meta(const Timestamp &) -> std::tuple<
hpp::proto::field_meta<1, &Timestamp::seconds, hpp::proto::encoding_rule::defaulted, hpp::proto::vint64_t>,
hpp::proto::field_meta<2, &Timestamp::nanos, hpp::proto::encoding_rule::defaulted, hpp::proto::vint64_t>>;
hpp::proto::field_meta<1, &Timestamp::seconds, hpp::proto::field_option::none, hpp::proto::vint64_t>,
hpp::proto::field_meta<2, &Timestamp::nanos, hpp::proto::field_option::none, hpp::proto::vint64_t>>;

struct FieldMask {
constexpr static bool glaze_reflect = false;
std::vector<std::string> paths;
};

auto pb_meta(const FieldMask &)
-> std::tuple<hpp::proto::field_meta<1, &FieldMask::paths, hpp::proto::encoding_rule::unpacked_repeated>>;
-> std::tuple<hpp::proto::field_meta<1, &FieldMask::paths, hpp::proto::field_option::unpacked_repeated>>;
} // namespace wellknown

template <>
Expand Down
115 changes: 46 additions & 69 deletions include/hpp_proto/pb_serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@
#include <climits>
#include <concepts>
#include <cstring>
#include <glaze/util/expected.hpp>
#include <map>
#include <memory>
#include <numeric>
#include <system_error>
#include <glaze/util/expected.hpp>
// #include <hpp_proto/expected.h>
#include <hpp_proto/memory_resource_utils.h>

namespace hpp {
namespace proto {
using glz::expected;
using glz::unexpected;
using glz::expected;
using glz::unexpected;
/////////////////////////////////////////////////////////////////
// varint code is based on https://github.com/eyalz800/zpp_bits
/////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -95,7 +95,8 @@ concept associative_container =
std::ranges::range<Type> && requires(Type container) { typename std::remove_cvref_t<Type>::key_type; };

template <typename Type>
concept tuple = !std::ranges::range<Type> && requires(Type tuple) { sizeof(std::tuple_size<std::remove_cvref_t<Type>>); };
concept tuple =
!std::ranges::range<Type> && requires(Type tuple) { sizeof(std::tuple_size<std::remove_cvref_t<Type>>); };

template <typename Type>
concept variant = requires(Type variant) {
Expand Down Expand Up @@ -198,12 +199,11 @@ concept is_basic_out = requires { typename Type::is_basic_out; };

} // namespace concepts

enum class encoding_rule {
defaulted = 0,
enum field_option {
none = 0,
explicit_presence = 1,
unpacked_repeated = 2,
group = 3,
packed_repeated = 4
group = 4
};

template <auto Accessor>
Expand All @@ -216,17 +216,19 @@ struct accesor_type {
}
};

template <uint32_t Number, auto Accessor, encoding_rule Encoding = encoding_rule::defaulted, typename Type = void,
auto DefaultValue = std::monostate{}>
struct field_meta {
template <uint32_t Number, int options, typename Type, auto DefaultValue>
struct field_meta_base {

constexpr static uint32_t number = Number;
constexpr static encoding_rule encoding = Encoding;
constexpr static auto access = accesor_type<Accessor>{};
using type = Type;

constexpr static bool is_explicit_presence = (options & field_option::explicit_presence);
constexpr static bool is_unpacked_repeated = (options & field_option::unpacked_repeated);
constexpr static bool is_group = (options & field_option::group);

template <typename T>
inline static constexpr bool omit_value(const T &v) {
if constexpr (Encoding == encoding_rule::defaulted) {
static constexpr bool omit_value(const T &v) {
if constexpr (options == field_option::none) {
return is_default_value<T, DefaultValue>(v);
} else if constexpr (requires { v.has_value(); }) {
return !v.has_value();
Expand All @@ -243,6 +245,12 @@ struct field_meta {
}
};

template <uint32_t Number, auto Accessor, int options = field_option::none, typename Type = void,
auto DefaultValue = std::monostate{}>
struct field_meta : field_meta_base<Number, options, Type, DefaultValue> {
constexpr static auto access = accesor_type<Accessor>{};
};

template <auto Accessor, typename... AlternativeMeta>
struct oneof_field_meta {
constexpr static auto access = accesor_type<Accessor>{};
Expand Down Expand Up @@ -298,46 +306,23 @@ struct extension_meta_base {
}
};

template <typename Extendee, uint32_t Number, encoding_rule Encoding, typename Type, typename ValueType,
template <typename Extendee, uint32_t Number, int options, typename Type, typename ValueType,
auto DefaultValue = std::monostate{}>
struct extension_meta : extension_meta_base<extension_meta<Extendee, Number, Encoding, Type, ValueType, DefaultValue>> {

constexpr static uint32_t number = Number;
constexpr static encoding_rule encoding = Encoding;
using type = Type;
struct extension_meta : field_meta_base<Number, options, Type, DefaultValue>,
extension_meta_base<extension_meta<Extendee, Number, options, Type, ValueType, DefaultValue>> {
constexpr static auto default_value = unwrap(DefaultValue);
constexpr static bool has_default_value = !std::same_as<std::remove_const_t<decltype(DefaultValue)>, std::monostate>;
static constexpr bool is_repeated = false;
using extendee = Extendee;

using get_result_type = ValueType;
using set_value_type = ValueType;

template <typename T>
static constexpr bool omit_value(const T &v) {
if constexpr (Encoding == encoding_rule::defaulted) {
return is_default_value<T, DefaultValue>(v);
} else if constexpr (requires { v.has_value(); }) {
return !v.has_value();
} else if constexpr (std::is_pointer_v<std::remove_cvref_t<T>>) {
return v == nullptr;
} else if constexpr (requires {
typename T::element_type;
v.get();
}) {
return v.get() == nullptr;
} else {
return false;
}
}
};

template <typename Extendee, uint32_t Number, encoding_rule Encoding, typename Type, typename ValueType>
template <typename Extendee, uint32_t Number, int options, typename Type, typename ValueType>
struct repeated_extension_meta
: extension_meta_base<repeated_extension_meta<Extendee, Number, Encoding, Type, ValueType>> {
constexpr static uint32_t number = Number;
constexpr static encoding_rule encoding = Encoding;
using type = Type;
: field_meta_base<Number, options, Type, std::monostate{}>,
extension_meta_base<repeated_extension_meta<Extendee, Number, options, Type, ValueType>> {
constexpr static bool has_default_value = false;
static constexpr bool is_repeated = true;
using extendee = Extendee;
Expand Down Expand Up @@ -386,12 +371,7 @@ constexpr auto make_tag(uint32_t number, wire_type type) {

template <typename Type, typename Meta>
constexpr auto make_tag(Meta meta) {
// check if Meta::number is static or not
if constexpr (requires { *&Meta::number; }) {
return make_tag(Meta::number, tag_type<Type>());
} else {
return make_tag(meta.number, tag_type<Type>());
}
return make_tag(meta.number, tag_type<Type>());
}

constexpr auto tag_type(uint32_t tag) { return wire_type(tag & 0x7); }
Expand Down Expand Up @@ -447,8 +427,8 @@ struct map_entry {
typename serialize_type<KeyType>::type key;
typename serialize_type<MappedType>::type value;
constexpr static bool allow_inline_visit_members_lambda = true;
using pb_meta = std::tuple<field_meta<1, &mutable_type::key, encoding_rule::explicit_presence>,
field_meta<2, &mutable_type::value, encoding_rule::explicit_presence>>;
using pb_meta = std::tuple<field_meta<1, &mutable_type::key, field_option::explicit_presence>,
field_meta<2, &mutable_type::value, field_option::explicit_presence>>;

template <typename Target, typename Source>
constexpr static auto move_or_copy(Source &&src) {
Expand Down Expand Up @@ -497,8 +477,8 @@ struct map_entry {
constexpr const auto &operator()(const read_only_type &entry) const { return entry.value; }
};

using pb_meta = std::tuple<field_meta<1, key_accessor{}, encoding_rule::explicit_presence>,
field_meta<2, value_accessor{}, encoding_rule::explicit_presence>>;
using pb_meta = std::tuple<field_meta<1, key_accessor{}, field_option::explicit_presence>,
field_meta<2, value_accessor{}, field_option::explicit_presence>>;
};
};

Expand Down Expand Up @@ -768,13 +748,12 @@ struct pb_serializer {
} else if constexpr (requires { *item; }) {
return cache_count(meta, *item);
} else if constexpr (concepts::has_meta<type>) {
return cache_count(item) + (meta.encoding != encoding_rule::group);
return cache_count(item) + (!meta.is_group);
} else if constexpr (std::ranges::input_range<type>) {
if (item.empty())
return 0;
using value_type = typename std::ranges::range_value_t<type>;
if constexpr (concepts::has_meta<value_type> || Meta::encoding == encoding_rule::unpacked_repeated ||
Meta::encoding == encoding_rule::group) {
if constexpr (concepts::has_meta<value_type> || meta.is_unpacked_repeated || meta.is_group) {
return transform_accumulate(item, [](const auto &elem) constexpr { return cache_count(Meta{}, elem); });
} else {
using element_type =
Expand Down Expand Up @@ -877,7 +856,7 @@ struct pb_serializer {
} else if constexpr (requires { *item; }) {
return field_size(meta, *item, cache);
} else if constexpr (concepts::has_meta<type>) {
if constexpr (meta.encoding != encoding_rule::group) {
if constexpr (!meta.is_group) {
decltype(auto) msg_size = *cache++;
auto s = static_cast<uint32_t>(message_size(item, cache));
msg_size = s;
Expand All @@ -889,8 +868,7 @@ struct pb_serializer {
if (item.empty())
return 0;
using value_type = typename std::ranges::range_value_t<type>;
if constexpr (concepts::has_meta<value_type> || Meta::encoding == encoding_rule::unpacked_repeated ||
Meta::encoding == encoding_rule::group) {
if constexpr (concepts::has_meta<value_type> || meta.is_unpacked_repeated || meta.is_group) {
return transform_accumulate(item,
[&cache](const auto &elem) constexpr { return field_size(Meta{}, elem, cache); });
} else {
Expand Down Expand Up @@ -1012,7 +990,7 @@ struct pb_serializer {
} else if constexpr (requires { *item; }) {
return serialize_field(meta, *item, cache, archive);
} else if constexpr (concepts::has_meta<type>) {
if constexpr (meta.encoding != encoding_rule::group) {
if constexpr (!meta.is_group) {
archive(make_tag<type>(meta), varint{*cache++});
serialize(std::forward<decltype(item)>(item), cache, archive);
} else {
Expand All @@ -1029,8 +1007,7 @@ struct pb_serializer {
std::conditional_t<std::is_same_v<typename Meta::type, void> || concepts::contiguous_byte_range<type>,
value_type, typename Meta::type>;

if constexpr (concepts::has_meta<value_type> || Meta::encoding == encoding_rule::group ||
Meta::encoding == encoding_rule::unpacked_repeated) {
if constexpr (concepts::has_meta<value_type> || meta.is_unpacked_repeated || meta.is_group) {
for (const auto &element : item) {
if constexpr (std::same_as<element_type, std::remove_cvref_t<decltype(element)>> ||
concepts::is_map_entry<typename Meta::type>) {
Expand Down Expand Up @@ -1655,12 +1632,12 @@ struct pb_serializer {
} else if constexpr (concepts::numeric_or_byte<type>) {
return archive(item);
} else if constexpr (concepts::has_meta<type>) {
if constexpr (meta.encoding != encoding_rule::group) {
if constexpr (!meta.is_group) {
return deserialize_sized(item, context, archive);
} else {
return deserialize_group(field_num, item, context, archive);
}
} else if constexpr (meta.encoding == encoding_rule::group) {
} else if constexpr (meta.is_group) {
// repeated group
if constexpr (requires { item.emplace_back(); }) {
return deserialize_group(field_num, item.emplace_back(), context, archive);
Expand All @@ -1674,7 +1651,7 @@ struct pb_serializer {
return deserialize_packed_repeated(meta, std::forward<type>(item), context, archive);
} else { // repeated non-group
using value_type = typename type::value_type;
if constexpr (concepts::numeric<value_type> && meta.encoding != encoding_rule::unpacked_repeated) {
if constexpr (concepts::numeric<value_type> && !meta.is_unpacked_repeated) {
if (tag_type(tag) != wire_type::length_delimited) {
return deserialize_unpacked_repeated(meta, tag, std::forward<type>(item), context, archive);
}
Expand Down Expand Up @@ -1777,8 +1754,8 @@ struct pb_serializer {
concepts::is_basic_in auto &archive) {

while (!archive.empty()) {
vuint32_t tag;
if (auto result = archive(tag); result.failure()) [[unlikely]] {
vuint32_t tag;
if (auto result = archive(tag); result.failure()) [[unlikely]] {
return result;
}

Expand Down Expand Up @@ -1896,7 +1873,7 @@ inline errc extension_meta_base<ExtensionMeta>::write(concepts::pb_extension aut

template <typename ExtensionMeta>
inline errc extension_meta_base<ExtensionMeta>::write(concepts::pb_extension auto &extensions, auto &&value,
concepts::is_pb_context auto && ctx) {
concepts::is_pb_context auto &&ctx) {
check(extensions);

std::span<std::byte> buf;
Expand Down
Loading

0 comments on commit 48f67d4

Please sign in to comment.