Add Java (mutable) language feature handling to 2024 transform.

This handles all of the global java option changes, as well as the mutable/proto1 features.  These can't be reasonably separated because they're all so interdependent.

PiperOrigin-RevId: 803293866
diff --git a/editions/codegen_tests/edition2023_java_dual_multiple_files.proto b/editions/codegen_tests/edition2023_java_dual_multiple_files.proto
new file mode 100644
index 0000000..9c78f9c
--- /dev/null
+++ b/editions/codegen_tests/edition2023_java_dual_multiple_files.proto
@@ -0,0 +1,36 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2023 Google Inc.  All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+edition = "2023";
+
+package protobuf_editions_test.edition2023;
+
+option java_package = "com.google.protobuf.editions.test.edition2023";
+option java_multiple_files = true;
+option java_outer_classname = "Edition2023DualClassname";
+
+message Edition2023JavaDualMultipleFilesMessage {
+  int32 foo = 1;
+
+  message NestedMessage {
+    int32 bar = 1;
+  }
+
+  enum NestedEnum {
+    NESTED_ENUM_UNKNOWN = 0;
+  }
+}
+
+enum Edition2023JavaDualMultipleFilesEnum {
+  JAVA_DUAL_MULTIPLE_FILES_ENUM_UNKNOWN = 0;
+}
+
+service Edition2023JavaDualMultipleFilesService {
+  // Edition2023JavaDualMultipleFilesService.Method
+  rpc Method(Edition2023JavaDualMultipleFilesMessage.NestedMessage)
+      returns (Edition2023JavaDualMultipleFilesMessage) {}
+}
diff --git a/editions/codegen_tests/edition2023_java_multiple_files.proto b/editions/codegen_tests/edition2023_java_multiple_files.proto
new file mode 100644
index 0000000..02c87b9
--- /dev/null
+++ b/editions/codegen_tests/edition2023_java_multiple_files.proto
@@ -0,0 +1,35 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2023 Google Inc.  All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+edition = "2023";
+
+package protobuf_editions_test.edition2023;
+
+option java_package = "com.google.protobuf.editions.test.edition2023";
+option java_multiple_files = true;
+
+message Edition2023JavaMultipleFilesMessage {
+  int32 foo = 1;
+
+  message NestedMessage {
+    int32 bar = 1;
+  }
+
+  enum NestedEnum {
+    NESTED_ENUM_UNKNOWN = 0;
+  }
+}
+
+enum Edition2023JavaMultipleFilesEnum {
+  JAVA_MULTIPLE_FILES_ENUM_UNKNOWN = 0;
+}
+
+service Edition2023JavaMultipleFilesService {
+  // Edition2023JavaMultipleFilesService.Method
+  rpc Method(Edition2023JavaMultipleFilesMessage.NestedMessage)
+      returns (Edition2023JavaMultipleFilesMessage) {}
+}
diff --git a/editions/codegen_tests/edition2023_java_mutable_multiple_files.proto b/editions/codegen_tests/edition2023_java_mutable_multiple_files.proto
new file mode 100644
index 0000000..9998d37
--- /dev/null
+++ b/editions/codegen_tests/edition2023_java_mutable_multiple_files.proto
@@ -0,0 +1,35 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2023 Google Inc.  All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+edition = "2023";
+
+package protobuf_editions_test.edition2023;
+
+option java_package = "com.google.protobuf.editions.test.edition2023";
+option java_multiple_files = true;
+
+message Edition2023JavaMutableMultipleFilesMessage {
+  int32 foo = 1;
+
+  message NestedMessage {
+    int32 bar = 1;
+  }
+
+  enum NestedEnum {
+    NESTED_ENUM_UNKNOWN = 0;
+  }
+}
+
+enum Edition2023JavaMutableMultipleFilesEnum {
+  JAVA_MUTABLE_MULTIPLE_FILES_ENUM_UNKNOWN = 0;
+}
+
+service Edition2023JavaMutableMultipleFilesService {
+  // Edition2023JavaMutableMultipleFilesService.Method
+  rpc Method(Edition2023JavaMutableMultipleFilesMessage.NestedMessage)
+      returns (Edition2023JavaMutableMultipleFilesMessage) {}
+}
diff --git a/editions/codegen_tests/edition2023_java_no_multiple_files.proto b/editions/codegen_tests/edition2023_java_no_multiple_files.proto
new file mode 100644
index 0000000..bfac4f0
--- /dev/null
+++ b/editions/codegen_tests/edition2023_java_no_multiple_files.proto
@@ -0,0 +1,35 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2023 Google Inc.  All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+edition = "2023";
+
+package protobuf_editions_test.edition2023;
+
+option java_package = "com.google.protobuf.editions.test.edition2023";
+option java_outer_classname = "Edition2023NoMultipleFilesName";
+
+message Edition2023JavaNoMultipleFilesMessage {
+  int32 foo = 1;
+
+  message NestedMessage {
+    int32 bar = 1;
+  }
+
+  enum NestedEnum {
+    NESTED_ENUM_UNKNOWN = 0;
+  }
+}
+
+enum Edition2023JavaNoMultipleFilesEnum {
+  JAVA_NO_MULTIPLE_FILES_ENUM_UNKNOWN = 0;
+}
+
+service Edition2023JavaNoMultipleFilesService {
+  // Edition2023JavaNoMultipleFilesService.Method
+  rpc Method(Edition2023JavaNoMultipleFilesMessage.NestedMessage)
+      returns (Edition2023JavaNoMultipleFilesMessage) {}
+}
diff --git a/editions/codegen_tests/edition2023_java_outer_classname.proto b/editions/codegen_tests/edition2023_java_outer_classname.proto
new file mode 100644
index 0000000..c7b7701
--- /dev/null
+++ b/editions/codegen_tests/edition2023_java_outer_classname.proto
@@ -0,0 +1,35 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2023 Google Inc.  All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+edition = "2023";
+
+package protobuf_editions_test.edition2023;
+
+option java_package = "com.google.protobuf.editions.test.edition2023";
+option java_outer_classname = "Edition2023JavaName";
+
+message Edition2023OuterClassnameMessage {
+  int32 foo = 1;
+
+  message NestedMessage {
+    int32 bar = 1;
+  }
+
+  enum NestedEnum {
+    NESTED_ENUM_UNKNOWN = 0;
+  }
+}
+
+enum Edition2023OuterClassnameEnum {
+  JAVA_OUTER_CLASSNAME_ENUM_UNKNOWN = 0;
+}
+
+service Edition2023OuterClassnameService {
+  // Edition2023OuterClassnameService.Method
+  rpc Method(Edition2023OuterClassnameMessage.NestedMessage)
+      returns (Edition2023OuterClassnameMessage) {}
+}
diff --git a/editions/codegen_tests/edition2023_java_outer_classname_future.proto b/editions/codegen_tests/edition2023_java_outer_classname_future.proto
new file mode 100644
index 0000000..ca44e13
--- /dev/null
+++ b/editions/codegen_tests/edition2023_java_outer_classname_future.proto
@@ -0,0 +1,38 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2023 Google Inc.  All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+edition = "2023";
+
+package protobuf_editions_test.edition2023;
+
+option java_package = "com.google.protobuf.editions.test.edition2023";
+option java_multiple_files = true;
+
+// This is the default outer classname in edition 2024.
+option java_outer_classname = "Edition2023JavaOuterClassnameFutureProto";
+
+message Edition2023OuterClassnameFutureMessage {
+  int32 foo = 1;
+
+  message NestedMessage {
+    int32 bar = 1;
+  }
+
+  enum NestedEnum {
+    NESTED_ENUM_UNKNOWN = 0;
+  }
+}
+
+enum Edition2023OuterClassnameFutureEnum {
+  JAVA_OUTERCLASSNAME_FUTURE_ENUM_UNKNOWN = 0;
+}
+
+service Edition2023OuterclassnameFutureService {
+  // Edition2023OuterClassnameFutureService.Method
+  rpc Method(Edition2023OuterClassnameFutureMessage.NestedMessage)
+      returns (Edition2023OuterClassnameFutureMessage) {}
+}
diff --git a/editions/codegen_tests/edition2023_java_proto1_multiple_files.proto b/editions/codegen_tests/edition2023_java_proto1_multiple_files.proto
new file mode 100644
index 0000000..9a1d792
--- /dev/null
+++ b/editions/codegen_tests/edition2023_java_proto1_multiple_files.proto
@@ -0,0 +1,36 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2023 Google Inc.  All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+edition = "2023";
+
+package protobuf_editions_test.edition2023;
+
+option java_package = "com.google.protobuf.editions.test.edition2023";
+option java_multiple_files = true;
+option java_api_version = 1;
+
+message Edition2023JavaProto1MultipleFilesMessage {
+  int32 foo = 1;
+
+  message NestedMessage {
+    int32 bar = 1;
+  }
+
+  enum NestedEnum {
+    NESTED_ENUM_UNKNOWN = 0;
+  }
+}
+
+enum Edition2023JavaProto1MultipleFilesEnum {
+  JAVA_PROTO1_MULTIPLE_FILES_ENUM_UNKNOWN = 0;
+}
+
+service Edition2023JavaProto1MultipleFilesService {
+  // Edition2023JavaProto1MultipleFilesService.Method
+  rpc Method(Edition2023JavaProto1MultipleFilesMessage.NestedMessage)
+      returns (Edition2023JavaProto1MultipleFilesMessage) {}
+}
diff --git a/editions/codegen_tests/edition2023_java_proto1_no_multiple_files.proto b/editions/codegen_tests/edition2023_java_proto1_no_multiple_files.proto
new file mode 100644
index 0000000..41ebfb5
--- /dev/null
+++ b/editions/codegen_tests/edition2023_java_proto1_no_multiple_files.proto
@@ -0,0 +1,36 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2023 Google Inc.  All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+edition = "2023";
+
+package protobuf_editions_test.edition2023;
+
+option java_package = "com.google.protobuf.editions.test.edition2023";
+option java_outer_classname = "Edition2023NoMultipleFilesName";
+option java_api_version = 1;
+
+message Edition2023JavaProto1NoMultipleFilesMessage {
+  int32 foo = 1;
+
+  message NestedMessage {
+    int32 bar = 1;
+  }
+
+  enum NestedEnum {
+    NESTED_ENUM_UNKNOWN = 0;
+  }
+}
+
+enum Edition2023JavaProto1NoMultipleFilesEnum {
+  JAVA_PROTO1_NO_MULTIPLE_FILES_ENUM_UNKNOWN = 0;
+}
+
+service Edition2023JavaProto1NoMultipleFilesService {
+  // Edition2023JavaProto1NoMultipleFilesService.Method
+  rpc Method(Edition2023JavaProto1NoMultipleFilesMessage.NestedMessage)
+      returns (Edition2023JavaProto1NoMultipleFilesMessage) {}
+}
diff --git a/editions/codegen_tests/edition2023_java_proto1_outer_classname_future.proto b/editions/codegen_tests/edition2023_java_proto1_outer_classname_future.proto
new file mode 100644
index 0000000..f20675e
--- /dev/null
+++ b/editions/codegen_tests/edition2023_java_proto1_outer_classname_future.proto
@@ -0,0 +1,38 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2023 Google Inc.  All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+edition = "2023";
+
+package protobuf_editions_test.edition2023;
+
+option java_api_version = 1;
+option java_package = "com.google.protobuf.editions.test.edition2023";
+
+// This is what the default proto2 classname is.
+option java_outer_classname_proto1 = "Edition2023JavaProto1OuterclassnameFutureProto";
+
+message Edition2023Proto1OuterClassnameFutureMessage {
+  int32 foo = 1;
+
+  message NestedMessage {
+    int32 bar = 1;
+  }
+
+  enum NestedEnum {
+    NESTED_ENUM_UNKNOWN = 0;
+  }
+}
+
+enum Edition2023Proto1OuterClassnameFutureEnum {
+  JAVA_PROTO1_OUTERCLASSNAME_FUTURE_ENUM_UNKNOWN = 0;
+}
+
+service Edition2023Proto1OuterclassnameFutureService {
+  // Edition2023Proto1OuterClassnameFutureService.Method
+  rpc Method(Edition2023Proto1OuterClassnameFutureMessage.NestedMessage)
+      returns (Edition2023Proto1OuterClassnameFutureMessage) {}
+}
diff --git a/java/core/src/main/resources/google/protobuf/java_mutable_features.proto b/java/core/src/main/resources/google/protobuf/java_mutable_features.proto
index bc66ba1..c356e72 100644
--- a/java/core/src/main/resources/google/protobuf/java_mutable_features.proto
+++ b/java/core/src/main/resources/google/protobuf/java_mutable_features.proto
@@ -32,14 +32,10 @@
   }
 
   // Whether to nest the generated class in the generated file class for
