Skip to content

Commit 230232a

Browse files
pizzudcopybara-github
authored andcommitted
Implement AbslStringify for the Descriptor family of types.
Implementing this method allows descriptors to be used in contexts that support ABSL's formatting, most notably gunit's PrintToString and absl's StrFormat. The implementations are done on the concrete descriptor type, which appears to be more idiomatic for AbslStringify. Implementing them on pointers-to-descriptors would be nicer for users who typically interact with pointers, but that would conflict with AbslStringify's built-in support for pointers. The implementation simply forwards to DebugString for simplicity. PiperOrigin-RevId: 558854354
1 parent a2b3470 commit 230232a

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

src/google/protobuf/descriptor.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
#include "absl/container/flat_hash_map.h"
7070
#include "absl/log/absl_check.h"
7171
#include "absl/log/absl_log.h"
72+
#include "absl/strings/str_format.h"
7273
#include "absl/strings/string_view.h"
7374
#include "absl/synchronization/mutex.h"
7475
#include "absl/types/optional.h"
@@ -347,6 +348,12 @@ class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase {
347348
// include original user comments in output).
348349
std::string DebugStringWithOptions(const DebugStringOptions& options) const;
349350

351+
// Allows formatting with absl and gtest.
352+
template <typename Sink>
353+
friend void AbslStringify(Sink& sink, const Descriptor& d) {
354+
absl::Format(&sink, "%s", d.DebugString());
355+
}
356+
350357
// Returns true if this is a placeholder for an unknown type. This will
351358
// only be the case if this descriptor comes from a DescriptorPool
352359
// with AllowUnknownDependencies() set.
@@ -981,6 +988,12 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase {
981988
// See Descriptor::DebugStringWithOptions().
982989
std::string DebugStringWithOptions(const DebugStringOptions& options) const;
983990

991+
// Allows formatting with absl and gtest.
992+
template <typename Sink>
993+
friend void AbslStringify(Sink& sink, const FieldDescriptor& d) {
994+
absl::Format(&sink, "%s", d.DebugString());
995+
}
996+
984997
// Helper method to get the CppType for a particular Type.
985998
static CppType TypeToCppType(Type type);
986999

@@ -1186,6 +1199,12 @@ class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase {
11861199
// See Descriptor::DebugStringWithOptions().
11871200
std::string DebugStringWithOptions(const DebugStringOptions& options) const;
11881201

1202+
// Allows formatting with absl and gtest.
1203+
template <typename Sink>
1204+
friend void AbslStringify(Sink& sink, const OneofDescriptor& d) {
1205+
absl::Format(&sink, "%s", d.DebugString());
1206+
}
1207+
11891208
// Source Location ---------------------------------------------------
11901209

11911210
// Updates |*out_location| to the source location of the complete
@@ -1307,6 +1326,12 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase {
13071326
// See Descriptor::DebugStringWithOptions().
13081327
std::string DebugStringWithOptions(const DebugStringOptions& options) const;
13091328

1329+
// Allows formatting with absl and gtest.
1330+
template <typename Sink>
1331+
friend void AbslStringify(Sink& sink, const EnumDescriptor& d) {
1332+
absl::Format(&sink, "%s", d.DebugString());
1333+
}
1334+
13101335
// Returns true if this is a placeholder for an unknown enum. This will
13111336
// only be the case if this descriptor comes from a DescriptorPool
13121337
// with AllowUnknownDependencies() set.
@@ -1500,6 +1525,12 @@ class PROTOBUF_EXPORT EnumValueDescriptor : private internal::SymbolBaseN<0>,
15001525
// See Descriptor::DebugStringWithOptions().
15011526
std::string DebugStringWithOptions(const DebugStringOptions& options) const;
15021527

1528+
// Allows formatting with absl and gtest.
1529+
template <typename Sink>
1530+
friend void AbslStringify(Sink& sink, const EnumValueDescriptor& d) {
1531+
absl::Format(&sink, "%s", d.DebugString());
1532+
}
1533+
15031534
// Source Location ---------------------------------------------------
15041535

15051536
// Updates |*out_location| to the source location of the complete
@@ -1597,6 +1628,12 @@ class PROTOBUF_EXPORT ServiceDescriptor : private internal::SymbolBase {
15971628
// See Descriptor::DebugStringWithOptions().
15981629
std::string DebugStringWithOptions(const DebugStringOptions& options) const;
15991630

1631+
// Allows formatting with absl and gtest.
1632+
template <typename Sink>
1633+
friend void AbslStringify(Sink& sink, const ServiceDescriptor& d) {
1634+
absl::Format(&sink, "%s", d.DebugString());
1635+
}
1636+
16001637
// Source Location ---------------------------------------------------
16011638

16021639
// Updates |*out_location| to the source location of the complete
@@ -1698,6 +1735,12 @@ class PROTOBUF_EXPORT MethodDescriptor : private internal::SymbolBase {
16981735
// See Descriptor::DebugStringWithOptions().
16991736
std::string DebugStringWithOptions(const DebugStringOptions& options) const;
17001737

1738+
// Allows formatting with absl and gtest.
1739+
template <typename Sink>
1740+
friend void AbslStringify(Sink& sink, const MethodDescriptor& d) {
1741+
absl::Format(&sink, "%s", d.DebugString());
1742+
}
1743+
17011744
// Source Location ---------------------------------------------------
17021745

17031746
// Updates |*out_location| to the source location of the complete
@@ -1913,6 +1956,12 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase {
19131956
// See Descriptor::DebugStringWithOptions().
19141957
std::string DebugStringWithOptions(const DebugStringOptions& options) const;
19151958

1959+
// Allows formatting with absl and gtest.
1960+
template <typename Sink>
1961+
friend void AbslStringify(Sink& sink, const FileDescriptor& d) {
1962+
absl::Format(&sink, "%s", d.DebugString());
1963+
}
1964+
19161965
// Returns true if this is a placeholder for an unknown file. This will
19171966
// only be the case if this descriptor comes from a DescriptorPool
19181967
// with AllowUnknownDependencies() set.

src/google/protobuf/descriptor_unittest.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <cstdlib>
4040
#include <limits>
4141
#include <memory>
42+
#include <string>
4243
#include <tuple>
4344
#include <vector>
4445

@@ -83,6 +84,7 @@
8384

8485
using ::testing::AnyOf;
8586
using ::testing::ElementsAre;
87+
using ::testing::HasSubstr;
8688
using ::testing::NotNull;
8789

8890
namespace google {
@@ -614,6 +616,13 @@ TEST_F(FileDescriptorTest, DebugStringRoundTrip) {
614616
}
615617
}
616618

619+
TEST_F(FileDescriptorTest, AbslStringifyWorks) {
620+
std::string s = absl::StrFormat(
621+
"%v",
622+
*protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file());
623+
EXPECT_THAT(s, HasSubstr("TestMessageWithCustomOptions"));
624+
}
625+
617626
// ===================================================================
618627

619628
// Test simple flat messages and fields.
@@ -1209,6 +1218,12 @@ TEST_F(DescriptorTest, FieldEnumType) {
12091218
EXPECT_EQ(enum_, bar_->enum_type());
12101219
}
12111220

1221+
TEST_F(DescriptorTest, AbslStringifyWorks) {
1222+
EXPECT_THAT(absl::StrFormat("%v", *message_),
1223+
HasSubstr(message_->full_name()));
1224+
EXPECT_THAT(absl::StrFormat("%v", *foo_), HasSubstr(foo_->name()));
1225+
}
1226+
12121227

12131228
// ===================================================================
12141229

@@ -1302,6 +1317,10 @@ TEST_F(OneofDescriptorTest, FindByName) {
13021317
EXPECT_TRUE(oneof_message_->FindOneofByName("no_such_oneof") == nullptr);
13031318
}
13041319

1320+
TEST_F(OneofDescriptorTest, AbslStringifyWorks) {
1321+
EXPECT_THAT(absl::StrFormat("%v", *oneof_), HasSubstr(oneof_->name()));
1322+
}
1323+
13051324
// ===================================================================
13061325

13071326
class StylizedFieldNamesTest : public testing::Test {
@@ -1650,6 +1669,11 @@ TEST_F(EnumDescriptorTest, IsClosed) {
16501669
EXPECT_FALSE(enum3->is_closed());
16511670
}
16521671

1672+
TEST_F(EnumDescriptorTest, AbslStringifyWorks) {
1673+
EXPECT_THAT(absl::StrFormat("%v", *enum_), HasSubstr(enum_->full_name()));
1674+
EXPECT_THAT(absl::StrFormat("%v", *foo_), HasSubstr(foo_->name()));
1675+
}
1676+
16531677
// ===================================================================
16541678

16551679
// Test service descriptors.
@@ -1810,6 +1834,11 @@ TEST_F(ServiceDescriptorTest, MethodOutputType) {
18101834
EXPECT_EQ(bar_response_, bar_->output_type());
18111835
}
18121836

1837+
TEST_F(ServiceDescriptorTest, AbslStringifyWorks) {
1838+
EXPECT_THAT(absl::StrFormat("%v", *service_), HasSubstr(service_->name()));
1839+
EXPECT_THAT(absl::StrFormat("%v", *foo_), HasSubstr(foo_->name()));
1840+
}
1841+
18131842
// ===================================================================
18141843

18151844
// Test nested types.

0 commit comments

Comments
 (0)