Replace previous breaking changes with deprecation warnings.

These changes hid public APIs that are deprecated in advance of protobuf editions.  They will be fully removed in a future release.  Any uses of them should be migrated to the future-facing feature helpers we provide on descriptor classes.

PiperOrigin-RevId: 527422059
diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java
index be7c76a..e866d19 100644
--- a/java/core/src/main/java/com/google/protobuf/Descriptors.java
+++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java
@@ -162,6 +162,8 @@
     }
 
     /** The syntax of the .proto file. */
+    @Deprecated
+    public
     enum Syntax {
       UNKNOWN("unknown"),
       PROTO2("proto2"),
@@ -175,6 +177,8 @@
     }
 
     /** Get the syntax of the .proto file. */
+    @Deprecated
+    public
     Syntax getSyntax() {
       if (Syntax.PROTO3.name.equals(proto.getSyntax())) {
         return Syntax.PROTO3;
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index c12e9dc..51b6dd9 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -2612,10 +2612,12 @@
   }
 
   // TODO(liujisi): Also populate when syntax="proto2".
-  if (syntax() == SYNTAX_PROTO3
+  FileDescriptorLegacy::Syntax syntax = FileDescriptorLegacy(this).syntax();
+  if (syntax == FileDescriptorLegacy::Syntax::SYNTAX_PROTO3
   ) {
-    proto->set_syntax(SyntaxName(syntax()));
+    proto->set_syntax(FileDescriptorLegacy::SyntaxName(syntax));
   }
+
   if (&options() != &FileOptions::default_instance()) {
     *proto->mutable_options() = options();
   }
@@ -3010,8 +3012,9 @@
     SourceLocationCommentPrinter syntax_comment(this, path, "",
                                                 debug_string_options);
     syntax_comment.AddPreComment(&contents);
-    absl::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n",
-                              SyntaxName(syntax()));
+    absl::SubstituteAndAppend(
+        &contents, "syntax = \"$0\";\n\n",
+        FileDescriptorLegacy::SyntaxName(FileDescriptorLegacy(this).syntax()));
     syntax_comment.AddPostComment(&contents);
   }
 
@@ -3282,7 +3285,7 @@
 
   // Label is omitted for maps, oneof, and plain proto3 fields.
   if (is_map() || real_containing_oneof() ||
-      (is_optional() && !has_optional_keyword())) {
+      (is_optional() && !FieldDescriptorLegacy(this).has_optional_keyword())) {
     label.clear();
   }
 
