Internal change

PiperOrigin-RevId: 808889863
diff --git a/src/google/protobuf/generated_message_tctable_impl.h b/src/google/protobuf/generated_message_tctable_impl.h
index b0654ee..c09c29c 100644
--- a/src/google/protobuf/generated_message_tctable_impl.h
+++ b/src/google/protobuf/generated_message_tctable_impl.h
@@ -43,6 +43,7 @@
 
 namespace internal {
 
+
 enum {
   kInlinedStringAuxIdx = 0,
   kSplitOffsetAuxIdx = 1,
@@ -854,6 +855,9 @@
   template <typename FieldType>
   PROTOBUF_CC static const char* FastVarintS1(PROTOBUF_TC_PARAM_DECL);
 
+  static LazyEagerVerifyFnType GetLazyEagerVerifyFn(
+      const google::protobuf::internal::TcParseTableBase* table, uint32_t field_number);
+
   friend class GeneratedTcTableLiteTest;
   static void* MaybeGetSplitBase(MessageLite* msg, bool is_split,
                                  const TcParseTableBase* table);
diff --git a/src/google/protobuf/generated_message_tctable_lite.cc b/src/google/protobuf/generated_message_tctable_lite.cc
index 5176e11..cc06c06 100644
--- a/src/google/protobuf/generated_message_tctable_lite.cc
+++ b/src/google/protobuf/generated_message_tctable_lite.cc
@@ -99,6 +99,16 @@
 
 }  // namespace
 
+LazyEagerVerifyFnType TcParser::GetLazyEagerVerifyFn(
+    const google::protobuf::internal::TcParseTableBase* table, uint32_t field_number) {
+  auto* entry = TcParser::FindFieldEntry(table, field_number);
+  if (ABSL_PREDICT_FALSE(entry == nullptr)) return nullptr;
+  if (ABSL_PREDICT_FALSE(entry->aux_idx == entry->kNoAuxIdx)) return nullptr;
+
+  const auto* aux = table->field_aux(entry);
+  return aux[1].verify_func;
+}
+
 absl::Status TcParser::VerifyHasBitConsistency(const MessageLite* msg,
                                                const TcParseTableBase* table) {
   namespace fl = internal::field_layout;
@@ -315,9 +325,7 @@
 }
 
 // On the fast path, a (matching) 1-byte tag already has the decoded value.
-static uint32_t FastDecodeTag(uint8_t coded_tag) {
-  return coded_tag;
-}
+static uint32_t FastDecodeTag(uint8_t coded_tag) { return coded_tag; }
 
 // On the fast path, a (matching) 2-byte tag always needs to be decoded.
 static uint32_t FastDecodeTag(uint16_t coded_tag) {
@@ -566,21 +574,21 @@
   static_assert(7 == FieldKind::kFkMap, "Invalid table order");
 
   static_assert(8 == (+field_layout::kSplitMask | FieldKind::kFkNone),
-    "Invalid table order");
+                "Invalid table order");
   static_assert(9 == (+field_layout::kSplitMask | FieldKind::kFkVarint),
-    "Invalid table order");
+                "Invalid table order");
   static_assert(10 == (+field_layout::kSplitMask | FieldKind::kFkPackedVarint),
-    "Invalid table order");
+                "Invalid table order");
   static_assert(11 == (+field_layout::kSplitMask | FieldKind::kFkFixed),
-    "Invalid table order");
+                "Invalid table order");
   static_assert(12 == (+field_layout::kSplitMask | FieldKind::kFkPackedFixed),
-    "Invalid table order");
+                "Invalid table order");
   static_assert(13 == (+field_layout::kSplitMask | FieldKind::kFkString),
-    "Invalid table order");
+                "Invalid table order");
   static_assert(14 == (+field_layout::kSplitMask | FieldKind::kFkMessage),
-    "Invalid table order");
+                "Invalid table order");
   static_assert(15 == (+field_layout::kSplitMask | FieldKind::kFkMap),
-    "Invalid table order");
+                "Invalid table order");
 
   TailCallParseFunc parse_fn = kMiniParseTable[field_type];
   if (export_called_function) *test_out = {parse_fn, tag, entry};
diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h
index 8463d1b..4956140 100644
--- a/src/google/protobuf/parse_context.h
+++ b/src/google/protobuf/parse_context.h
@@ -641,6 +641,9 @@
     if (ABSL_PREDICT_FALSE(!ConsumeEndGroup(tag))) return nullptr;
     return ptr;
   }
+  template <typename Func>
+  [[nodiscard]] PROTOBUF_ALWAYS_INLINE const char* ParseWithLengthInlined(
+      const char* ptr, uint32_t length, const Func& func);
 
  private:
   // Out-of-line routine to save space in ParseContext::ParseMessage<T>
@@ -1243,6 +1246,23 @@
   return ptr;
 }
 
+// Note that "length" is read outside of this function.
+template <typename Func>
+[[nodiscard]] PROTOBUF_ALWAYS_INLINE const char*
+ParseContext::ParseWithLengthInlined(const char* ptr, uint32_t length,
+                                     const Func& func) {
+  ABSL_DCHECK_NE(ptr, nullptr);
+  LimitToken old;
+  old = PushLimit(ptr, length);
+  --depth_;
+  auto old_depth = depth_;
+  PROTOBUF_ALWAYS_INLINE_CALL ptr = func(ptr);
+  if (ptr != nullptr) ABSL_DCHECK_EQ(old_depth, depth_);
+  depth_++;
+  if (!PopLimit(std::move(old))) return nullptr;
+  return ptr;
+}
+
 inline const char* EpsCopyInputStream::ReadMicroString(const char* ptr,
                                                        MicroString& str,
                                                        Arena* arena) {