-  // Java Proto2 Mutable API. This is only applicable to *top-level* messages,
-  // enums, and services.
+  // Java Proto2 Mutable API. This is only available at the file level.
   optional NestInFileClassFeature.NestInFileClass nest_in_file_class = 6 [
     retention = RETENTION_RUNTIME,
     targets = TARGET_TYPE_FILE,
-    targets = TARGET_TYPE_MESSAGE,
-    targets = TARGET_TYPE_ENUM,
-    targets = TARGET_TYPE_SERVICE,
     feature_support = {
       edition_introduced: EDITION_2024,
     },
diff --git a/src/google/protobuf/compiler/java/helpers.cc b/src/google/protobuf/compiler/java/helpers.cc
index 3650fc4..d829b33 100644
--- a/src/google/protobuf/compiler/java/helpers.cc
+++ b/src/google/protobuf/compiler/java/helpers.cc
@@ -32,6 +32,7 @@
 #include "google/protobuf/compiler/java/generator.h"
 #include "google/protobuf/compiler/java/name_resolver.h"
 #include "google/protobuf/compiler/versions.h"
+#include "google/protobuf/descriptor.h"
 #include "google/protobuf/descriptor.pb.h"
 #include "google/protobuf/io/printer.h"
 #include "google/protobuf/io/strtod.h"
diff --git a/src/google/protobuf/compiler/java/name_resolver_test.cc b/src/google/protobuf/compiler/java/name_resolver_test.cc
index 6b64785..f57f92b 100644
--- a/src/google/protobuf/compiler/java/name_resolver_test.cc
+++ b/src/google/protobuf/compiler/java/name_resolver_test.cc
@@ -141,6 +141,88 @@
             "ConflictingFileClassNameOuterClass");
 }
 
