Internal change
PiperOrigin-RevId: 812009227
diff --git a/src/google/protobuf/compiler/cpp/file_unittest.cc b/src/google/protobuf/compiler/cpp/file_unittest.cc
index 58c07e7..b340f4e 100644
--- a/src/google/protobuf/compiler/cpp/file_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/file_unittest.cc
@@ -175,6 +175,7 @@
"TestVerifyInt32BigFieldNumber",
"TestVerifyInt32",
"TestRequiredMessage",
+ "TestRequiredLazyMessage",
"TestParsingMerge.RepeatedGroup",
"TestParsingMerge.RepeatedFieldsGenerator.Group2",
"TestParsingMerge.RepeatedFieldsGenerator.Group1",
diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc
index e7c771f..281cf2c 100644
--- a/src/google/protobuf/compiler/cpp/helpers.cc
+++ b/src/google/protobuf/compiler/cpp/helpers.cc
@@ -1371,6 +1371,15 @@
!HasSimpleBaseClass(descriptor, options);
}
+// Returns true if a message (descriptor) directly has required fields. Later
+// CLs will expand to cover transitively required fields.
+bool ShouldVerifyV2(const Descriptor* descriptor, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer) {
+ if (!ShouldVerify(descriptor, options, scc_analyzer)) return false;
+
+ return HasRequiredFields(descriptor);
+}
+
bool IsEligibleForV2Batching(const FieldDescriptor* field) {
// Non-message fields whose numbers fit into 2B should be considered for
// batching although the actual batching depends on the current batching, the
diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h
index ef643e0..174fd3f 100644
--- a/src/google/protobuf/compiler/cpp/helpers.h
+++ b/src/google/protobuf/compiler/cpp/helpers.h
@@ -529,6 +529,11 @@
bool IsV2CodegenEnabled(const Options& options);
bool ShouldGenerateV2Code(const Descriptor* descriptor, const Options& options);
+// Returns true if a message (descriptor) needs v2 verify function because it
+// may (transitively) contain a required field.
+bool ShouldVerifyV2(const Descriptor* descriptor, const Options& options,
+ MessageSCCAnalyzer* scc_analyzer);
+
// Returns true if a field can be batched.
bool IsEligibleForV2Batching(const FieldDescriptor* field);
bool HasFieldEligibleForV2Batching(const Descriptor* descriptor);
diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc
index 098739c..8b2b1ea 100644
--- a/src/google/protobuf/compiler/cpp/message.cc
+++ b/src/google/protobuf/compiler/cpp/message.cc
@@ -72,6 +72,11 @@
using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic;
using Sub = ::google::protobuf::io::Printer::Sub;
+template <typename T>
+inline std::string PrintUnsignedLiteral(T value) {
+ return absl::StrCat(value, "u");
+}
+
// Create an expression that evaluates to
// "for all i, (_has_bits_[i] & masks[i]) == masks[i]"
// masks is allowed to be shorter than _has_bits_, but at least one element of
@@ -4669,6 +4674,9 @@
void MessageGenerator::GenerateVerify(io::Printer* p) {
}
+void MessageGenerator::GenerateVerifyV2(io::Printer* p) {
+}
+
void MessageGenerator::GenerateSerializeOneofFields(
io::Printer* p, const std::vector<const FieldDescriptor*>& fields) {
ABSL_CHECK(!fields.empty());
diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h
index 60f697c..1ef7d4e 100644
--- a/src/google/protobuf/compiler/cpp/message.h
+++ b/src/google/protobuf/compiler/cpp/message.h
@@ -121,6 +121,7 @@
void GenerateOneofClear(io::Printer* p);
void GenerateVerifyDecl(io::Printer* p);
void GenerateVerify(io::Printer* p);
+ void GenerateVerifyV2(io::Printer* p);
void GenerateAnnotationDecl(io::Printer* p);
void GenerateSerializeWithCachedSizes(io::Printer* p);
void GenerateSerializeWithCachedSizesToArray(io::Printer* p);
diff --git a/src/google/protobuf/compiler/cpp/test_bad_identifiers_editions.proto b/src/google/protobuf/compiler/cpp/test_bad_identifiers_editions.proto
index c48d4e3..bd44687 100644
--- a/src/google/protobuf/compiler/cpp/test_bad_identifiers_editions.proto
+++ b/src/google/protobuf/compiler/cpp/test_bad_identifiers_editions.proto
@@ -36,7 +36,6 @@
// Use common namespaces to make sure we are properly qualifying
message std {}
-
int32 input = 1;
int32 output = 2;
string length = 3;
diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h
index 61112c8..b4c10c5 100644
--- a/src/google/protobuf/parse_context.h
+++ b/src/google/protobuf/parse_context.h
@@ -533,6 +533,7 @@
ParseContext* ctx);
using LazyEagerVerifyFnRef = std::remove_pointer<LazyEagerVerifyFnType>::type&;
+
// ParseContext holds all data that is global to the entire parse. Most
// importantly it contains the input stream, but also recursion depth and also
// stores the end group tag, in case a parser ended on a endgroup, to verify
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto
index a631e91..d377a55 100644
--- a/src/google/protobuf/unittest.proto
+++ b/src/google/protobuf/unittest.proto
@@ -802,6 +802,11 @@
];
}
+message TestRequiredLazyMessage {
+ TestRequired child = 1 [lazy = true];
+ TestRequiredLazyMessage recurse = 2 [lazy = true];
+}
+
message TestNestedRequiredForeign {
TestNestedRequiredForeign child = 1;
TestRequiredForeign payload = 2;