Update retention logic to remove empty options messages
This way the retention stripping will not leave empty options messages lying
around.
PiperOrigin-RevId: 535728592
diff --git a/objectivec/GPBAny.pbobjc.m b/objectivec/GPBAny.pbobjc.m
index ada41e5..9b7939d 100644
--- a/objectivec/GPBAny.pbobjc.m
+++ b/objectivec/GPBAny.pbobjc.m
@@ -91,9 +91,9 @@
"\001\001\004\241!!\000";
[localDescriptor setupExtraTextInfo:extraTextFormatInfo];
#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
diff --git a/objectivec/GPBApi.pbobjc.m b/objectivec/GPBApi.pbobjc.m
index a6283a8..b416445 100644
--- a/objectivec/GPBApi.pbobjc.m
+++ b/objectivec/GPBApi.pbobjc.m
@@ -145,9 +145,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBApi__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -272,9 +272,9 @@
"\002\002\007\244\241!!\000\004\010\244\241!!\000";
[localDescriptor setupExtraTextInfo:extraTextFormatInfo];
#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -341,9 +341,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBMixin__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
diff --git a/objectivec/GPBDuration.pbobjc.m b/objectivec/GPBDuration.pbobjc.m
index 1a54a76..a618e9c 100644
--- a/objectivec/GPBDuration.pbobjc.m
+++ b/objectivec/GPBDuration.pbobjc.m
@@ -86,9 +86,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBDuration__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
diff --git a/objectivec/GPBEmpty.pbobjc.m b/objectivec/GPBEmpty.pbobjc.m
index b69738c..c33be8b 100644
--- a/objectivec/GPBEmpty.pbobjc.m
+++ b/objectivec/GPBEmpty.pbobjc.m
@@ -62,9 +62,9 @@
fieldCount:0
storageSize:sizeof(GPBEmpty__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
diff --git a/objectivec/GPBFieldMask.pbobjc.m b/objectivec/GPBFieldMask.pbobjc.m
index 8de5ad4..347bcbe 100644
--- a/objectivec/GPBFieldMask.pbobjc.m
+++ b/objectivec/GPBFieldMask.pbobjc.m
@@ -75,9 +75,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBFieldMask__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
diff --git a/objectivec/GPBSourceContext.pbobjc.m b/objectivec/GPBSourceContext.pbobjc.m
index 7ae605b..cea417d 100644
--- a/objectivec/GPBSourceContext.pbobjc.m
+++ b/objectivec/GPBSourceContext.pbobjc.m
@@ -75,9 +75,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBSourceContext__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
diff --git a/objectivec/GPBStruct.pbobjc.m b/objectivec/GPBStruct.pbobjc.m
index eabd761..600b495 100644
--- a/objectivec/GPBStruct.pbobjc.m
+++ b/objectivec/GPBStruct.pbobjc.m
@@ -115,9 +115,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBStruct__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -222,9 +222,9 @@
[localDescriptor setupOneofs:oneofs
count:(uint32_t)(sizeof(oneofs) / sizeof(char*))
firstHasIndex:-1];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -285,9 +285,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBListValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
diff --git a/objectivec/GPBTimestamp.pbobjc.m b/objectivec/GPBTimestamp.pbobjc.m
index edd7349..dc6baeb 100644
--- a/objectivec/GPBTimestamp.pbobjc.m
+++ b/objectivec/GPBTimestamp.pbobjc.m
@@ -86,9 +86,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBTimestamp__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
diff --git a/objectivec/GPBType.pbobjc.m b/objectivec/GPBType.pbobjc.m
index db7a41f..7b44e39 100644
--- a/objectivec/GPBType.pbobjc.m
+++ b/objectivec/GPBType.pbobjc.m
@@ -307,9 +307,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBType__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -468,9 +468,9 @@
"\001\006\004\241!!\000";
[localDescriptor setupExtraTextInfo:extraTextFormatInfo];
#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -593,9 +593,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBEnum__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -673,9 +673,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBEnumValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -730,9 +730,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBOption__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
diff --git a/objectivec/GPBWrappers.pbobjc.m b/objectivec/GPBWrappers.pbobjc.m
index 07be68b..30461e3 100644
--- a/objectivec/GPBWrappers.pbobjc.m
+++ b/objectivec/GPBWrappers.pbobjc.m
@@ -83,9 +83,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBDoubleValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -129,9 +129,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBFloatValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -175,9 +175,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBInt64Value__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -221,9 +221,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBUInt64Value__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -267,9 +267,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBInt32Value__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -313,9 +313,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBUInt32Value__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -358,9 +358,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBBoolValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -404,9 +404,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBStringValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
@@ -450,9 +450,9 @@
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBBytesValue__storage_)
flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown | GPBDescriptorInitializationFlag_ClosedEnumSupportKnown)];
- #if defined(DEBUG) && DEBUG
+#if defined(DEBUG) && DEBUG
NSAssert(descriptor == nil, @"Startup recursed!");
- #endif // DEBUG
+#endif // DEBUG
descriptor = localDescriptor;
}
return descriptor;
diff --git a/src/google/protobuf/compiler/retention.cc b/src/google/protobuf/compiler/retention.cc
index 8790128..b296fbb 100644
--- a/src/google/protobuf/compiler/retention.cc
+++ b/src/google/protobuf/compiler/retention.cc
@@ -37,6 +37,7 @@
#include <vector>
#include "absl/container/flat_hash_set.h"
+#include "absl/strings/match.h"
#include "absl/types/span.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/dynamic_message.h"
@@ -47,6 +48,15 @@
namespace {
+bool IsOptionsProto(const Message& m) {
+ const Descriptor* descriptor = m.GetDescriptor();
+ return descriptor->file()->name() ==
+ DescriptorProto::descriptor()->file()->name() &&
+ absl::EndsWith(descriptor->name(), "Options");
+}
+
+bool IsEmpty(const Message& m) { return m.ByteSizeLong() == 0; }
+
// Recursively strips any options with source retention from the message. If
// stripped_paths is not null, then this function will populate it with the
// paths that were stripped, using the path format from
@@ -74,8 +84,18 @@
path.pop_back();
}
} else {
- StripMessage(*reflection->MutableMessage(&m, field), path,
- stripped_paths);
+ Message* child = reflection->MutableMessage(&m, field);
+ bool was_nonempty_options_proto =
+ IsOptionsProto(*child) && !IsEmpty(*child);
+ StripMessage(*child, path, stripped_paths);
+ // If this is an options message that became empty due to retention
+ // stripping, remove it.
+ if (was_nonempty_options_proto && IsEmpty(*child)) {
+ reflection->ClearField(&m, field);
+ if (stripped_paths != nullptr) {
+ stripped_paths->push_back(path);
+ }
+ }
}
}
path.pop_back();
diff --git a/src/google/protobuf/retention_test.cc b/src/google/protobuf/retention_test.cc
index 4e5af2d..5ccd705 100644
--- a/src/google/protobuf/retention_test.cc
+++ b/src/google/protobuf/retention_test.cc
@@ -244,6 +244,47 @@
EXPECT_EQ(stripped_file.source_code_info().location_size(), 63);
}
+TEST(RetentionTest, RemoveEmptyOptions) {
+ // If an options message is completely empty after stripping, that message
+ // should be removed.
+ std::string proto_file =
+ absl::Substitute(R"(
+ syntax = "proto2";
+
+ package google.protobuf.internal;
+
+ import "$0";
+
+ message Extendee {
+ extensions 1 to max [declaration = {
+ number: 1,
+ full_name: ".my.ext",
+ type: ".my.Message",
+ }];
+ })",
+ FileDescriptorSet::descriptor()->file()->name());
+ io::ArrayInputStream input_stream(proto_file.data(),
+ static_cast<int>(proto_file.size()));
+ io::ErrorCollector error_collector;
+ io::Tokenizer tokenizer(&input_stream, &error_collector);
+ compiler::Parser parser;
+ FileDescriptorProto file_descriptor;
+ ASSERT_TRUE(parser.Parse(&tokenizer, &file_descriptor));
+ file_descriptor.set_name("retention.proto");
+
+ DescriptorPool pool;
+ FileDescriptorProto descriptor_proto_descriptor;
+ FileDescriptorSet::descriptor()->file()->CopyTo(&descriptor_proto_descriptor);
+ pool.BuildFile(descriptor_proto_descriptor);
+ pool.BuildFile(file_descriptor);
+
+ FileDescriptorProto stripped_file = compiler::StripSourceRetentionOptions(
+ *pool.FindFileByName("retention.proto"));
+ ASSERT_EQ(stripped_file.message_type_size(), 1);
+ ASSERT_EQ(stripped_file.message_type(0).extension_range_size(), 1);
+ EXPECT_FALSE(stripped_file.message_type(0).extension_range(0).has_options());
+}
+
TEST(RetentionTest, InvalidDescriptor) {
// This test creates an invalid descriptor and makes sure we can strip its
// options without crashing.