Do not cache dynamic descriptors in FuzzTest's static descriptor cache.

PiperOrigin-RevId: 976461681
diff --git a/domain_tests/arbitrary_domains_protobuf_test.cc b/domain_tests/arbitrary_domains_protobuf_test.cc
index a770b01..85aae8f 100644
--- a/domain_tests/arbitrary_domains_protobuf_test.cc
+++ b/domain_tests/arbitrary_domains_protobuf_test.cc
@@ -38,8 +38,10 @@
 #include "./domain_tests/domain_testing.h"
 #include "./fuzztest/internal/test_protobuf.pb.h"
 #include "google/protobuf/descriptor.h"
+#include "google/protobuf/dynamic_message.h"
 #include "google/protobuf/message.h"
 #include "google/protobuf/message_lite.h"
+#include "google/protobuf/descriptor.pb.h"
 #include "google/protobuf/util/message_differencer.h"
 
 namespace fuzztest {
@@ -853,5 +855,33 @@
   EXPECT_TRUE(domain2.ValidateCorpusValue(*corpus2).ok());
 }
 
+TEST(ProtobufDomainTest, EnsureNoUseAfterFreeAcrossDynamicPoolDestructions) {
+  google::protobuf::FileDescriptorProto file_proto;
+  file_proto.set_name("dynamic_test.proto");
+  auto* message_proto = file_proto.add_message_type();
+  message_proto->set_name("DynamicTestMessage");
+  auto* field = message_proto->add_field();
+  field->set_name("dynamic_field");
+  field->set_number(1);
+  field->set_type(google::protobuf::FieldDescriptorProto::TYPE_INT32);
+
+  for (int i = 0; i < 10; ++i) {
+    google::protobuf::DescriptorPool pool;
+    const google::protobuf::FileDescriptor* file_desc = pool.BuildFile(file_proto);
+    ASSERT_NE(file_desc, nullptr);
+    const google::protobuf::Descriptor* message_desc =
+        file_desc->FindMessageTypeByName("DynamicTestMessage");
+    ASSERT_NE(message_desc, nullptr);
+
+    google::protobuf::DynamicMessageFactory factory(&pool);
+    const google::protobuf::Message* prototype = factory.GetPrototype(message_desc);
+    ASSERT_NE(prototype, nullptr);
+
+    auto domain = ProtobufOf([prototype] { return prototype; });
+    auto values = GenerateInitialValues(domain, 10);
+    EXPECT_FALSE(values.empty());
+  }
+}
+
 }  // namespace
 }  // namespace fuzztest
diff --git a/fuzztest/internal/domains/protobuf_domain_impl.h b/fuzztest/internal/domains/protobuf_domain_impl.h
index 39f45e2..c3e3ca5 100644
--- a/fuzztest/internal/domains/protobuf_domain_impl.h
+++ b/fuzztest/internal/domains/protobuf_domain_impl.h
@@ -364,31 +364,45 @@
     return caches_->SetFields(descriptor, GetProtobufFields(descriptor));
   }
 
-  static const std::vector<const FieldDescriptor*>& GetProtobufFields(
+  static std::vector<const FieldDescriptor*> GetProtobufFields(
       const ProtoDescriptor* descriptor) {
-    ABSL_CONST_INIT static absl::Mutex mutex(absl::kConstInit);
-    static absl::NoDestructor<absl::flat_hash_map<
-        const ProtoDescriptor*,
-        std::unique_ptr<std::vector<const FieldDescriptor*>>>>
-        descriptor_to_fields ABSL_GUARDED_BY(mutex);
-    {
+    const auto* pool = descriptor->file()->pool();
+    const bool is_generated_pool = (pool == pool->generated_pool());
+    if (is_generated_pool) {
+      ABSL_CONST_INIT static absl::Mutex mutex(absl::kConstInit);
+      static absl::NoDestructor<absl::flat_hash_map<
+          const ProtoDescriptor*,
+          std::unique_ptr<std::vector<const FieldDescriptor*>>>>
+          descriptor_to_fields ABSL_GUARDED_BY(mutex);
+      {
+        absl::MutexLock l(mutex);
+        auto it = descriptor_to_fields->find(descriptor);
+        if (it != descriptor_to_fields->end()) return *(it->second);
+      }
+      std::vector<const FieldDescriptor*> fields;
+      fields.reserve(descriptor->field_count());
+      for (int i = 0; i < descriptor->field_count(); ++i) {
+        fields.push_back(descriptor->field(i));
+      }
       absl::MutexLock l(mutex);
-      auto it = descriptor_to_fields->find(descriptor);
-      if (it != descriptor_to_fields->end()) return *(it->second);
+      if (ShouldEnumerateExtensions(descriptor)) {
+        pool->FindAllExtensions(descriptor, &fields);
+      }
+      auto [it, _] = descriptor_to_fields->insert(
+          {descriptor, std::make_unique<std::vector<const FieldDescriptor*>>(
+                           std::move(fields))});
+      return *(it->second);
     }
+
     std::vector<const FieldDescriptor*> fields;
     fields.reserve(descriptor->field_count());
     for (int i = 0; i < descriptor->field_count(); ++i) {
       fields.push_back(descriptor->field(i));
     }
-    absl::MutexLock l(mutex);
     if (ShouldEnumerateExtensions(descriptor)) {
-      descriptor->file()->pool()->FindAllExtensions(descriptor, &fields);
+      pool->FindAllExtensions(descriptor, &fields);
     }
-    auto [it, _] = descriptor_to_fields->insert(
-        {descriptor, std::make_unique<std::vector<const FieldDescriptor*>>(
-                         std::move(fields))});
-    return *(it->second);
+    return fields;
   }
 
  private: