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;