@@ -3573,7 +3576,8 @@
 
 bool FieldDescriptor::is_packed() const {
   if (!is_packable()) return false;
-  if (file_->syntax() == FileDescriptor::SYNTAX_PROTO2) {
+  if (FileDescriptorLegacy(file_).syntax() ==
+      FileDescriptorLegacy::Syntax::SYNTAX_PROTO2) {
     return (options_ != nullptr) && options_->packed();
   } else {
     return options_ == nullptr || !options_->has_packed() || options_->packed();
@@ -3582,7 +3586,8 @@
 
 bool FieldDescriptor::requires_utf8_validation() const {
   return type() == TYPE_STRING &&
-         file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
+         FileDescriptorLegacy(file_).syntax() ==
+             FileDescriptorLegacy::Syntax::SYNTAX_PROTO3;
 }
 
 bool Descriptor::GetSourceLocation(SourceLocation* out_location) const {
@@ -3989,7 +3994,7 @@
                                     const Descriptor* result);
   void CheckFieldJsonNameUniqueness(const std::string& message_name,
                                     const DescriptorProto& message,
-                                    FileDescriptor::Syntax syntax,
+                                    FileDescriptorLegacy::Syntax syntax,
                                     bool use_custom_names);
   void CheckEnumValueUniqueness(const EnumDescriptorProto& proto,
                                 const EnumDescriptor* result);
@@ -4711,7 +4716,7 @@
   placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance();
   placeholder->source_code_info_ = &SourceCodeInfo::default_instance();
   placeholder->is_placeholder_ = true;
-  placeholder->syntax_ = FileDescriptor::SYNTAX_UNKNOWN;
+  placeholder->syntax_ = FileDescriptorLegacy::SYNTAX_UNKNOWN;
   placeholder->finished_building_ = true;
   // All other fields are zero or nullptr.
 
@@ -5226,11 +5231,11 @@
   // TODO(liujisi): Report error when the syntax is empty after all the protos
   // have added the syntax statement.
   if (proto.syntax().empty() || proto.syntax() == "proto2") {
-    file_->syntax_ = FileDescriptor::SYNTAX_PROTO2;
+    file_->syntax_ = FileDescriptorLegacy::SYNTAX_PROTO2;
   } else if (proto.syntax() == "proto3") {
-    file_->syntax_ = FileDescriptor::SYNTAX_PROTO3;
+    file_->syntax_ = FileDescriptorLegacy::SYNTAX_PROTO3;
   } else {
-    file_->syntax_ = FileDescriptor::SYNTAX_UNKNOWN;
+    file_->syntax_ = FileDescriptorLegacy::SYNTAX_UNKNOWN;
     AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, [&] {
       return absl::StrCat("Unrecognized syntax: ", proto.syntax());
     });
@@ -5681,11 +5686,12 @@
 
 void DescriptorBuilder::CheckFieldJsonNameUniqueness(
     const DescriptorProto& proto, const Descriptor* result) {
-  FileDescriptor::Syntax syntax = result->file()->syntax();
+  FileDescriptorLegacy::Syntax syntax =
+      FileDescriptorLegacy(result->file()).syntax();
   std::string message_name = result->full_name();
   if (pool_->deprecated_legacy_json_field_conflicts_ ||
       IsLegacyJsonFieldConflictEnabled(result->options())) {
-    if (syntax == FileDescriptor::SYNTAX_PROTO3) {
+    if (syntax == FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) {
       // Only check default JSON names for conflicts in proto3.  This is legacy
       // behavior that will be removed in a later version.
       CheckFieldJsonNameUniqueness(message_name, proto, syntax, false);
@@ -5725,7 +5731,7 @@
 
 void DescriptorBuilder::CheckFieldJsonNameUniqueness(
     const std::string& message_name, const DescriptorProto& message,
-    FileDescriptor::Syntax syntax, bool use_custom_names) {
+    FileDescriptorLegacy::Syntax syntax, bool use_custom_names) {
   absl::flat_hash_map<std::string, JsonNameDetails> name_to_field;
   for (const FieldDescriptorProto& field : message.field()) {
     JsonNameDetails details = GetJsonNameDetails(&field, use_custom_names);
@@ -5769,7 +5775,7 @@
     };
 
     bool involves_default = !details.is_custom || !match.is_custom;
-    if (syntax == FileDescriptor::SYNTAX_PROTO2 && involves_default) {
+    if (syntax == FileDescriptorLegacy::SYNTAX_PROTO2 && involves_default) {
       // TODO(b/261750676) Upgrade this to an error once downstream protos have
       // been fixed.
       AddWarning(message_name, field, DescriptorPool::ErrorCollector::NAME,
@@ -5808,7 +5814,8 @@
   result->proto3_optional_ = proto.proto3_optional();
 
   if (proto.proto3_optional() &&
-      file_->syntax() != FileDescriptor::SYNTAX_PROTO3) {
+      FileDescriptorLegacy(file_).syntax() !=
+          FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) {
     AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
              [&] {
                return absl::StrCat(
@@ -6221,7 +6228,8 @@
       // compatibility we issue only a warning for proto2.
       if ((pool_->deprecated_legacy_json_field_conflicts_ ||
            IsLegacyJsonFieldConflictEnabled(result->options())) &&
-          result->file()->syntax() == FileDescriptor::SYNTAX_PROTO2) {
+          FileDescriptorLegacy(result->file()).syntax() ==
+              FileDescriptorLegacy::Syntax::SYNTAX_PROTO2) {
         AddWarning(value->full_name(), proto.value(i),
                    DescriptorPool::ErrorCollector::NAME, make_error);
         continue;
@@ -6585,7 +6593,7 @@
     const FieldDescriptor* field = message->field(i);
     if (field->proto3_optional_) {
       if (!field->containing_oneof() ||
-          !field->containing_oneof()->is_synthetic()) {
+          !OneofDescriptorLegacy(field->containing_oneof()).is_synthetic()) {
         AddError(message->full_name(), proto.field(i),
                  DescriptorPool::ErrorCollector::OTHER,
                  "Fields with proto3_optional set must be "
@@ -6598,7 +6606,7 @@
   int first_synthetic = -1;
   for (int i = 0; i < message->oneof_decl_count(); i++) {
     const OneofDescriptor* oneof = message->oneof_decl(i);
-    if (oneof->is_synthetic()) {
+    if (OneofDescriptorLegacy(oneof).is_synthetic()) {
       if (first_synthetic == -1) {
         first_synthetic = i;
       }
@@ -7140,7 +7148,8 @@
       }
     }
   }
-  if (file->syntax() == FileDescriptor::SYNTAX_PROTO3) {
+  if (FileDescriptorLegacy(file).syntax() ==
+      FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) {
     ValidateProto3(file, proto);
   }
 }
@@ -7203,8 +7212,10 @@
   }
   if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
       field->enum_type() &&
-      field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_PROTO3 &&
-      field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_UNKNOWN) {
+      FileDescriptorLegacy(field->enum_type()->file()).syntax() !=
+          FileDescriptorLegacy::Syntax::SYNTAX_PROTO3 &&
+      FileDescriptorLegacy(field->enum_type()->file()).syntax() !=
+          FileDescriptorLegacy::Syntax::SYNTAX_UNKNOWN) {
     // Proto3 messages can only use Proto3 enum types; otherwise we can't
     // guarantee that the default value is zero.
     AddError(
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index 97829d2..347f51a 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -79,6 +79,8 @@
 
 #ifdef SWIG
 #define PROTOBUF_EXPORT
+#define PROTOBUF_IGNORE_DEPRECATION_START
+#define PROTOBUF_IGNORE_DEPRECATION_STOP
 #endif
 
 
@@ -922,10 +924,17 @@
   friend class Reflection;
   friend class FieldDescriptorLegacy;
 
+
+ public:
+  ABSL_DEPRECATED(
+      "Syntax is deprecated in favor of editions, please use "
+      "FieldDescriptor::has_presence instead.")
   // Returns true if this field was syntactically written with "optional" in the
   // .proto file. Excludes singular proto3 fields that do not have a label.
   bool has_optional_keyword() const;
 
+ private:
+
   // Fill the json_name field of FieldDescriptorProto.
   void CopyJsonNameTo(FieldDescriptorProto* proto) const;
 
@@ -1083,10 +1092,17 @@
   friend class compiler::cpp::Formatter;
   friend class OneofDescriptorLegacy;
 
+
+ public:
+  ABSL_DEPRECATED(
+      "Syntax is deprecated in favor of editions, please use "
+      "real_oneof_decl_count for now instead of is_synthetic.")
   // Returns whether this oneof was inserted by the compiler to wrap a proto3
   // optional field. If this returns true, code generators should *not* emit it.
   bool is_synthetic() const;
 
+ private:
+
   // See Descriptor::DebugString().
   void DebugString(int depth, std::string* contents,
                    const DebugStringOptions& options) const;
@@ -1657,12 +1673,18 @@
   // descriptor.proto, and any available extensions of that message.
   const FileOptions& options() const;
 
+
  private:
   // With the upcoming release of editions, syntax should not be used for
   // business logic.  Instead, the various feature helpers defined in this file
   // should be used to query more targeted behaviors.  For example:
   // has_presence, is_closed, requires_utf8_validation.
-  enum Syntax
+  enum
+      ABSL_DEPRECATED(
+          "Syntax is deprecated in favor of editions.  Please use targeted "
+          "feature helpers instead (e.g. has_presence, is_packed, "
+          "requires_utf8_validation, etc).")
+          Syntax
 #ifndef SWIG
       : int
 #endif  // !SWIG
@@ -1671,13 +1693,22 @@
     SYNTAX_PROTO2 = 2,
     SYNTAX_PROTO3 = 3,
   };
+  PROTOBUF_IGNORE_DEPRECATION_START
+  ABSL_DEPRECATED(
+      "Syntax is deprecated in favor of editions.  Please use targeted "
+      "feature helpers instead (e.g. has_presence, is_packed, "
+      "requires_utf8_validation, etc).")
   Syntax syntax() const;
+  PROTOBUF_IGNORE_DEPRECATION_STOP
 
   // Define a visibility-restricted wrapper for internal use until the migration
   // is complete.
   friend class FileDescriptorLegacy;
 
+  PROTOBUF_IGNORE_DEPRECATION_START
+  ABSL_DEPRECATED("Syntax is deprecated in favor of editions")
   static const char* SyntaxName(Syntax syntax);
+  PROTOBUF_IGNORE_DEPRECATION_STOP
 
  public:
 
@@ -2314,7 +2345,9 @@
 PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, reserved_name_count, int)
 
 inline bool EnumDescriptor::is_closed() const {
+  PROTOBUF_IGNORE_DEPRECATION_START
   return file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
+  PROTOBUF_IGNORE_DEPRECATION_STOP
 }
 
 PROTOBUF_DEFINE_NAME_ACCESSOR(EnumValueDescriptor)
@@ -2465,25 +2498,33 @@
 }
 
 inline bool FieldDescriptor::has_optional_keyword() const {
+  PROTOBUF_IGNORE_DEPRECATION_START
   return proto3_optional_ ||
          (file()->syntax() == FileDescriptor::SYNTAX_PROTO2 && is_optional() &&
           !containing_oneof());
+  PROTOBUF_IGNORE_DEPRECATION_STOP
 }
 
 inline const OneofDescriptor* FieldDescriptor::real_containing_oneof() const {
+  PROTOBUF_IGNORE_DEPRECATION_START
   auto* oneof = containing_oneof();
   return oneof && !oneof->is_synthetic() ? oneof : nullptr;
+  PROTOBUF_IGNORE_DEPRECATION_STOP
 }
 
 inline bool FieldDescriptor::has_presence() const {
+  PROTOBUF_IGNORE_DEPRECATION_START
   if (is_repeated()) return false;
   return cpp_type() == CPPTYPE_MESSAGE || containing_oneof() ||
          file()->syntax() == FileDescriptor::SYNTAX_PROTO2;
+  PROTOBUF_IGNORE_DEPRECATION_STOP
 }
 
 inline bool FieldDescriptor::legacy_enum_field_treated_as_closed() const {
+  PROTOBUF_IGNORE_DEPRECATION_START
   return type() == TYPE_ENUM &&
          file()->syntax() == FileDescriptor::SYNTAX_PROTO2;
+  PROTOBUF_IGNORE_DEPRECATION_STOP
 }
 
 // To save space, index() is computed by looking at the descriptor's position
@@ -2586,9 +2627,11 @@
   return dependency(weak_dependencies_[index]);
 }
 
+PROTOBUF_IGNORE_DEPRECATION_START
 inline FileDescriptor::Syntax FileDescriptor::syntax() const {
   return static_cast<Syntax>(syntax_);
 }
+PROTOBUF_IGNORE_DEPRECATION_STOP
 
 namespace internal {
 
diff --git a/src/google/protobuf/descriptor_legacy.h b/src/google/protobuf/descriptor_legacy.h
index 763f447..75b9cfa 100644
--- a/src/google/protobuf/descriptor_legacy.h
+++ b/src/google/protobuf/descriptor_legacy.h
@@ -66,6 +66,7 @@
 
 namespace google {
 namespace protobuf {
+PROTOBUF_IGNORE_DEPRECATION_START
 
 // Wraps FileDescriptor.
 class PROTOBUF_EXPORT FileDescriptorLegacy {
@@ -74,10 +75,15 @@
 
   // Any dependencies on file-level syntax keyword should be replaced by
   // feature-level switches to support go/protobuf-editions.
-  using Syntax = FileDescriptor::Syntax;
-  Syntax syntax() const { return desc_->syntax(); }
+  enum Syntax {
+    SYNTAX_UNKNOWN = FileDescriptor::SYNTAX_UNKNOWN,
+    SYNTAX_PROTO2 = FileDescriptor::SYNTAX_PROTO2,
+    SYNTAX_PROTO3 = FileDescriptor::SYNTAX_PROTO3,
+  };
+  Syntax syntax() const { return static_cast<Syntax>(desc_->syntax()); }
   static absl::string_view SyntaxName(Syntax syntax) {
-    return FileDescriptor::SyntaxName(syntax);
+    return FileDescriptor::SyntaxName(
+        static_cast<FileDescriptor::Syntax>(syntax));
   }
 
  private:
@@ -104,6 +110,7 @@
   const OneofDescriptor* desc_;
 };
 
+PROTOBUF_IGNORE_DEPRECATION_STOP
 }  // namespace protobuf
 }  // namespace google