+TEST_F(NameResolverTest, FileProto1ClassNameEdition2023) {
+  BuildFileAndPopulatePool("foo.proto",
+                           R"schema(
+      edition = "2023";
+
+      package proto2_unittest;
+
+      option java_api_version = 1;
+
+      message Bar {
+        int32 field = 1;
+      }
+                )schema");
+
+  ClassNameResolver resolver;
+  auto file = pool_.FindFileByName("foo.proto");
+  EXPECT_EQ(resolver.GetFileClassName(file, /* immutable = */ false),
+            "FooOuterClass");
+}
+
+TEST_F(NameResolverTest, FileProto1ClassNameEdition2024) {
+  BuildFileAndPopulatePool("foo.proto",
+                           R"schema(
+      edition = "2024";
+
+      package proto2_unittest;
+
+      option java_api_version = 1;
+
+      message Bar {
+        int32 field = 1;
+      }
+                )schema");
+
+  ClassNameResolver resolver;
+  auto file = pool_.FindFileByName("foo.proto");
+  EXPECT_EQ(resolver.GetFileClassName(file, /* immutable = */ false),
+            "FooProto");
+}
+
+TEST_F(NameResolverTest, FileProto1ClassNameEdition2024Overridden) {
+  BuildFileAndPopulatePool("foo.proto",
+                           R"schema(
+      edition = "2024";
+
+      package proto2_unittest;
+
+      option java_api_version = 1;
+      option java_outer_classname = "BarBuz";
+
+      message Bar {
+        int32 field = 1;
+      }
+                )schema");
+
+  ClassNameResolver resolver;
+  auto file = pool_.FindFileByName("foo.proto");
+  EXPECT_EQ(resolver.GetFileClassName(file, /* immutable = */ false), "BarBuz");
+}
+
+TEST_F(NameResolverTest, FileProto1ClassNameEdition2024OverriddenProto1) {
+  BuildFileAndPopulatePool("foo.proto",
+                           R"schema(
+      edition = "2024";
+
+      package proto2_unittest;
+
+      option java_api_version = 1;
+      option java_outer_classname = "BarBuz";
+      option java_outer_classname_proto1 = "BarBuzProto1";
+
+      message Bar {
+        int32 field = 1;
+      }
+                )schema");
+
+  ClassNameResolver resolver;
+  auto file = pool_.FindFileByName("foo.proto");
+  EXPECT_EQ(resolver.GetFileClassName(file, /* immutable = */ false),
+            "BarBuzProto1");
+}
+
 TEST_F(NameResolverTest, MultipleFilesServiceEdition2023) {
   BuildFileAndPopulatePool("foo.proto",
                            R"schema(