Skip to content

Commit 6243ab5

Browse files
jckingcopybara-github
authored andcommitted
Add utility function to add minimally required descriptors to pool
PiperOrigin-RevId: 814827176
1 parent 07b1edd commit 6243ab5

File tree

7 files changed

+117
-4
lines changed

7 files changed

+117
-4
lines changed

common/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ cc_library(
887887
deps = [
888888
"//internal:minimal_descriptors",
889889
"@com_google_absl//absl/base:nullability",
890+
"@com_google_absl//absl/status",
890891
"@com_google_protobuf//:protobuf",
891892
],
892893
)
@@ -897,6 +898,7 @@ cc_test(
897898
deps = [
898899
":minimal_descriptor_pool",
899900
"//internal:testing",
901+
"@com_google_absl//absl/status:status_matchers",
900902
"@com_google_protobuf//:protobuf",
901903
],
902904
)

common/minimal_descriptor_pool.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "common/minimal_descriptor_pool.h"
1616

1717
#include "absl/base/nullability.h"
18+
#include "absl/status/status.h"
1819
#include "internal/minimal_descriptor_pool.h"
1920
#include "google/protobuf/descriptor.h"
2021

@@ -24,4 +25,10 @@ const google::protobuf::DescriptorPool* absl_nonnull GetMinimalDescriptorPool()
2425
return internal::GetMinimalDescriptorPool();
2526
}
2627

28+
// If required, adds the minimally required descriptors to the pool.
29+
absl::Status AddMinimumRequiredDescriptorsToPool(
30+
google::protobuf::DescriptorPool* absl_nonnull pool) {
31+
return internal::AddMinimumRequiredDescriptorsToPool(pool);
32+
}
33+
2734
} // namespace cel

common/minimal_descriptor_pool.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define THIRD_PARTY_CEL_CPP_COMMON_MINIMAL_DESCRIPTOR_POOL_H_
1717

1818
#include "absl/base/nullability.h"
19+
#include "absl/status/status.h"
1920
#include "google/protobuf/descriptor.h"
2021

2122
namespace cel {
@@ -26,6 +27,10 @@ namespace cel {
2627
// lifetime of the process and should not be deleted.
2728
const google::protobuf::DescriptorPool* absl_nonnull GetMinimalDescriptorPool();
2829

30+
// If required, adds the minimally required descriptors to the pool.
31+
absl::Status AddMinimumRequiredDescriptorsToPool(
32+
google::protobuf::DescriptorPool* absl_nonnull pool);
33+
2934
} // namespace cel
3035

3136
#endif // THIRD_PARTY_CEL_CPP_COMMON_MINIMAL_DESCRIPTOR_POOL_H_

common/minimal_descriptor_pool_test.cc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414

1515
#include "common/minimal_descriptor_pool.h"
1616

17+
#include "absl/status/status_matchers.h"
1718
#include "internal/testing.h"
1819
#include "google/protobuf/descriptor.h"
1920

2021
namespace cel {
2122
namespace {
2223

24+
using ::absl_testing::IsOk;
2325
using ::testing::NotNull;
2426

2527
TEST(GetMinimalDescriptorPool, NullValue) {
@@ -145,5 +147,38 @@ TEST(GetMinimalDescriptorPool, Struct) {
145147
EXPECT_EQ(desc->well_known_type(), google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT);
146148
}
147149

150+
TEST(AddMinimumRequiredDescriptorsToPool, Adds) {
151+
google::protobuf::DescriptorPool pool;
152+
ASSERT_THAT(AddMinimumRequiredDescriptorsToPool(&pool), IsOk());
153+
EXPECT_THAT(pool.FindEnumTypeByName("google.protobuf.NullValue"), NotNull());
154+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.BoolValue"),
155+
NotNull());
156+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.Int32Value"),
157+
NotNull());
158+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.Int64Value"),
159+
NotNull());
160+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.UInt32Value"),
161+
NotNull());
162+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.UInt64Value"),
163+
NotNull());
164+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.FloatValue"),
165+
NotNull());
166+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.DoubleValue"),
167+
NotNull());
168+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.BytesValue"),
169+
NotNull());
170+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.StringValue"),
171+
NotNull());
172+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.Any"), NotNull());
173+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.Duration"),
174+
NotNull());
175+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.Timestamp"),
176+
NotNull());
177+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.Value"), NotNull());
178+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.ListValue"),
179+
NotNull());
180+
EXPECT_THAT(pool.FindMessageTypeByName("google.protobuf.Struct"), NotNull());
181+
}
182+
148183
} // namespace
149184
} // namespace cel

internal/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,9 @@ cc_library(
499499
"@com_google_absl//absl/base:no_destructor",
500500
"@com_google_absl//absl/base:nullability",
501501
"@com_google_absl//absl/log:absl_check",
502+
"@com_google_absl//absl/status",
503+
"@com_google_absl//absl/strings",
504+
"@com_google_absl//absl/strings:string_view",
502505
"@com_google_protobuf//:protobuf",
503506
],
504507
)

internal/minimal_descriptor_pool.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define THIRD_PARTY_CEL_CPP_INTERNAL_MINIMAL_DESCRIPTOR_POOL_H_
1717

