diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index 923d8c1..b291a4e 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -26,6 +26,7 @@
 
 #include "absl/base/attributes.h"
 #include "absl/base/optimization.h"
+#include "absl/container/btree_map.h"
 #include "absl/container/flat_hash_set.h"
 #include "absl/functional/overload.h"
 #include "absl/hash/hash.h"
@@ -49,6 +50,10 @@
 namespace google {
 namespace protobuf {
 namespace internal {
+
+struct ExtensionSet::LargeMap : public absl::btree_map<int, Extension> {
+  using btree_map::btree_map;
+};
 namespace {
 
 inline WireFormatLite::FieldType real_type(FieldType type) {
@@ -1565,6 +1570,39 @@ std::pair<ExtensionSet::Extension*, bool>
 ExtensionSet::InternalInsertIntoLargeMap(int key) {
   ABSL_DCHECK(is_large());
   auto maybe = map_.large->insert({key, Extension()});
   return {&maybe.first->second, maybe.second};
 }
 
+size_t ExtensionSet::LargeMapSize() const {
+  return map_.large->size();
+}
+
+void ExtensionSet::ForEachLargeMap(
+    absl::FunctionRef<void(int, Extension&)> func,
+    absl::FunctionRef<void(const void*)> prefetch_func) {
+  ForEachPrefetchImpl(map_.large->begin(), map_.large->end(), func,
+                      prefetch_func);
+}
+
+void ExtensionSet::ForEachLargeMap(
+    absl::FunctionRef<void(int, const Extension&)> func,
+    absl::FunctionRef<void(const void*)> prefetch_func) const {
+  ForEachPrefetchImpl(map_.large->begin(), map_.large->end(), func,
+                      prefetch_func);
+}
+
+void ExtensionSet::ForEachNoPrefetchLargeMap(
+    absl::FunctionRef<void(int, Extension&)> func) {
+  ForEachNoPrefetch(map_.large->begin(), map_.large->end(), func);
+}
+
+void ExtensionSet::ForEachNoPrefetchLargeMap(
+    absl::FunctionRef<void(int, const Extension&)> func) const {
+  ForEachNoPrefetch(map_.large->begin(), map_.large->end(), func);
+}
+
+bool ExtensionSet::AnyOfNoPrefetchLargeMap(
+    absl::FunctionRef<bool(int, const Extension&)> predicate) const {
+  return AnyOfNoPrefetch(map_.large->begin(), map_.large->end(), predicate);
+}
+
 std::pair<ExtensionSet::Extension*, bool> ExtensionSet::Insert(Arena* arena,
                                                                int key) {
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index 923d8c1..b291a4e 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -34,7 +34,7 @@
 #include "google/protobuf/stubs/common.h"
 #include "absl/base/casts.h"
 #include "absl/base/prefetch.h"
-#include "absl/container/btree_map.h"
+#include "absl/functional/function_ref.h"
 #include "absl/log/absl_check.h"
 #include "absl/strings/string_view.h"
 #include "google/protobuf/generated_enum_util.h"
@@ -893,7 +893,7 @@ class PROTOBUF_EXPORT ExtensionSet {
     Extension second;
   };
 
-  using LargeMap = absl::btree_map<int, Extension>;
+  struct LargeMap;
 
   // Wrapper API that switches between flat-map and LargeMap.
 
@@ -911,6 +911,15 @@ class PROTOBUF_EXPORT ExtensionSet {
   // Same as insert for the large map.
   std::pair<Extension*, bool> InternalInsertIntoLargeMap(int key);
 
+  size_t LargeMapSize() const;
+  void ForEachLargeMap(absl::FunctionRef<void(int, Extension&)> func,
+                       absl::FunctionRef<void(const void*)> prefetch_func);
+  void ForEachLargeMap(absl::FunctionRef<void(int, const Extension&)> func,
+                       absl::FunctionRef<void(const void*)> prefetch_func) const;
+  void ForEachNoPrefetchLargeMap(absl::FunctionRef<void(int, Extension&)> func);
+  void ForEachNoPrefetchLargeMap(absl::FunctionRef<void(int, const Extension&)> func) const;
+  bool AnyOfNoPrefetchLargeMap(absl::FunctionRef<bool(int, const Extension&)> predicate) const;
+
   // Grows the flat_capacity_.
   // If flat_capacity_ > kMaximumFlatCapacity, converts to LargeMap.
   void GrowCapacity(Arena* arena, size_t minimum_new_capacity);
@@ -932,7 +941,7 @@ class PROTOBUF_EXPORT ExtensionSet {
   // Returns the number of elements in the ExtensionSet, including cleared
   // extensions.
   size_t Size() const {
-    return ABSL_PREDICT_FALSE(is_large()) ? map_.large->size() : flat_size_;
+    return ABSL_PREDICT_FALSE(is_large()) ? LargeMapSize() : flat_size_;
   }
 
   // For use as `PrefetchFunctor`s in `ForEach`.
@@ -975,8 +984,9 @@ class PROTOBUF_EXPORT ExtensionSet {
   template <typename KeyValueFunctor, typename PrefetchFunctor>
   void ForEach(KeyValueFunctor func, PrefetchFunctor prefetch_func) {
     if (ABSL_PREDICT_FALSE(is_large())) {
-      ForEachPrefetchImpl(map_.large->begin(), map_.large->end(),
-                          std::move(func), std::move(prefetch_func));
+      ForEachLargeMap(
+          [&](int k, Extension& ext) { func(k, ext); },
+          [&](const void* p) { prefetch_func(p); });
       return;
     }
     ForEachPrefetchImpl(flat_begin(), flat_end(), std::move(func),
@@ -986,8 +996,9 @@ class PROTOBUF_EXPORT ExtensionSet {
   template <typename KeyValueFunctor, typename PrefetchFunctor>
   void ForEach(KeyValueFunctor func, PrefetchFunctor prefetch_func) const {
     if (ABSL_PREDICT_FALSE(is_large())) {
-      ForEachPrefetchImpl(map_.large->begin(), map_.large->end(),
-                          std::move(func), std::move(prefetch_func));
+      ForEachLargeMap(
+          [&](int k, const Extension& ext) { func(k, ext); },
+          [&](const void* p) { prefetch_func(p); });
       return;
     }
     ForEachPrefetchImpl(flat_begin(), flat_end(), std::move(func),
@@ -1019,8 +1030,7 @@ class PROTOBUF_EXPORT ExtensionSet {
   template <typename KeyValueFunctor>
   void ForEachNoPrefetch(KeyValueFunctor func) {
     if (ABSL_PREDICT_FALSE(is_large())) {
-      ForEachNoPrefetch(map_.large->begin(), map_.large->end(),
-                        std::move(func));
+      ForEachNoPrefetchLargeMap([&](int k, Extension& ext) { func(k, ext); });
       return;
     }
     ForEachNoPrefetch(flat_begin(), flat_end(), std::move(func));
@@ -1030,8 +1040,8 @@ class PROTOBUF_EXPORT ExtensionSet {
   template <typename KeyValueFunctor>
   void ForEachNoPrefetch(KeyValueFunctor func) const {
     if (ABSL_PREDICT_FALSE(is_large())) {
-      ForEachNoPrefetch(map_.large->begin(), map_.large->end(),
-                        std::move(func));
+      ForEachNoPrefetchLargeMap(
+          [&](int k, const Extension& ext) { func(k, ext); });
       return;
     }
     ForEachNoPrefetch(flat_begin(), flat_end(), std::move(func));
@@ -1043,8 +1053,8 @@ class PROTOBUF_EXPORT ExtensionSet {
   template <typename KeyValueFunctor>
   bool AnyOfNoPrefetch(KeyValueFunctor predicate) const {
     if (ABSL_PREDICT_FALSE(is_large())) {
-      return AnyOfNoPrefetch(map_.large->begin(), map_.large->end(),
-                             std::move(predicate));
+      return AnyOfNoPrefetchLargeMap(
+          [&](int k, const Extension& ext) { return predicate(k, ext); });
     }
     return AnyOfNoPrefetch(flat_begin(), flat_end(), std::move(predicate));
   }
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index 923d8c1..b291a4e 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -365,7 +365,7 @@ int ExtensionSet::SpaceUsedExcludingSelf() const {
 
 size_t ExtensionSet::SpaceUsedExcludingSelfLong() const {
   size_t total_size =
-      (is_large() ? map_.large->size() : flat_capacity_) * sizeof(KeyValue);
+      (is_large() ? Size() : flat_capacity_) * sizeof(KeyValue);
   ForEach(
       [&total_size](int /* number */, const Extension& ext) {
         total_size += ext.SpaceUsedExcludingSelfLong();
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index 923d8c1..b291a4e 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -31,7 +31,6 @@
 #include "absl/base/attributes.h"
 #include "absl/base/optimization.h"
 #include "absl/base/prefetch.h"
-#include "absl/container/btree_map.h"
 #include "absl/hash/hash.h"
 #include "absl/log/absl_check.h"
 #include "absl/numeric/bits.h"
