From afaf93b85db8ab9b25a1910ffbec59a2d80bfc12 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 27 Oct 2022 19:53:08 +0000 Subject: [PATCH] Internal change PiperOrigin-RevId: 484326389 --- src/google/protobuf/arena_align.h | 2 +- src/google/protobuf/arenastring.h | 12 ++++++------ src/google/protobuf/compiler/BUILD.bazel | 1 + .../protobuf/compiler/command_line_interface.cc | 3 ++- .../compiler/csharp/csharp_map_field.cc | 5 ++--- .../protobuf/compiler/objectivec/enum_field.cc | 4 ++++ .../protobuf/compiler/objectivec/map_field.cc | 5 +++++ src/google/protobuf/message.h | 15 ++++++++++++++- src/google/protobuf/text_format.cc | 17 +++++++++++++++++ src/google/protobuf/text_format.h | 3 +++ src/google/protobuf/text_format_unittest.cc | 4 ++++ 11 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/google/protobuf/arena_align.h b/src/google/protobuf/arena_align.h index fba8c1cec1..fde9b4d5aa 100644 --- a/src/google/protobuf/arena_align.h +++ b/src/google/protobuf/arena_align.h @@ -79,7 +79,7 @@ namespace protobuf { namespace internal { struct ArenaAlignDefault { - static constexpr size_t align = 8; // NOLINT + PROTOBUF_EXPORT static constexpr size_t align = 8; // NOLINT static constexpr bool IsAligned(size_t n) { return (n & (align - 1)) == 0; } diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index 45a8773db2..c6d61d737f 100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -100,9 +100,9 @@ class TaggedStringPtr { // Bit flags qualifying string properties. We can use 2 bits as // ptr_ is guaranteed and enforced to be aligned on 4 byte boundaries. enum Flags { - kArenaBit = 0x1, // ptr is arena allocated - kMutableBit = 0x2, // ptr contents are fully mutable - kMask = 0x3 // Bit mask + kArenaBit = 0x1, // ptr is arena allocated + kMutableBit = 0x2, // ptr contents are fully mutable + kMask = 0x3 // Bit mask }; // Composed logical types @@ -168,7 +168,7 @@ class TaggedStringPtr { // If the current string is a heap-allocated mutable value, returns a pointer // to it. Returns nullptr otherwise. - inline std::string *GetIfAllocated() const { + inline std::string* GetIfAllocated() const { auto allocated = as_int() ^ kAllocated; if (allocated & kMask) return nullptr; @@ -423,8 +423,8 @@ inline void ArenaStringPtr::SetBytes(absl::string_view value, Arena* arena) { } template <> -PROTOBUF_EXPORT -void ArenaStringPtr::Set(const std::string& value, Arena* arena); +PROTOBUF_EXPORT void ArenaStringPtr::Set(const std::string& value, + Arena* arena); template <> inline void ArenaStringPtr::SetBytes(const std::string& value, Arena* arena) { diff --git a/src/google/protobuf/compiler/BUILD.bazel b/src/google/protobuf/compiler/BUILD.bazel index af05903a6a..d60d78f65f 100644 --- a/src/google/protobuf/compiler/BUILD.bazel +++ b/src/google/protobuf/compiler/BUILD.bazel @@ -83,6 +83,7 @@ cc_library( ":code_generator", ":importer", "//src/google/protobuf:protobuf_nowkt", + "@com_google_absl//absl/container:btree", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", ], diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 7cff1e3563..80916fdc7a 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -34,6 +34,7 @@ #include "google/protobuf/compiler/command_line_interface.h" +#include "absl/container/btree_map.h" #include "absl/container/flat_hash_map.h" #include "google/protobuf/stubs/platform_macros.h" @@ -427,7 +428,7 @@ class CommandLineInterface::GeneratorContextImpl : public GeneratorContext { // The files_ field maps from path keys to file content values. It's a map // instead of an unordered_map so that files are written in order (good when // writing zips). - absl::flat_hash_map files_; + absl::btree_map files_; const std::vector& parsed_files_; bool had_error_; }; diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc index 50d8b1d828..062e3a73b7 100644 --- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc @@ -86,9 +86,8 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) { } void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) { - printer->Print( - variables_, - "$name$_.MergeFrom(other.$name$_);\n"); + printer->Print(variables_, + "$name$_.MergeFrom(other.$name$_);\n"); } void MapFieldGenerator::GenerateParsingCode(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/objectivec/enum_field.cc b/src/google/protobuf/compiler/objectivec/enum_field.cc index 061033b97d..db4b35faed 100644 --- a/src/google/protobuf/compiler/objectivec/enum_field.cc +++ b/src/google/protobuf/compiler/objectivec/enum_field.cc @@ -149,6 +149,10 @@ void RepeatedEnumFieldGenerator::FinishInitialization() { variables_["storage_type"] + "|\n"; } +// NOTE: RepeatedEnumFieldGenerator::DetermineForwardDeclarations isn't needed +// because `GPBEnumArray` isn't generic (like `NSArray` would be for messages) +// and thus doesn't reference the type in the header. + } // namespace objectivec } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/objectivec/map_field.cc b/src/google/protobuf/compiler/objectivec/map_field.cc index c5ca768cfc..767aa1dbca 100644 --- a/src/google/protobuf/compiler/objectivec/map_field.cc +++ b/src/google/protobuf/compiler/objectivec/map_field.cc @@ -163,6 +163,11 @@ void MapFieldGenerator::DetermineForwardDeclarations( std::set* fwd_decls, bool include_external_types) const { RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls, include_external_types); + // NOTE: Maps with values of enums don't have to worry about adding the + // forward declaration because `GPB*EnumDictionary` isn't generic to the + // specific enum (like say `NSDictionary`) and thus doesn't + // reference the type in the header. + const FieldDescriptor* value_descriptor = descriptor_->message_type()->map_value(); // Within a file there is no requirement on the order of the messages, so diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index f0c0ccc9db..335527e4e0 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -121,6 +121,7 @@ #include "google/protobuf/port.h" #include "absl/base/call_once.h" #include "absl/base/casts.h" +#include "absl/functional/function_ref.h" #include "absl/strings/string_view.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/generated_message_reflection.h" @@ -181,7 +182,10 @@ class CelMapReflectionFriend; // field_backed_map_impl.cc namespace internal { class MapFieldPrinterHelper; // text_format.cc -} +void PerformAbslStringify( + const Message& message, + absl::FunctionRef append); // text_format.cc +} // namespace internal namespace util { class MessageDifferencer; } @@ -330,6 +334,15 @@ class PROTOBUF_EXPORT Message : public MessageLite { // Convenience function useful in GDB. Prints DebugString() to stdout. void PrintDebugString() const; + // Implementation of the `AbslStringify` interface. This adds something + // similar to either `ShortDebugString()` or `DebugString()` to the sink. + // Do not rely on exact format. + template + friend void AbslStringify(Sink& sink, const google::protobuf::Message& message) { + internal::PerformAbslStringify( + message, [&](absl::string_view content) { sink.Append(content); }); + } + // Reflection-based methods ---------------------------------------- // These methods are pure-virtual in MessageLite, but Message provides // reflection-based default implementations. diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index b38c53f36f..b80ee89330 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -166,6 +166,23 @@ std::string Message::Utf8DebugString() const { void Message::PrintDebugString() const { printf("%s", DebugString().c_str()); } +namespace internal { + +void PerformAbslStringify(const Message& message, + absl::FunctionRef append) { + // TODO(b/249835002): consider using the single line version for short + TextFormat::Printer printer; + printer.SetExpandAny(true); + printer.SetInsertSilentMarker(true); + printer.SetRedactDebugString(true); + printer.SetRandomizeDebugString(true); + std::string result; + printer.PrintToString(message, &result); + append(result); +} + +} // namespace internal + // =========================================================================== // Implementation of the parse information tree class. diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index f6574869da..fbcbea4593 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -385,6 +385,9 @@ class PROTOBUF_EXPORT TextFormat { friend std::string Message::DebugString() const; friend std::string Message::ShortDebugString() const; friend std::string Message::Utf8DebugString() const; + friend void internal::PerformAbslStringify( + const Message& message, + absl::FunctionRef append); // Sets whether silent markers will be inserted. void SetInsertSilentMarker(bool v) { insert_silent_marker_ = v; } diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 836bfd789b..4deeec8f1f 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -60,6 +60,7 @@ #include "google/protobuf/stubs/logging.h" #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" #include "absl/strings/str_replace.h" #include "absl/strings/substitute.h" #include "google/protobuf/test_util.h" @@ -76,6 +77,8 @@ namespace protobuf { namespace text_format_unittest { using ::google::protobuf::internal::kDebugStringSilentMarker; +using ::testing::AllOf; +using ::testing::HasSubstr; // A basic string with different escapable characters for testing. const std::string kEscapeTestString = @@ -158,6 +161,7 @@ TEST_F(TextFormatTest, ShortDebugString) { "optional_foreign_message { }")); } + TEST_F(TextFormatTest, ShortPrimitiveRepeateds) { proto_.set_optional_int32(123); proto_.add_repeated_int32(456);