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
3854const 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