hpb: Introduce UPB_EXT_PRIMITIVE to flesh out all remaining scalars for extensions

In this CL, we add the macro UPB_EXT_PRIMITIVE.
The template specializations are practically identical sans the CppType and UpbFunc called, so we now consolidate via this macro.

Added support for uint32/64, float/double, and bool.
Getting and setting exts of ^ in hpb should all work, and fetch the proper default value as well (if provided in the .proto).

PiperOrigin-RevId: 707897721
pull/19721/head
Hong Shin 2 months ago committed by Copybara-Service
parent 9e44913d43
commit cac05fe0d1
  1. 53
      hpb/extension.h
  2. 10
      hpb_generator/gen_utils.cc
  3. 88
      hpb_generator/tests/extension_test.cc
  4. 9
      hpb_generator/tests/test_extension.proto

@ -70,32 +70,31 @@ struct UpbExtensionTrait<hpb::RepeatedField<T>> {
}
};
template <>
struct UpbExtensionTrait<int32_t> {
using DefaultType = int32_t;
using ReturnType = int32_t;
static constexpr auto kSetter = upb_Message_SetExtensionInt32;
template <typename Msg, typename Id>
static constexpr ReturnType Get(Msg message, const Id& id) {
auto default_val = hpb::internal::PrivateAccess::GetDefaultValue(id);
return upb_Message_GetExtensionInt32(hpb::interop::upb::GetMessage(message),
id.mini_table_ext(), default_val);
}
};
template <>
struct UpbExtensionTrait<int64_t> {
using DefaultType = int64_t;
using ReturnType = int64_t;
static constexpr auto kSetter = upb_Message_SetExtensionInt64;
template <typename Msg, typename Id>
static constexpr ReturnType Get(Msg message, const Id& id) {
auto default_val = hpb::internal::PrivateAccess::GetDefaultValue(id);
return upb_Message_GetExtensionInt64(hpb::interop::upb::GetMessage(message),
id.mini_table_ext(), default_val);
}
};
#define UPB_EXT_PRIMITIVE(CppType, UpbFunc) \
template <> \
struct UpbExtensionTrait<CppType> { \
using DefaultType = CppType; \
using ReturnType = CppType; \
static constexpr auto kSetter = upb_Message_SetExtension##UpbFunc; \
\
template <typename Msg, typename Id> \
static constexpr ReturnType Get(Msg message, const Id& id) { \
auto default_val = hpb::internal::PrivateAccess::GetDefaultValue(id); \
return upb_Message_GetExtension##UpbFunc( \
hpb::interop::upb::GetMessage(message), id.mini_table_ext(), \
default_val); \
} \
};
UPB_EXT_PRIMITIVE(bool, Bool);
UPB_EXT_PRIMITIVE(int32_t, Int32);
UPB_EXT_PRIMITIVE(int64_t, Int64);
UPB_EXT_PRIMITIVE(uint32_t, UInt32);
UPB_EXT_PRIMITIVE(uint64_t, UInt64);
UPB_EXT_PRIMITIVE(float, Float);
UPB_EXT_PRIMITIVE(double, Double);
#undef UPB_EXT_PRIMITIVE
// TODO: b/375460289 - flesh out non-promotional msg support that does
// not return an error if missing but the default msg
@ -245,7 +244,7 @@ absl::Status SetExtension(
Ptr<T> message,
const ::hpb::internal::ExtensionIdentifier<T, Extension>& id,
const Extension& value) {
if constexpr (std::is_integral_v<Extension>) {
if constexpr (std::is_arithmetic_v<Extension>) {
bool res = hpb::internal::UpbExtensionTrait<Extension>::kSetter(
hpb::interop::upb::GetMessage(message), id.mini_table_ext(), value,
hpb::interop::upb::GetArena(message));

@ -139,6 +139,16 @@ std::string DefaultValue(const FieldDescriptor* field) {
return absl::StrCat(field->default_value_int32());
case FieldDescriptor::CPPTYPE_INT64:
return absl::StrCat(field->default_value_int64());
case FieldDescriptor::CPPTYPE_UINT32:
return absl::StrCat(field->default_value_uint32());
case FieldDescriptor::CPPTYPE_UINT64:
return absl::StrCat(field->default_value_uint64());
case FieldDescriptor::CPPTYPE_FLOAT:
return absl::StrCat(field->default_value_float());
case FieldDescriptor::CPPTYPE_DOUBLE:
return absl::StrCat(field->default_value_double());
case FieldDescriptor::CPPTYPE_BOOL:
return field->default_value_bool() ? "true" : "false";
case FieldDescriptor::CPPTYPE_MESSAGE:
return "::std::false_type()";
default:

@ -7,6 +7,9 @@
#include "google/protobuf/hpb/extension.h"
#include <cstdint>
#include <type_traits>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "google/protobuf/compiler/hpb/tests/child_model.upb.proto.h"
@ -23,11 +26,16 @@ using ::hpb_unittest::protos::other_ext;
using ::hpb_unittest::protos::TestModel;
using ::hpb_unittest::protos::theme;
using ::hpb_unittest::protos::ThemeExtension;
using ::hpb_unittest::someotherpackage::protos::bool_ext;
using ::hpb_unittest::someotherpackage::protos::double_ext;
using ::hpb_unittest::someotherpackage::protos::float_ext;
using ::hpb_unittest::someotherpackage::protos::int32_ext;
using ::hpb_unittest::someotherpackage::protos::int64_ext;
using ::hpb_unittest::someotherpackage::protos::repeated_int32_ext;
using ::hpb_unittest::someotherpackage::protos::repeated_int64_ext;
using ::hpb_unittest::someotherpackage::protos::repeated_string_ext;
using ::hpb_unittest::someotherpackage::protos::uint32_ext;
using ::hpb_unittest::someotherpackage::protos::uint64_ext;
using ::testing::status::IsOkAndHolds;
@ -55,7 +63,7 @@ TEST(CppGeneratedCode, ClearExtensionWithEmptyExtensionPtr) {
EXPECT_EQ(false, ::hpb::HasExtension(recursive_child, theme));
}
TEST(CppGeneratedCode, SetExtensionInt32) {
TEST(CppGeneratedCode, GetSetExtensionInt32) {
TestModel model;
EXPECT_EQ(false, hpb::HasExtension(&model, int32_ext));
int32_t val = 55;
@ -64,7 +72,7 @@ TEST(CppGeneratedCode, SetExtensionInt32) {
EXPECT_THAT(hpb::GetExtension(&model, int32_ext), IsOkAndHolds(val));
}
TEST(CppGeneratedCode, SetExtensionInt64) {
TEST(CppGeneratedCode, GetSetExtensionInt64) {
TestModel model;
EXPECT_EQ(false, hpb::HasExtension(&model, int64_ext));
int64_t val = std::numeric_limits<int32_t>::max() + int64_t{1};
@ -73,6 +81,50 @@ TEST(CppGeneratedCode, SetExtensionInt64) {
EXPECT_THAT(hpb::GetExtension(&model, int64_ext), IsOkAndHolds(val));
}
TEST(CppGeneratedCode, GetSetExtensionUInt32) {
TestModel model;
EXPECT_EQ(false, hpb::HasExtension(&model, uint32_ext));
uint32_t val = std::numeric_limits<int32_t>::max() + uint32_t{5};
auto x = hpb::SetExtension(&model, uint32_ext, val);
EXPECT_EQ(true, hpb::HasExtension(&model, uint32_ext));
EXPECT_THAT(hpb::GetExtension(&model, uint32_ext), IsOkAndHolds(val));
}
TEST(CppGeneratedCode, GetSetExtensionUInt64) {
TestModel model;
EXPECT_EQ(false, hpb::HasExtension(&model, uint64_ext));
uint64_t val = std::numeric_limits<int64_t>::max() + uint64_t{5};
auto x = hpb::SetExtension(&model, uint64_ext, val);
EXPECT_EQ(true, hpb::HasExtension(&model, uint64_ext));
EXPECT_THAT(hpb::GetExtension(&model, uint64_ext), IsOkAndHolds(val));
}
TEST(CppGeneratedCode, GetSetExtensionFloat) {
TestModel model;
EXPECT_EQ(false, hpb::HasExtension(&model, float_ext));
float val = 2.78;
auto x = hpb::SetExtension(&model, float_ext, val);
EXPECT_EQ(true, hpb::HasExtension(&model, float_ext));
EXPECT_THAT(hpb::GetExtension(&model, float_ext), IsOkAndHolds(val));
}
TEST(CppGeneratedCode, GetSetExtensionDouble) {
TestModel model;
EXPECT_EQ(false, hpb::HasExtension(&model, double_ext));
double val = std::numeric_limits<float>::max() + 1.23;
auto x = hpb::SetExtension(&model, double_ext, val);
EXPECT_EQ(true, hpb::HasExtension(&model, double_ext));
EXPECT_THAT(hpb::GetExtension(&model, double_ext), IsOkAndHolds(val));
}
TEST(CppGeneratedCode, GetSetExtensionBool) {
TestModel model;
EXPECT_EQ(false, hpb::HasExtension(&model, bool_ext));
auto x = hpb::SetExtension(&model, bool_ext, true);
EXPECT_EQ(true, hpb::HasExtension(&model, bool_ext));
EXPECT_THAT(hpb::GetExtension(&model, bool_ext), IsOkAndHolds(true));
}
TEST(CppGeneratedCode, SetExtension) {
TestModel model;
void* prior_message;
@ -235,6 +287,38 @@ TEST(CppGeneratedCode, GetExtensionInt64WithDefault) {
EXPECT_EQ(*res, expected);
}
TEST(CppGeneratedCode, GetExtensionUInt32WithDefault) {
TestModel model;
auto res = hpb::GetExtension(&model, uint32_ext);
EXPECT_THAT(res, IsOkAndHolds(12));
}
TEST(CppGeneratedCode, GetExtensionUInt64WithDefault) {
TestModel model;
auto res = hpb::GetExtension(&model, uint64_ext);
EXPECT_THAT(res, IsOkAndHolds(4294967296));
}
TEST(CppGeneratedCode, GetExtensionFloatWithDefault) {
TestModel model;
auto res = hpb::GetExtension(&model, float_ext);
static_assert(std::is_same_v<decltype(res), absl::StatusOr<float>>);
EXPECT_THAT(res, IsOkAndHolds(3.14f));
}
TEST(CppGeneratedCode, GetExtensionDoubleWithDefault) {
TestModel model;
auto res = hpb::GetExtension(&model, double_ext);
static_assert(std::is_same_v<decltype(res), absl::StatusOr<double>>);
EXPECT_THAT(res, IsOkAndHolds(340282000000000000000000000000000000001.23));
}
TEST(CppGeneratedCode, GetExtensionBoolWithDefault) {
TestModel model;
auto res = hpb::GetExtension(&model, bool_ext);
EXPECT_THAT(res, IsOkAndHolds(true));
}
TEST(CppGeneratedCode, GetExtensionOnMutableChild) {
TestModel model;
ThemeExtension extension1;

@ -20,11 +20,16 @@ extend TestModel {
extend TestModel {
int32 int32_ext = 13002 [default = 644];
int64 int64_ext = 13003 [default = 2147483648];
repeated int32 repeated_int32_ext = 13004;
repeated int64 repeated_int64_ext = 13005;
repeated string repeated_string_ext = 13006;
uint32 uint32_ext = 13007 [default = 12];
uint64 uint64_ext = 13008 [default = 4294967296];
float float_ext = 13009 [default = 3.14];
double double_ext = 13010
[default = 340282000000000000000000000000000000001.23];
bool bool_ext = 13011 [default = true];
}

Loading…
Cancel
Save