1818
#include "absl/base/nullability.h"
19+
#include "absl/status/status.h"
1920
#include "google/protobuf/descriptor.h"
2021

2122
namespace cel::internal {
@@ -30,6 +31,10 @@ namespace cel::internal {
3031
// google::protobuf::DescriptorPool my_descriptor_pool(GetMinimalDescriptorPool());
3132
const google::protobuf::DescriptorPool* absl_nonnull GetMinimalDescriptorPool();
3233

34+
// If required, adds the minimally required descriptors to the pool.
35+
absl::Status AddMinimumRequiredDescriptorsToPool(
36+
google::protobuf::DescriptorPool* absl_nonnull pool);
37+
3338
} // namespace cel::internal
3439

3540
#endif // THIRD_PARTY_CEL_CPP_INTERNAL_MINIMAL_DESCRIPTOR_POOL_H_

internal/minimal_descriptors.cc

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@
1313
// limitations under the License.
1414

1515
#include <cstdint>
16+
#include <string>
17+
#include <vector>
1618

1719
#include "google/protobuf/descriptor.pb.h"
1820
#include "absl/base/attributes.h"
1921
#include "absl/base/macros.h"
2022
#include "absl/base/no_destructor.h"
2123
#include "absl/base/nullability.h"
2224
#include "absl/log/absl_check.h"
25+
#include "absl/status/status.h"
26+
#include "absl/strings/str_cat.h"
27+
#include "absl/strings/str_join.h"
28+
#include "absl/strings/string_view.h"
2329
#include "internal/minimal_descriptor_database.h"
2430
#include "internal/minimal_descriptor_pool.h"
2531
#include "google/protobuf/descriptor.h"
@@ -33,15 +39,24 @@ ABSL_CONST_INIT const uint8_t kMinimalDescriptorSet[] = {
3339
#include "internal/minimal_descriptor_set_embed.inc"
3440
};
3541

42+
const google::protobuf::FileDescriptorSet* GetMinimumFileDescriptorSet() {
43+
static google::protobuf::FileDescriptorSet* const file_desc_set = []() {
44+
google::protobuf::FileDescriptorSet* file_desc_set = new google::protobuf::FileDescriptorSet();
45+
ABSL_CHECK(file_desc_set->ParseFromArray( // Crash OK
46+
kMinimalDescriptorSet, ABSL_ARRAYSIZE(kMinimalDescriptorSet)));
47+
return file_desc_set;
48+
}();
49+
return file_desc_set;
50+
}
51+
3652
} // namespace
3753

3854
const google::protobuf::DescriptorPool* absl_nonnull GetMinimalDescriptorPool() {
3955
static const google::protobuf::DescriptorPool* absl_nonnull const pool = []() {
40-
google::protobuf::FileDescriptorSet file_desc_set;
41-
ABSL_CHECK(file_desc_set.ParseFromArray( // Crash OK
42-
kMinimalDescriptorSet, ABSL_ARRAYSIZE(kMinimalDescriptorSet)));
56+
const google::protobuf::FileDescriptorSet* file_desc_set =
57+
GetMinimumFileDescriptorSet();
4358
auto* pool = new google::protobuf::DescriptorPool();
44-
for (const auto& file_desc : file_desc_set.file()) {
59+
for (const auto& file_desc : file_desc_set->file()) {
4560
ABSL_CHECK(pool->BuildFile(file_desc) != nullptr); // Crash OK
4661
}
4762
return pool;
@@ -55,4 +70,45 @@ google::protobuf::DescriptorDatabase* absl_nonnull GetMinimalDescriptorDatabase(
5570
return &*database;
5671
}
5772

73+
namespace {
74+
75+
class DescriptorErrorCollector final
76+
: public google::protobuf::DescriptorPool::ErrorCollector {
77+
public:
78+
void RecordError(absl::string_view, absl::string_view element_name,
79+
const google::protobuf::Message*, ErrorLocation,
80+
absl::string_view message) override {
81+
errors_.push_back(absl::StrCat(element_name, ": ", message));
82+
}
83+
84+
bool FoundErrors() const { return !errors_.empty(); }
85+
86+
std::string FormatErrors() const { return absl::StrJoin(errors_, "\n\t"); }
87+
88+
private:
89+
std::vector<std::string> errors_;
90+
};
91+
92+
} // namespace
93+
94+
absl::Status AddMinimumRequiredDescriptorsToPool(
95+
google::protobuf::DescriptorPool* absl_nonnull pool) {
96+
const google::protobuf::FileDescriptorSet* file_desc_set =
97+
GetMinimumFileDescriptorSet();
98+
for (const auto& file_desc : file_desc_set->file()) {
99+
if (pool->FindFileByName(file_desc.name()) != nullptr) {
100+
continue;
101+
}
102+
DescriptorErrorCollector error_collector;
103+
if (pool->BuildFileCollectingErrors(file_desc, &error_collector) ==
104+
nullptr) {
105+
ABSL_DCHECK(error_collector.FoundErrors());
106+
return absl::UnknownError(
107+
absl::StrCat("Failed to build file descriptor for ", file_desc.name(),
108+
":\n\t", error_collector.FormatErrors()));
109+
}
110+
}
111+
return absl::OkStatus();
112+
}
113+
58114
} // namespace cel::internal

0 commit comments

Comments
 (0)