From 88d8f6001d4b14520488f23de36366b7df673373 Mon Sep 17 00:00:00 2001
From: Mike Kruskal <mkruskal@google.com>
Date: Thu, 3 Nov 2022 00:10:52 -0700
Subject: [PATCH] Migrate remaining compiler code to from std::set to Abseil
 tables.

PiperOrigin-RevId: 485794075
---
 .../compiler/command_line_interface.cc        | 33 +++++++++----------
 .../compiler/command_line_interface.h         |  5 ++-
 src/google/protobuf/compiler/cpp/enum.h       |  1 -
 src/google/protobuf/compiler/cpp/field.cc     |  4 +--
 src/google/protobuf/compiler/cpp/file.cc      |  1 -
 src/google/protobuf/compiler/cpp/file.h       |  1 -
 src/google/protobuf/compiler/cpp/generator.cc |  3 +-
 src/google/protobuf/compiler/cpp/helpers.cc   |  1 -
 src/google/protobuf/compiler/cpp/message.cc   |  5 +--
 src/google/protobuf/compiler/cpp/message.h    |  1 -
 src/google/protobuf/compiler/cpp/options.h    |  5 +--
 .../protobuf/compiler/csharp/csharp_enum.cc   |  6 ++--
 src/google/protobuf/compiler/importer.h       |  1 -
 src/google/protobuf/compiler/java/BUILD.bazel | 15 +++++----
 src/google/protobuf/compiler/java/file.cc     | 20 +++++------
 src/google/protobuf/compiler/java/message.cc  | 20 +++++++----
 src/google/protobuf/compiler/java/message.h   |  3 +-
 .../protobuf/compiler/java/message_builder.cc | 18 ++++++----
 .../protobuf/compiler/java/message_builder.h  |  3 +-
 .../compiler/java/message_builder_lite.cc     |  6 ++--
 .../compiler/java/message_builder_lite.h      |  3 +-
 .../protobuf/compiler/java/message_lite.cc    | 16 +++++----
 .../protobuf/compiler/objectivec/BUILD.bazel  | 13 ++++----
 .../protobuf/compiler/objectivec/enum.cc      |  9 ++---
 .../protobuf/compiler/objectivec/enum.h       |  4 +--
 .../compiler/objectivec/enum_field.cc         |  4 +--
 .../protobuf/compiler/objectivec/enum_field.h |  4 +--
 .../protobuf/compiler/objectivec/extension.cc |  4 +--
 .../protobuf/compiler/objectivec/extension.h  |  4 ++-
 .../protobuf/compiler/objectivec/field.cc     |  6 ++--
 .../protobuf/compiler/objectivec/field.h      |  9 ++---
 .../protobuf/compiler/objectivec/file.cc      | 16 ++++-----
 .../protobuf/compiler/objectivec/map_field.cc |  7 ++--
 .../protobuf/compiler/objectivec/map_field.h  |  6 ++--
 .../protobuf/compiler/objectivec/message.cc   |  5 ++-
 .../protobuf/compiler/objectivec/message.h    |  7 ++--
 .../compiler/objectivec/message_field.cc      | 12 ++++---
 .../compiler/objectivec/message_field.h       | 10 +++---
 .../protobuf/compiler/objectivec/oneof.h      |  1 -
 src/google/protobuf/compiler/parser.cc        |  2 +-
 .../protobuf/compiler/php/php_generator.cc    | 33 ++++++++++---------
 src/google/protobuf/compiler/plugin.cc        |  2 --
 .../protobuf/compiler/python/pyi_generator.cc |  5 +--
 .../protobuf/compiler/python/pyi_generator.h  |  7 ++--
 src/google/protobuf/compiler/scc.h            |  3 +-
 45 files changed, 182 insertions(+), 162 deletions(-)

diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index c2a6ef48fe..6a44b04a47 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -34,7 +34,7 @@
 
 #include "google/protobuf/compiler/command_line_interface.h"
 
-#include "absl/container/btree_map.h"
+#include "absl/container/btree_set.h"
 #include "absl/container/flat_hash_map.h"
 
 #include "google/protobuf/stubs/platform_macros.h"
@@ -2212,7 +2212,7 @@ bool CommandLineInterface::GenerateDependencyManifestFile(
     DiskSourceTree* source_tree) {
   FileDescriptorSet file_set;
 
-  std::set<const FileDescriptor*> already_seen;
+  absl::flat_hash_set<const FileDescriptor*> already_seen;
   for (int i = 0; i < parsed_files.size(); i++) {
     GetTransitiveDependencies(parsed_files[i], false, false, &already_seen,
                               file_set.mutable_file());
@@ -2293,7 +2293,7 @@ bool CommandLineInterface::GeneratePluginOutput(
   }
 
 
-  std::set<const FileDescriptor*> already_seen;
+  absl::flat_hash_set<const FileDescriptor*> already_seen;
   for (int i = 0; i < parsed_files.size(); i++) {
     request.add_file_to_generate(parsed_files[i]->name());
     GetTransitiveDependencies(parsed_files[i],
@@ -2442,13 +2442,13 @@ bool CommandLineInterface::WriteDescriptorSet(
     const std::vector<const FileDescriptor*>& parsed_files) {
   FileDescriptorSet file_set;
 
-  std::set<const FileDescriptor*> already_seen;
+  absl::flat_hash_set<const FileDescriptor*> already_seen;
   if (!imports_in_descriptor_set_) {
     // Since we don't want to output transitive dependencies, but we do want
     // things to be in dependency order, add all dependencies that aren't in
     // parsed_files to already_seen.  This will short circuit the recursion
     // in GetTransitiveDependencies.
-    std::set<const FileDescriptor*> to_output;
+    absl::flat_hash_set<const FileDescriptor*> to_output;
     to_output.insert(parsed_files.begin(), parsed_files.end());
     for (int i = 0; i < parsed_files.size(); i++) {
       const FileDescriptor* file = parsed_files[i];
@@ -2506,7 +2506,7 @@ bool CommandLineInterface::WriteDescriptorSet(
 void CommandLineInterface::GetTransitiveDependencies(
     const FileDescriptor* file, bool include_json_name,
     bool include_source_code_info,
-    std::set<const FileDescriptor*>* already_seen,
+    absl::flat_hash_set<const FileDescriptor*>* already_seen,
     RepeatedPtrField<FileDescriptorProto>* output) {
   if (!already_seen->insert(file).second) {
     // Already saw this file.  Skip.
@@ -2579,9 +2579,9 @@ namespace {
 // order of the nested messages is also preserved.
 typedef std::pair<int, int> FieldRange;
 void GatherOccupiedFieldRanges(
-    const Descriptor* descriptor, std::set<FieldRange>* ranges,
+    const Descriptor* descriptor, absl::btree_set<FieldRange>* ranges,
     std::vector<const Descriptor*>* nested_messages) {
-  std::set<const Descriptor*> groups;
+  absl::flat_hash_set<const Descriptor*> groups;
   for (int i = 0; i < descriptor->field_count(); ++i) {
     const FieldDescriptor* fd = descriptor->field(i);
     ranges->insert(FieldRange(fd->number(), fd->number() + 1));
@@ -2613,27 +2613,26 @@ void GatherOccupiedFieldRanges(
 // Actually prints the formatted free field numbers for given message name and
 // occupied ranges.
 void FormatFreeFieldNumbers(const std::string& name,
-                            const std::set<FieldRange>& ranges) {
+                            const absl::btree_set<FieldRange>& ranges) {
   std::string output;
   absl::StrAppendFormat(&output, "%-35s free:", name.c_str());
   int next_free_number = 1;
-  for (std::set<FieldRange>::const_iterator i = ranges.begin();
-       i != ranges.end(); ++i) {
+  for (const auto& range : ranges) {
     // This happens when groups re-use parent field numbers, in which
     // case we skip the FieldRange entirely.
-    if (next_free_number >= i->second) continue;
+    if (next_free_number >= range.second) continue;
 
-    if (next_free_number < i->first) {
-      if (next_free_number + 1 == i->first) {
+    if (next_free_number < range.first) {
+      if (next_free_number + 1 == range.first) {
         // Singleton
         absl::StrAppendFormat(&output, " %d", next_free_number);
       } else {
         // Range
         absl::StrAppendFormat(&output, " %d-%d", next_free_number,
-                              i->first - 1);
+                              range.first - 1);
       }
     }
-    next_free_number = i->second;
+    next_free_number = range.second;
   }
   if (next_free_number <= FieldDescriptor::kMaxNumber) {
     absl::StrAppendFormat(&output, " %d-INF", next_free_number);
@@ -2644,7 +2643,7 @@ void FormatFreeFieldNumbers(const std::string& name,
 }  // namespace
 
 void CommandLineInterface::PrintFreeFieldNumbers(const Descriptor* descriptor) {
-  std::set<FieldRange> ranges;
+  absl::btree_set<FieldRange> ranges;
   std::vector<const Descriptor*> nested_messages;
   GatherOccupiedFieldRanges(descriptor, &ranges, &nested_messages);
 
diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h
index bec0455c74..4abe0d6160 100644
--- a/src/google/protobuf/compiler/command_line_interface.h
+++ b/src/google/protobuf/compiler/command_line_interface.h
@@ -41,7 +41,6 @@
 #include <cstdint>
 #include <functional>
 #include <memory>
-#include <set>
 #include <string>
 #include <utility>
 #include <vector>
@@ -322,7 +321,7 @@ class PROTOC_EXPORT CommandLineInterface {
   static void GetTransitiveDependencies(
       const FileDescriptor* file, bool include_json_name,
       bool include_source_code_info,
-      std::set<const FileDescriptor*>* already_seen,
+      absl::flat_hash_set<const FileDescriptor*>* already_seen,
       RepeatedPtrField<FileDescriptorProto>* output);
 
   // Implements the --print_free_field_numbers. This function prints free field
@@ -411,7 +410,7 @@ class PROTOC_EXPORT CommandLineInterface {
 
   // Names of proto files which are allowed to be imported. Used by build
   // systems to enforce depend-on-what-you-import.
-  std::set<std::string> direct_dependencies_;
+  absl::flat_hash_set<std::string> direct_dependencies_;
   bool direct_dependencies_explicitly_set_ = false;
 
   // If there's a violation of depend-on-what-you-import, this string will be
diff --git a/src/google/protobuf/compiler/cpp/enum.h b/src/google/protobuf/compiler/cpp/enum.h
index 49a262d40d..58a62f5533 100644
--- a/src/google/protobuf/compiler/cpp/enum.h
+++ b/src/google/protobuf/compiler/cpp/enum.h
@@ -35,7 +35,6 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
 #define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
 
-#include <set>
 #include <string>
 
 #include "google/protobuf/descriptor.h"
diff --git a/src/google/protobuf/compiler/cpp/field.cc b/src/google/protobuf/compiler/cpp/field.cc
index 50f86e1e7f..928f9aede8 100644
--- a/src/google/protobuf/compiler/cpp/field.cc
+++ b/src/google/protobuf/compiler/cpp/field.cc
@@ -68,8 +68,8 @@ void MaySetAnnotationVariable(
     absl::string_view prepared_template, int field_index,
     absl::string_view access_type,
     absl::flat_hash_map<absl::string_view, std::string>* variables) {
-  if (options.field_listener_options.forbidden_field_listener_events.count(
-          std::string(annotation_name)))
+  if (options.field_listener_options.forbidden_field_listener_events.contains(
+          annotation_name))
     return;
   (*variables)[absl::StrCat("annotate_", annotation_name)] = absl::Substitute(
       absl::StrCat(substitute_template_prefix, prepared_template, ");\n"),
diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc
index 759b43d12a..afba7ef906 100644
--- a/src/google/protobuf/compiler/cpp/file.cc
+++ b/src/google/protobuf/compiler/cpp/file.cc
@@ -36,7 +36,6 @@
 
 #include <iostream>
 #include <memory>
-#include <set>
 #include <string>
 #include <utility>
 #include <vector>
diff --git a/src/google/protobuf/compiler/cpp/file.h b/src/google/protobuf/compiler/cpp/file.h
index 3cb297e4a6..5f8ffcfc3e 100644
--- a/src/google/protobuf/compiler/cpp/file.h
+++ b/src/google/protobuf/compiler/cpp/file.h
@@ -38,7 +38,6 @@
 #include <algorithm>
 #include <functional>
 #include <memory>
-#include <set>
 #include <string>
 #include <vector>
 
diff --git a/src/google/protobuf/compiler/cpp/generator.cc b/src/google/protobuf/compiler/cpp/generator.cc
index 278354ca06..b45b16b379 100644
--- a/src/google/protobuf/compiler/cpp/generator.cc
+++ b/src/google/protobuf/compiler/cpp/generator.cc
@@ -42,6 +42,7 @@
 
 #include "absl/strings/match.h"
 #include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
 #include "google/protobuf/compiler/cpp/file.h"
 #include "google/protobuf/compiler/cpp/helpers.h"
 #include "google/protobuf/descriptor.pb.h"
@@ -168,7 +169,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
         }
         if (next_pos > pos)
           file_options.field_listener_options.forbidden_field_listener_events
-              .insert(value.substr(pos, next_pos - pos));
+              .emplace(value.substr(pos, next_pos - pos));
         pos = next_pos + 1;
       } while (pos < value.size());
     } else if (key == "unverified_lazy_message_sets") {
diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc
index eeb23fc66c..569bc1dc31 100644
--- a/src/google/protobuf/compiler/cpp/helpers.cc
+++ b/src/google/protobuf/compiler/cpp/helpers.cc
@@ -40,7 +40,6 @@
 #include <limits>
 #include <memory>
 #include <queue>
-#include <set>
 #include <string>
 #include <utility>
 #include <vector>
diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc
index bf54fb4289..d8316905ed 100644
--- a/src/google/protobuf/compiler/cpp/message.cc
+++ b/src/google/protobuf/compiler/cpp/message.cc
@@ -51,6 +51,7 @@
 #include "google/protobuf/map_entry_lite.h"
 #include "google/protobuf/wire_format.h"
 #include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
 #include "absl/strings/ascii.h"
 #include "absl/strings/escaping.h"
 #include "absl/strings/str_cat.h"
@@ -514,8 +515,8 @@ void AnnotationVar(const Descriptor* desc, const Options& options,
                    absl::flat_hash_map<absl::string_view, std::string>& vars,
                    absl::string_view name, absl::string_view val) {
   if (!HasTracker(desc, options) ||
-      options.field_listener_options.forbidden_field_listener_events.count(
-          std::string(absl::StripPrefix(name, "annotate_"))) != 0) {
+      options.field_listener_options.forbidden_field_listener_events.contains(
+          absl::StripPrefix(name, "annotate_"))) {
     val = "";
   }
 
diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h
index 6afa856913..7e22304152 100644
--- a/src/google/protobuf/compiler/cpp/message.h
+++ b/src/google/protobuf/compiler/cpp/message.h
@@ -38,7 +38,6 @@
 #include <cstdint>
 #include <limits>
 #include <memory>
-#include <set>
 #include <string>
 #include <utility>
 #include <vector>
diff --git a/src/google/protobuf/compiler/cpp/options.h b/src/google/protobuf/compiler/cpp/options.h
index 7aab669131..affaca38c1 100644
--- a/src/google/protobuf/compiler/cpp/options.h
+++ b/src/google/protobuf/compiler/cpp/options.h
@@ -33,9 +33,10 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
 #define GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
 
-#include <set>
 #include <string>
 
+#include "absl/container/flat_hash_set.h"
+
 namespace google {
 namespace protobuf {
 namespace compiler {
@@ -53,7 +54,7 @@ enum class EnforceOptimizeMode {
 
 struct FieldListenerOptions {
   bool inject_field_listener_events = false;
-  std::set<std::string> forbidden_field_listener_events;
+  absl::flat_hash_set<std::string> forbidden_field_listener_events;
 };
 
 // Generator options (see generator.cc for a description of each):
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.cc b/src/google/protobuf/compiler/csharp/csharp_enum.cc
index 846da9b6c9..eaeef31053 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_enum.cc
@@ -31,8 +31,10 @@
 #include "google/protobuf/compiler/csharp/csharp_enum.h"
 
 #include <sstream>
+#include <string>
 
 #include "google/protobuf/compiler/code_generator.h"
+#include "absl/container/flat_hash_set.h"
 #include "absl/strings/str_cat.h"
 #include "google/protobuf/compiler/csharp/csharp_doc_comment.h"
 #include "google/protobuf/compiler/csharp/csharp_helpers.h"
@@ -63,8 +65,8 @@ void EnumGenerator::Generate(io::Printer* printer) {
                  "access_level", class_access_level(),
                  "name", descriptor_->name());
   printer->Indent();
-  std::set<std::string> used_names;
-  std::set<int> used_number;
+  absl::flat_hash_set<std::string> used_names;
+  absl::flat_hash_set<int> used_number;
   for (int i = 0; i < descriptor_->value_count(); i++) {
       WriteEnumValueDocComment(printer, descriptor_->value(i));
       if (descriptor_->value(i)->options().deprecated()) {
diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h
index 3b8dd51d58..3912f2dcb2 100644
--- a/src/google/protobuf/compiler/importer.h
+++ b/src/google/protobuf/compiler/importer.h
@@ -37,7 +37,6 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
 #define GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
 
-#include <set>
 #include <string>
 #include <utility>
 #include <vector>
diff --git a/src/google/protobuf/compiler/java/BUILD.bazel b/src/google/protobuf/compiler/java/BUILD.bazel
index 3ccc73da81..b93a423b6c 100644
--- a/src/google/protobuf/compiler/java/BUILD.bazel
+++ b/src/google/protobuf/compiler/java/BUILD.bazel
@@ -20,23 +20,23 @@ cc_library(
 
 cc_library(
     name = "names_internal",
+    srcs = [
+        "helpers.cc",
+        "name_resolver.cc",
+        "names.cc",
+    ],
     hdrs = [
         "helpers.h",
         "name_resolver.h",
         "names.h",
         "options.h",
     ],
-    srcs = [
-        "helpers.cc",
-        "name_resolver.cc",
-        "names.cc",
-    ],
     copts = COPTS,
     include_prefix = "google/protobuf/compiler/java",
     visibility = ["//pkg:__pkg__"],
     deps = [
-        "//src/google/protobuf/compiler:code_generator",
         "//src/google/protobuf:protobuf_nowkt",
+        "//src/google/protobuf/compiler:code_generator",
         "@com_google_absl//absl/container:flat_hash_set",
     ],
 )
@@ -110,10 +110,11 @@ cc_library(
         "//src/google/protobuf/compiler:__pkg__",
     ],
     deps = [
-        ":names_internal",
         ":names",
+        ":names_internal",
         "//src/google/protobuf:protobuf_nowkt",
         "//src/google/protobuf/compiler:code_generator",
+        "@com_google_absl//absl/container:btree",
         "@com_google_absl//absl/container:flat_hash_set",
         "@com_google_absl//absl/strings",
     ],
diff --git a/src/google/protobuf/compiler/java/file.cc b/src/google/protobuf/compiler/java/file.cc
index 4776277db2..eb29de16cd 100644
--- a/src/google/protobuf/compiler/java/file.cc
+++ b/src/google/protobuf/compiler/java/file.cc
@@ -35,12 +35,13 @@
 #include "google/protobuf/compiler/java/file.h"
 
 #include <memory>
-#include <set>
+#include <vector>
 
 #include "google/protobuf/compiler/code_generator.h"
 #include "google/protobuf/io/printer.h"
 #include "google/protobuf/io/zero_copy_stream.h"
 #include "google/protobuf/dynamic_message.h"
+#include "absl/container/btree_set.h"
 #include "absl/strings/str_cat.h"
 #include "google/protobuf/compiler/java/context.h"
 #include "google/protobuf/compiler/java/enum.h"
@@ -76,8 +77,8 @@ struct FieldDescriptorCompare {
   }
 };
 
-typedef std::set<const FieldDescriptor*, FieldDescriptorCompare>
-    FieldDescriptorSet;
+using FieldDescriptorSet =
+    absl::btree_set<const FieldDescriptor*, FieldDescriptorCompare>;
 
 // Recursively searches the given message to collect extensions.
 // Returns true if all the extensions can be recognized. The extensions will be
@@ -456,16 +457,16 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
   FieldDescriptorSet extensions;
   CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
 
-  if (extensions.size() > 0) {
+  if (!extensions.empty()) {
     // Must construct an ExtensionRegistry containing all existing extensions
     // and use it to parse the descriptor data again to recognize extensions.
     printer->Print(
         "com.google.protobuf.ExtensionRegistry registry =\n"
         "    com.google.protobuf.ExtensionRegistry.newInstance();\n");
     FieldDescriptorSet::iterator it;
-    for (it = extensions.begin(); it != extensions.end(); it++) {
+    for (const FieldDescriptor* field : extensions) {
       std::unique_ptr<ExtensionGenerator> generator(
-          generator_factory_->NewExtensionGenerator(*it));
+          generator_factory_->NewExtensionGenerator(field));
       bytecode_estimate += generator->GenerateRegistrationCode(printer);
       MaybeRestartJavaMethod(
           printer, &bytecode_estimate, &method_num,
@@ -525,7 +526,7 @@ void FileGenerator::GenerateDescriptorInitializationCodeForMutable(
   FieldDescriptorSet extensions;
   CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
 
-  if (extensions.size() > 0) {
+  if (!extensions.empty()) {
     // Try to load immutable messages' outer class. Its initialization code
     // will take care of interpreting custom options.
     printer->Print(
@@ -546,9 +547,8 @@ void FileGenerator::GenerateDescriptorInitializationCodeForMutable(
         "com.google.protobuf.ExtensionRegistry registry =\n"
         "    com.google.protobuf.ExtensionRegistry.newInstance();\n"
         "com.google.protobuf.MessageLite defaultExtensionInstance = null;\n");
-    FieldDescriptorSet::iterator it;
-    for (it = extensions.begin(); it != extensions.end(); it++) {
-      const FieldDescriptor* field = *it;
+
+    for (const FieldDescriptor* field : extensions) {
       std::string scope;
       if (field->extension_scope() != NULL) {
         scope = name_resolver_->GetMutableClassName(field->extension_scope()) +
diff --git a/src/google/protobuf/compiler/java/message.cc b/src/google/protobuf/compiler/java/message.cc
index 9ff8b87aa0..86436aa80a 100644
--- a/src/google/protobuf/compiler/java/message.cc
+++ b/src/google/protobuf/compiler/java/message.cc
@@ -84,7 +84,8 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor)
     : descriptor_(descriptor) {
   for (int i = 0; i < descriptor_->field_count(); i++) {
     if (IsRealOneof(descriptor_->field(i))) {
-      oneofs_.insert(descriptor_->field(i)->containing_oneof());
+      const OneofDescriptor* oneof = descriptor_->field(i)->containing_oneof();
+      GOOGLE_CHECK(oneofs_.emplace(oneof->index(), oneof).first->second == oneof);
     }
   }
 }
@@ -294,13 +295,14 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
     field_generators_.get(descriptor_->field(i))
         .GenerateInterfaceMembers(printer);
   }
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
     printer->Print(
         "\n"
         "$classname$.$oneof_capitalized_name$Case "
         "get$oneof_capitalized_name$Case();\n",
         "oneof_capitalized_name",
-        context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "classname",
+        context_->GetOneofGeneratorInfo(kv.second)->capitalized_name,
+        "classname",
         context_->GetNameResolver()->GetImmutableClassName(descriptor_));
   }
   printer->Outdent();
@@ -426,7 +428,8 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
 
   // oneof
   absl::flat_hash_map<absl::string_view, std::string> vars;
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
+    const OneofDescriptor* oneof = kv.second;
     vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
     vars["oneof_capitalized_name"] =
         context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
@@ -1033,7 +1036,8 @@ void ImmutableMessageGenerator::GenerateEqualsAndHashCode(
   }
 
   // Compare oneofs.
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
+    const OneofDescriptor* oneof = kv.second;
     printer->Print(
         "if (!get$oneof_capitalized_name$Case().equals("
         "other.get$oneof_capitalized_name$Case())) return false;\n",
@@ -1113,7 +1117,8 @@ void ImmutableMessageGenerator::GenerateEqualsAndHashCode(
   }
 
   // hashCode oneofs.
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
+    const OneofDescriptor* oneof = kv.second;
     printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name",
                    context_->GetOneofGeneratorInfo(oneof)->name);
     printer->Indent();
@@ -1279,7 +1284,8 @@ void ImmutableMessageGenerator::GenerateKotlinDsl(io::Printer* printer) const {
         .GenerateKotlinDslMembers(printer);
   }
 
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
+    const OneofDescriptor* oneof = kv.second;
     printer->Print(
         "public val $oneof_name$Case: $message$.$oneof_capitalized_name$Case\n"
         "  @JvmName(\"get$oneof_capitalized_name$Case\")\n"
diff --git a/src/google/protobuf/compiler/java/message.h b/src/google/protobuf/compiler/java/message.h
index 683bb8d30f..a122c83433 100644
--- a/src/google/protobuf/compiler/java/message.h
+++ b/src/google/protobuf/compiler/java/message.h
@@ -37,6 +37,7 @@
 
 #include <string>
 
+#include "absl/container/btree_map.h"
 #include "google/protobuf/compiler/java/field.h"
 
 namespace google {
@@ -93,7 +94,7 @@ class MessageGenerator {
 
  protected:
   const Descriptor* descriptor_;
-  std::set<const OneofDescriptor*> oneofs_;
+  absl::btree_map<int, const OneofDescriptor*> oneofs_;
 };
 
 class ImmutableMessageGenerator : public MessageGenerator {
diff --git a/src/google/protobuf/compiler/java/message_builder.cc b/src/google/protobuf/compiler/java/message_builder.cc
index eb85dd4f76..4d63c88203 100644
--- a/src/google/protobuf/compiler/java/message_builder.cc
+++ b/src/google/protobuf/compiler/java/message_builder.cc
@@ -85,7 +85,8 @@ MessageBuilderGenerator::MessageBuilderGenerator(const Descriptor* descriptor,
          "generate lite messages.";
   for (int i = 0; i < descriptor_->field_count(); i++) {
     if (IsRealOneof(descriptor_->field(i))) {
-      oneofs_.insert(descriptor_->field(i)->containing_oneof());
+      const OneofDescriptor* oneof = descriptor_->field(i)->containing_oneof();
+      GOOGLE_CHECK(oneofs_.emplace(oneof->index(), oneof).first->second == oneof);
     }
   }
 }
@@ -127,7 +128,8 @@ void MessageBuilderGenerator::Generate(io::Printer* printer) {
 
   // oneof
   absl::flat_hash_map<absl::string_view, std::string> vars;
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
+    const OneofDescriptor* oneof = kv.second;
     vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
     vars["oneof_capitalized_name"] =
         context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
@@ -364,11 +366,11 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods(
         .GenerateBuilderClearCode(printer);
   }
 
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
     printer->Print(
         "$oneof_name$Case_ = 0;\n"
         "$oneof_name$_ = null;\n",
-        "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
+        "oneof_name", context_->GetOneofGeneratorInfo(kv.second)->name);
   }
 
   printer->Outdent();
@@ -452,9 +454,10 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods(
                    "bit_field_name", GetBitFieldName(i));
   }
 
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
     printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n",
-                   "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
+                   "oneof_name",
+                   context_->GetOneofGeneratorInfo(kv.second)->name);
   }
 
   printer->Outdent();
@@ -572,7 +575,8 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods(
     }
 
     // Merge oneof fields.
-    for (auto oneof : oneofs_) {
+    for (auto& kv : oneofs_) {
+      const OneofDescriptor* oneof = kv.second;
       printer->Print("switch (other.get$oneof_capitalized_name$Case()) {\n",
                      "oneof_capitalized_name",
                      context_->GetOneofGeneratorInfo(oneof)->capitalized_name);
diff --git a/src/google/protobuf/compiler/java/message_builder.h b/src/google/protobuf/compiler/java/message_builder.h
index ba0e26ba11..ec9b56fcf5 100644
--- a/src/google/protobuf/compiler/java/message_builder.h
+++ b/src/google/protobuf/compiler/java/message_builder.h
@@ -37,6 +37,7 @@
 
 #include <string>
 
+#include "absl/container/btree_map.h"
 #include "google/protobuf/compiler/java/field.h"
 
 namespace google {
@@ -83,7 +84,7 @@ class MessageBuilderGenerator {
   Context* context_;
   ClassNameResolver* name_resolver_;
   FieldGeneratorMap<ImmutableFieldGenerator> field_generators_;
-  std::set<const OneofDescriptor*> oneofs_;
+  absl::btree_map<int, const OneofDescriptor*> oneofs_;
 };
 
 }  // namespace java
diff --git a/src/google/protobuf/compiler/java/message_builder_lite.cc b/src/google/protobuf/compiler/java/message_builder_lite.cc
index 5f047344e2..945317743a 100644
--- a/src/google/protobuf/compiler/java/message_builder_lite.cc
+++ b/src/google/protobuf/compiler/java/message_builder_lite.cc
@@ -73,7 +73,8 @@ MessageBuilderLiteGenerator::MessageBuilderLiteGenerator(
          "generate non-lite messages.";
   for (int i = 0; i < descriptor_->field_count(); i++) {
     if (IsRealOneof(descriptor_->field(i))) {
-      oneofs_.insert(descriptor_->field(i)->containing_oneof());
+      const OneofDescriptor* oneof = descriptor_->field(i)->containing_oneof();
+      GOOGLE_CHECK(oneofs_.emplace(oneof->index(), oneof).first->second == oneof);
     }
   }
 }
@@ -103,7 +104,8 @@ void MessageBuilderLiteGenerator::Generate(io::Printer* printer) {
   GenerateCommonBuilderMethods(printer);
 
   // oneof
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
+    const OneofDescriptor* oneof = kv.second;
     vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
     vars["oneof_capitalized_name"] =
         context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
diff --git a/src/google/protobuf/compiler/java/message_builder_lite.h b/src/google/protobuf/compiler/java/message_builder_lite.h
index 1bcc5c6a2c..a0d0e15210 100644
--- a/src/google/protobuf/compiler/java/message_builder_lite.h
+++ b/src/google/protobuf/compiler/java/message_builder_lite.h
@@ -37,6 +37,7 @@
 
 #include <string>
 
+#include "absl/container/btree_map.h"
 #include "google/protobuf/compiler/java/field.h"
 
 namespace google {
@@ -76,7 +77,7 @@ class MessageBuilderLiteGenerator {
   Context* context_;
   ClassNameResolver* name_resolver_;
   FieldGeneratorMap<ImmutableFieldLiteGenerator> field_generators_;
-  std::set<const OneofDescriptor*> oneofs_;
+  absl::btree_map<int, const OneofDescriptor*> oneofs_;
 };
 
 }  // namespace java
diff --git a/src/google/protobuf/compiler/java/message_lite.cc b/src/google/protobuf/compiler/java/message_lite.cc
index 64195ecda6..8c35d978b6 100644
--- a/src/google/protobuf/compiler/java/message_lite.cc
+++ b/src/google/protobuf/compiler/java/message_lite.cc
@@ -81,7 +81,8 @@ ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator(
          "generate non-lite messages.";
   for (int i = 0; i < descriptor_->field_count(); i++) {
     if (IsRealOneof(descriptor_->field(i))) {
-      oneofs_.insert(descriptor_->field(i)->containing_oneof());
+      const OneofDescriptor* oneof = descriptor_->field(i)->containing_oneof();
+      GOOGLE_CHECK(oneofs_.emplace(oneof->index(), oneof).first->second == oneof);
     }
   }
 }
@@ -152,7 +153,8 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
     field_generators_.get(descriptor_->field(i))
         .GenerateInterfaceMembers(printer);
   }
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
+    const OneofDescriptor* oneof = kv.second;
     variables["oneof_capitalized_name"] =
         context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
     variables["classname"] =
@@ -245,7 +247,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
   // oneof
   absl::flat_hash_map<absl::string_view, std::string> vars = {{"{", ""},
                                                               {"}", ""}};
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
+    const OneofDescriptor* oneof = kv.second;
     vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
     vars["oneof_capitalized_name"] =
         context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
@@ -522,11 +525,11 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo(
 
     // Record the number of oneofs.
     WriteIntToUtf16CharSequence(oneofs_.size(), &chars);
-    for (auto oneof : oneofs_) {
+    for (auto& kv : oneofs_) {
       printer->Print(
           "\"$oneof_name$_\",\n"
           "\"$oneof_name$Case_\",\n",
-          "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
+          "oneof_name", context_->GetOneofGeneratorInfo(kv.second)->name);
     }
 
     // Integers for bit fields.
@@ -784,7 +787,8 @@ void ImmutableMessageLiteGenerator::GenerateKotlinDsl(
         .GenerateKotlinDslMembers(printer);
   }
 
-  for (auto oneof : oneofs_) {
+  for (auto& kv : oneofs_) {
+    const OneofDescriptor* oneof = kv.second;
     printer->Print(
         "public val $oneof_name$Case: $message$.$oneof_capitalized_name$Case\n"
         "  @JvmName(\"get$oneof_capitalized_name$Case\")\n"
diff --git a/src/google/protobuf/compiler/objectivec/BUILD.bazel b/src/google/protobuf/compiler/objectivec/BUILD.bazel
index 3e634caafc..e0de9eb461 100644
--- a/src/google/protobuf/compiler/objectivec/BUILD.bazel
+++ b/src/google/protobuf/compiler/objectivec/BUILD.bazel
@@ -19,34 +19,34 @@ cc_library(
 
 cc_library(
     name = "names_internal",
+    srcs = [
+        "names.cc",
+    ],
     hdrs = [
         "names.h",
         "nsobject_methods.h",
     ],
-    srcs = [
-        "names.cc",
-    ],
     copts = COPTS,
     include_prefix = "google/protobuf/compiler/objectivec",
     visibility = ["//pkg:__pkg__"],
     deps = [
         ":line_consumer",
-        "//src/google/protobuf/compiler:code_generator",
         "//src/google/protobuf:protobuf_nowkt",
+        "//src/google/protobuf/compiler:code_generator",
         "@com_google_absl//absl/container:flat_hash_set",
     ],
 )
 
 cc_library(
     name = "line_consumer",
-    hdrs = ["line_consumer.h"],
     srcs = ["line_consumer.cc"],
+    hdrs = ["line_consumer.h"],
     copts = COPTS,
     include_prefix = "google/protobuf/compiler/objectivec",
     visibility = ["//pkg:__pkg__"],
     deps = [
-        "//src/google/protobuf/compiler:code_generator",
         "//src/google/protobuf:protobuf_nowkt",
+        "//src/google/protobuf/compiler:code_generator",
     ],
 )
 
@@ -96,6 +96,7 @@ cc_library(
         ":names",
         "//src/google/protobuf:protobuf_nowkt",
         "//src/google/protobuf/compiler:code_generator",
+        "@com_google_absl//absl/container:btree",
         "@com_google_absl//absl/strings",
     ],
 )
diff --git a/src/google/protobuf/compiler/objectivec/enum.cc b/src/google/protobuf/compiler/objectivec/enum.cc
index 286739fa67..3235daf453 100644
--- a/src/google/protobuf/compiler/objectivec/enum.cc
+++ b/src/google/protobuf/compiler/objectivec/enum.cc
@@ -32,9 +32,9 @@
 
 #include <algorithm>
 #include <limits>
-#include <set>
 #include <string>
 
+#include "absl/container/flat_hash_set.h"
 #include "absl/strings/escaping.h"
 #include "absl/strings/str_cat.h"
 #include "google/protobuf/compiler/objectivec/helpers.h"
@@ -69,7 +69,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
   // compile error is just fine.
   // The values are still tracked to support the reflection apis and
   // TextFormat handing since they are different there.
-  std::set<std::string> value_names;
+  absl::flat_hash_set<std::string> value_names;
 
   for (int i = 0; i < descriptor_->value_count(); i++) {
     const EnumValueDescriptor* value = descriptor_->value(i);
@@ -80,11 +80,8 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
       base_values_.push_back(value);
       value_names.insert(EnumValueName(value));
     } else {
-      std::string value_name(EnumValueName(value));
-      if (value_names.find(value_name) != value_names.end()) {
+      if (!value_names.insert(EnumValueName(value)).second) {
         alias_values_to_skip_.insert(value);
-      } else {
-        value_names.insert(value_name);
       }
     }
     all_values_.push_back(value);
diff --git a/src/google/protobuf/compiler/objectivec/enum.h b/src/google/protobuf/compiler/objectivec/enum.h
index c990a85146..93b80ca12f 100644
--- a/src/google/protobuf/compiler/objectivec/enum.h
+++ b/src/google/protobuf/compiler/objectivec/enum.h
@@ -31,10 +31,10 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
 #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
 
-#include <set>
 #include <string>
 #include <vector>
 
+#include "absl/container/flat_hash_set.h"
 #include "google/protobuf/descriptor.h"
 #include "google/protobuf/io/printer.h"
 
@@ -60,7 +60,7 @@ class EnumGenerator {
   const EnumDescriptor* descriptor_;
   std::vector<const EnumValueDescriptor*> base_values_;
   std::vector<const EnumValueDescriptor*> all_values_;
-  std::set<const EnumValueDescriptor*> alias_values_to_skip_;
+  absl::flat_hash_set<const EnumValueDescriptor*> alias_values_to_skip_;
   const std::string name_;
 };
 
diff --git a/src/google/protobuf/compiler/objectivec/enum_field.cc b/src/google/protobuf/compiler/objectivec/enum_field.cc
index 8372bce7bf..e5e881a643 100644
--- a/src/google/protobuf/compiler/objectivec/enum_field.cc
+++ b/src/google/protobuf/compiler/objectivec/enum_field.cc
@@ -30,7 +30,6 @@
 
 #include "google/protobuf/compiler/objectivec/enum_field.h"
 
-#include <set>
 #include <string>
 
 #include "absl/container/flat_hash_map.h"
@@ -123,7 +122,8 @@ void EnumFieldGenerator::GenerateCFunctionImplementations(
 }
 
 void EnumFieldGenerator::DetermineForwardDeclarations(
-    std::set<std::string>* fwd_decls, bool include_external_types) const {
+    absl::btree_set<std::string>* fwd_decls,
+    bool include_external_types) const {
   SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls,
                                                      include_external_types);
   // If it is an enum defined in a different file (and not a WKT), then we'll
diff --git a/src/google/protobuf/compiler/objectivec/enum_field.h b/src/google/protobuf/compiler/objectivec/enum_field.h
index 9108162250..96dd2800f4 100644
--- a/src/google/protobuf/compiler/objectivec/enum_field.h
+++ b/src/google/protobuf/compiler/objectivec/enum_field.h
@@ -31,9 +31,9 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
 #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
 
-#include <set>
 #include <string>
 
+#include "absl/container/btree_set.h"
 #include "google/protobuf/compiler/objectivec/field.h"
 
 namespace google {
@@ -50,7 +50,7 @@ class EnumFieldGenerator : public SingleFieldGenerator {
  public:
   void GenerateCFunctionDeclarations(io::Printer* printer) const override;
   void GenerateCFunctionImplementations(io::Printer* printer) const override;
-  void DetermineForwardDeclarations(std::set<std::string>* fwd_decls,
+  void DetermineForwardDeclarations(absl::btree_set<std::string>* fwd_decls,
                                     bool include_external_types) const override;
 
  protected:
diff --git a/src/google/protobuf/compiler/objectivec/extension.cc b/src/google/protobuf/compiler/objectivec/extension.cc
index d8c179b763..c16a1e55e0 100644
--- a/src/google/protobuf/compiler/objectivec/extension.cc
+++ b/src/google/protobuf/compiler/objectivec/extension.cc
@@ -32,10 +32,10 @@
 
 #include <iostream>
 #include <ostream>
-#include <set>
 #include <string>
 #include <vector>
 
+#include "absl/container/btree_set.h"
 #include "absl/container/flat_hash_map.h"
 #include "absl/strings/str_cat.h"
 #include "google/protobuf/compiler/objectivec/helpers.h"
@@ -146,7 +146,7 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
 }
 
 void ExtensionGenerator::DetermineObjectiveCClassDefinitions(
-    std::set<std::string>* fwd_decls) {
+    absl::btree_set<std::string>* fwd_decls) {
   std::string extended_type = ClassName(descriptor_->containing_type());
   fwd_decls->insert(ObjCClassDeclaration(extended_type));
   ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
diff --git a/src/google/protobuf/compiler/objectivec/extension.h b/src/google/protobuf/compiler/objectivec/extension.h
index 34f5921a63..9975c12ec1 100644
--- a/src/google/protobuf/compiler/objectivec/extension.h
+++ b/src/google/protobuf/compiler/objectivec/extension.h
@@ -33,6 +33,7 @@
 
 #include <string>
 
+#include "absl/container/btree_set.h"
 #include "google/protobuf/descriptor.h"
 #include "google/protobuf/io/printer.h"
 
@@ -53,7 +54,8 @@ class ExtensionGenerator {
   void GenerateMembersHeader(io::Printer* printer);
   void GenerateStaticVariablesInitialization(io::Printer* printer);
   void GenerateRegistrationSource(io::Printer* printer);
-  void DetermineObjectiveCClassDefinitions(std::set<std::string>* fwd_decls);
+  void DetermineObjectiveCClassDefinitions(
+      absl::btree_set<std::string>* fwd_decls);
 
  private:
   std::string method_name_;
diff --git a/src/google/protobuf/compiler/objectivec/field.cc b/src/google/protobuf/compiler/objectivec/field.cc
index d02feb1766..24c25c5b7b 100644
--- a/src/google/protobuf/compiler/objectivec/field.cc
+++ b/src/google/protobuf/compiler/objectivec/field.cc
@@ -32,7 +32,6 @@
 
 #include <iostream>
 #include <ostream>
-#include <set>
 #include <string>
 #include <vector>
 
@@ -231,12 +230,13 @@ void FieldGenerator::GenerateCFunctionImplementations(
 }
 
 void FieldGenerator::DetermineForwardDeclarations(
-    std::set<std::string>* fwd_decls, bool include_external_types) const {
+    absl::btree_set<std::string>* fwd_decls,
+    bool include_external_types) const {
   // Nothing
 }
 
 void FieldGenerator::DetermineObjectiveCClassDefinitions(
-    std::set<std::string>* fwd_decls) const {
+    absl::btree_set<std::string>* fwd_decls) const {
   // Nothing
 }
 
diff --git a/src/google/protobuf/compiler/objectivec/field.h b/src/google/protobuf/compiler/objectivec/field.h
index f52e7c87f7..8cc1d5ab74 100644
--- a/src/google/protobuf/compiler/objectivec/field.h
+++ b/src/google/protobuf/compiler/objectivec/field.h
@@ -32,10 +32,10 @@
 #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
 
 #include <memory>
-#include <set>
 #include <string>
 #include <vector>
 
+#include "absl/container/btree_set.h"
 #include "absl/container/flat_hash_map.h"
 #include "absl/strings/match.h"
 #include "google/protobuf/descriptor.h"
@@ -68,10 +68,11 @@ class FieldGenerator {
   virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
 
   // Exposed for subclasses, should always call it on the parent class also.
-  virtual void DetermineForwardDeclarations(std::set<std::string>* fwd_decls,
-                                            bool include_external_types) const;
+  virtual void DetermineForwardDeclarations(
+      absl::btree_set<std::string>* fwd_decls,
+      bool include_external_types) const;
   virtual void DetermineObjectiveCClassDefinitions(
-      std::set<std::string>* fwd_decls) const;
+      absl::btree_set<std::string>* fwd_decls) const;
 
   // Used during generation, not intended to be extended by subclasses.
   void GenerateFieldDescription(io::Printer* printer,
diff --git a/src/google/protobuf/compiler/objectivec/file.cc b/src/google/protobuf/compiler/objectivec/file.cc
index d9643252da..02c029aa3b 100644
--- a/src/google/protobuf/compiler/objectivec/file.cc
+++ b/src/google/protobuf/compiler/objectivec/file.cc
@@ -33,12 +33,12 @@
 #include <algorithm>
 #include <iostream>
 #include <iterator>
-#include <set>
 #include <sstream>
 #include <string>
 #include <vector>
 
 #include "google/protobuf/compiler/code_generator.h"
+#include "absl/container/btree_set.h"
 #include "absl/container/flat_hash_map.h"
 #include "absl/container/flat_hash_set.h"
 #include "absl/strings/str_cat.h"
@@ -323,15 +323,14 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
       "\n");
   // clang-format on
 
-  std::set<std::string> fwd_decls;
+  absl::btree_set<std::string> fwd_decls;
   for (const auto& generator : message_generators_) {
     generator->DetermineForwardDeclarations(
         &fwd_decls,
         /* include_external_types = */ headers_use_forward_declarations);
   }
-  for (std::set<std::string>::const_iterator i(fwd_decls.begin());
-       i != fwd_decls.end(); ++i) {
-    printer->Print("$value$;\n", "value", *i);
+  for (const auto& fwd_decl : fwd_decls) {
+    printer->Print("$value$;\n", "value", fwd_decl);
   }
   if (fwd_decls.begin() != fwd_decls.end()) {
     printer->Print("\n");
@@ -441,14 +440,13 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
     if (headers_use_forward_declarations) {
       // #import the headers for anything that a plain dependency of this proto
       // file (that means they were just an include, not a "public" include).
-      std::set<std::string> public_import_names;
+      absl::flat_hash_set<std::string> public_import_names;
       for (int i = 0; i < file_->public_dependency_count(); i++) {
         public_import_names.insert(file_->public_dependency(i)->name());
       }
       for (int i = 0; i < file_->dependency_count(); i++) {
         const FileDescriptor* dep = file_->dependency(i);
-        bool public_import = (public_import_names.count(dep->name()) != 0);
-        if (!public_import) {
+        if (!public_import_names.contains(dep->name())) {
           import_writer.AddFile(dep, header_extension);
         }
       }
@@ -477,7 +475,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
     }
   }
 
-  std::set<std::string> fwd_decls;
+  absl::btree_set<std::string> fwd_decls;
   for (const auto& generator : message_generators_) {
     generator->DetermineObjectiveCClassDefinitions(&fwd_decls);
   }
diff --git a/src/google/protobuf/compiler/objectivec/map_field.cc b/src/google/protobuf/compiler/objectivec/map_field.cc
index f0f40d9a76..2b8df1b709 100644
--- a/src/google/protobuf/compiler/objectivec/map_field.cc
+++ b/src/google/protobuf/compiler/objectivec/map_field.cc
@@ -30,10 +30,10 @@
 
 #include "google/protobuf/compiler/objectivec/map_field.h"
 
-#include <set>
 #include <string>
 #include <vector>
 
+#include "absl/container/btree_set.h"
 #include "absl/strings/match.h"
 #include "google/protobuf/compiler/objectivec/helpers.h"
 #include "google/protobuf/compiler/objectivec/names.h"
@@ -160,7 +160,8 @@ void MapFieldGenerator::FinishInitialization() {
 }
 
 void MapFieldGenerator::DetermineForwardDeclarations(
-    std::set<std::string>* fwd_decls, bool include_external_types) const {
+    absl::btree_set<std::string>* fwd_decls,
+    bool include_external_types) const {
   RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls,
                                                        include_external_types);
   const FieldDescriptor* value_descriptor =
@@ -188,7 +189,7 @@ void MapFieldGenerator::DetermineForwardDeclarations(
 }
 
 void MapFieldGenerator::DetermineObjectiveCClassDefinitions(
-    std::set<std::string>* fwd_decls) const {
+    absl::btree_set<std::string>* fwd_decls) const {
   // Class name is already in "storage_type".
   const FieldDescriptor* value_descriptor =
       descriptor_->message_type()->map_value();
diff --git a/src/google/protobuf/compiler/objectivec/map_field.h b/src/google/protobuf/compiler/objectivec/map_field.h
index cb4c212cae..ee11354a12 100644
--- a/src/google/protobuf/compiler/objectivec/map_field.h
+++ b/src/google/protobuf/compiler/objectivec/map_field.h
@@ -32,9 +32,9 @@
 #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
 
 #include <memory>
-#include <set>
 #include <string>
 
+#include "absl/container/btree_set.h"
 #include "google/protobuf/compiler/objectivec/field.h"
 
 namespace google {
@@ -56,8 +56,8 @@ class MapFieldGenerator : public RepeatedFieldGenerator {
   ~MapFieldGenerator() override = default;
 
   void DetermineObjectiveCClassDefinitions(
-      std::set<std::string>* fwd_decls) const override;
-  void DetermineForwardDeclarations(std::set<std::string>* fwd_decls,
+      absl::btree_set<std::string>* fwd_decls) const override;
+  void DetermineForwardDeclarations(absl::btree_set<std::string>* fwd_decls,
                                     bool include_external_types) const override;
 
  private:
diff --git a/src/google/protobuf/compiler/objectivec/message.cc b/src/google/protobuf/compiler/objectivec/message.cc
index 91fd9ed0f2..84606dc75e 100644
--- a/src/google/protobuf/compiler/objectivec/message.cc
+++ b/src/google/protobuf/compiler/objectivec/message.cc
@@ -33,7 +33,6 @@
 #include <algorithm>
 #include <iostream>
 #include <memory>
-#include <set>
 #include <sstream>
 #include <string>
 #include <vector>
@@ -223,7 +222,7 @@ void MessageGenerator::GenerateStaticVariablesInitialization(
 }
 
 void MessageGenerator::DetermineForwardDeclarations(
-    std::set<std::string>* fwd_decls, bool include_external_types) {
+    absl::btree_set<std::string>* fwd_decls, bool include_external_types) {
   if (!IsMapEntryMessage(descriptor_)) {
     for (int i = 0; i < descriptor_->field_count(); i++) {
       const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
@@ -238,7 +237,7 @@ void MessageGenerator::DetermineForwardDeclarations(
 }
 
 void MessageGenerator::DetermineObjectiveCClassDefinitions(
-    std::set<std::string>* fwd_decls) {
+    absl::btree_set<std::string>* fwd_decls) {
   if (!IsMapEntryMessage(descriptor_)) {
     for (int i = 0; i < descriptor_->field_count(); i++) {
       const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
diff --git a/src/google/protobuf/compiler/objectivec/message.h b/src/google/protobuf/compiler/objectivec/message.h
index 3b181f13b5..59ccd071ba 100644
--- a/src/google/protobuf/compiler/objectivec/message.h
+++ b/src/google/protobuf/compiler/objectivec/message.h
@@ -32,10 +32,10 @@
 #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
 
 #include <memory>
-#include <set>
 #include <string>
 #include <vector>
 
+#include "absl/container/btree_set.h"
 #include "google/protobuf/compiler/objectivec/field.h"
 #include "google/protobuf/compiler/objectivec/oneof.h"
 #include "google/protobuf/descriptor.h"
@@ -63,8 +63,9 @@ class MessageGenerator {
   void GenerateMessageHeader(io::Printer* printer);
   void GenerateSource(io::Printer* printer);
   void GenerateExtensionRegistrationSource(io::Printer* printer);
-  void DetermineObjectiveCClassDefinitions(std::set<std::string>* fwd_decls);
-  void DetermineForwardDeclarations(std::set<std::string>* fwd_decls,
+  void DetermineObjectiveCClassDefinitions(
+      absl::btree_set<std::string>* fwd_decls);
+  void DetermineForwardDeclarations(absl::btree_set<std::string>* fwd_decls,
                                     bool include_external_types);
 
   // Checks if the message or a nested message includes a oneof definition.
diff --git a/src/google/protobuf/compiler/objectivec/message_field.cc b/src/google/protobuf/compiler/objectivec/message_field.cc
index ddf1f19716..c4e17d753a 100644
--- a/src/google/protobuf/compiler/objectivec/message_field.cc
+++ b/src/google/protobuf/compiler/objectivec/message_field.cc
@@ -30,9 +30,9 @@
 
 #include "google/protobuf/compiler/objectivec/message_field.h"
 
-#include <set>
 #include <string>
 
+#include "absl/container/btree_set.h"
 #include "absl/container/flat_hash_map.h"
 #include "google/protobuf/compiler/objectivec/helpers.h"
 #include "google/protobuf/compiler/objectivec/names.h"
@@ -66,7 +66,8 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor)
 }
 
 void MessageFieldGenerator::DetermineForwardDeclarations(
-    std::set<std::string>* fwd_decls, bool include_external_types) const {
+    absl::btree_set<std::string>* fwd_decls,
+    bool include_external_types) const {
   ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls,
                                                       include_external_types);
   // Within a file there is no requirement on the order of the messages, so
@@ -81,7 +82,7 @@ void MessageFieldGenerator::DetermineForwardDeclarations(
 }
 
 void MessageFieldGenerator::DetermineObjectiveCClassDefinitions(
-    std::set<std::string>* fwd_decls) const {
+    absl::btree_set<std::string>* fwd_decls) const {
   fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
 }
 
@@ -95,7 +96,8 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
 }
 
 void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
-    std::set<std::string>* fwd_decls, bool include_external_types) const {
+    absl::btree_set<std::string>* fwd_decls,
+    bool include_external_types) const {
   RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls,
                                                        include_external_types);
   // Within a file there is no requirement on the order of the messages, so
@@ -110,7 +112,7 @@ void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
 }
 
 void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions(
-    std::set<std::string>* fwd_decls) const {
+    absl::btree_set<std::string>* fwd_decls) const {
   fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
 }
 
diff --git a/src/google/protobuf/compiler/objectivec/message_field.h b/src/google/protobuf/compiler/objectivec/message_field.h
index 430e7ad7a1..40028a0a7f 100644
--- a/src/google/protobuf/compiler/objectivec/message_field.h
+++ b/src/google/protobuf/compiler/objectivec/message_field.h
@@ -31,9 +31,9 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
 #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
 
-#include <set>
 #include <string>
 
+#include "absl/container/btree_set.h"
 #include "google/protobuf/compiler/objectivec/field.h"
 
 namespace google {
@@ -52,10 +52,10 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator {
   MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete;
 
  public:
-  void DetermineForwardDeclarations(std::set<std::string>* fwd_decls,
+  void DetermineForwardDeclarations(absl::btree_set<std::string>* fwd_decls,
                                     bool include_external_types) const override;
   void DetermineObjectiveCClassDefinitions(
-      std::set<std::string>* fwd_decls) const override;
+      absl::btree_set<std::string>* fwd_decls) const override;
 };
 
 class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
@@ -70,10 +70,10 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
       const RepeatedMessageFieldGenerator&) = delete;
 
  public:
-  void DetermineForwardDeclarations(std::set<std::string>* fwd_decls,
+  void DetermineForwardDeclarations(absl::btree_set<std::string>* fwd_decls,
                                     bool include_external_types) const override;
   void DetermineObjectiveCClassDefinitions(
-      std::set<std::string>* fwd_decls) const override;
+      absl::btree_set<std::string>* fwd_decls) const override;
 };
 
 }  // namespace objectivec
diff --git a/src/google/protobuf/compiler/objectivec/oneof.h b/src/google/protobuf/compiler/objectivec/oneof.h
index 27a1ecbc07..d9a23f902c 100644
--- a/src/google/protobuf/compiler/objectivec/oneof.h
+++ b/src/google/protobuf/compiler/objectivec/oneof.h
@@ -31,7 +31,6 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
 #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
 
-#include <set>
 #include <string>
 #include <vector>
 
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index 7546792408..49ae6bdeac 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -598,7 +598,7 @@ bool Parser::ValidateEnum(const EnumDescriptorProto* proto) {
     return false;
   }
 
-  std::set<int> used_values;
+  absl::flat_hash_set<int> used_values;
   bool has_duplicates = false;
   for (int i = 0; i < proto->value_size(); ++i) {
     const EnumValueDescriptorProto& enum_value = proto->value(i);
diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc
index 4c5e61e7f4..5501c98f2b 100644
--- a/src/google/protobuf/compiler/php/php_generator.cc
+++ b/src/google/protobuf/compiler/php/php_generator.cc
@@ -31,6 +31,7 @@
 #include "google/protobuf/compiler/php/php_generator.h"
 
 #include <sstream>
+#include <string>
 
 #include "google/protobuf/compiler/code_generator.h"
 #include "absl/container/flat_hash_map.h"
@@ -45,18 +46,18 @@
 #include "google/protobuf/io/printer.h"
 #include "google/protobuf/io/zero_copy_stream.h"
 
-const std::string kDescriptorFile = "google/protobuf/descriptor.proto";
-const std::string kEmptyFile = "google/protobuf/empty.proto";
-const std::string kEmptyMetadataFile = "GPBMetadata/Google/Protobuf/GPBEmpty.php";
-const std::string kDescriptorMetadataFile =
+constexpr absl::string_view kDescriptorFile =
+    "google/protobuf/descriptor.proto";
+constexpr absl::string_view kEmptyFile = "google/protobuf/empty.proto";
+constexpr absl::string_view kEmptyMetadataFile =
+    "GPBMetadata/Google/Protobuf/GPBEmpty.php";
+constexpr absl::string_view kDescriptorMetadataFile =
     "GPBMetadata/Google/Protobuf/Internal/Descriptor.php";
-const std::string kDescriptorDirName = "Google/Protobuf/Internal";
-const std::string kDescriptorPackageName = "Google\\Protobuf\\Internal";
-const char* const kValidConstantNames[] = {
-    "int",   "float", "bool", "string",   "true",
-    "false", "null",  "void", "iterable", "parent",
-    "self", "readonly"
-};
+constexpr absl::string_view kDescriptorPackageName =
+    "Google\\Protobuf\\Internal";
+constexpr absl::string_view kValidConstantNames[] = {
+    "int",  "float", "bool",     "string", "true", "false",
+    "null", "void",  "iterable", "parent", "self", "readonly"};
 const int kValidConstantNamesSize = 12;
 const int kFieldSetter = 1;
 const int kFieldGetter = 2;
@@ -71,7 +72,7 @@ struct Options {
   bool is_descriptor = false;
   bool aggregate_metadata = false;
   bool gen_c_wkt = false;
-  std::set<std::string> aggregate_metadata_prefixes;
+  absl::flat_hash_set<std::string> aggregate_metadata_prefixes;
 };
 
 namespace {
@@ -208,7 +209,7 @@ std::string PhpNamePrefix(const std::string& classname) {
 
 std::string PhpName(const std::string& full_name, const Options& options) {
   if (options.is_descriptor) {
-    return kDescriptorPackageName;
+    return std::string(kDescriptorPackageName);
   }
 
   std::string segment;
@@ -264,17 +265,17 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file,
   std::string segment = "";
 
   if (proto_file == kEmptyFile) {
-    return kEmptyMetadataFile;
+    return std::string(kEmptyMetadataFile);
   }
   if (options.is_descriptor) {
-    return kDescriptorMetadataFile;
+    return std::string(kDescriptorMetadataFile);
   }
 
   // Append directory name.
   std::string file_no_suffix;
   int lastindex = proto_file.find_last_of('.');
   if (proto_file == kEmptyFile) {
-    return kEmptyMetadataFile;
+    return std::string(kEmptyMetadataFile);
   } else {
     file_no_suffix = proto_file.substr(0, lastindex);
   }
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc
index b7e5c0e6f8..76f4f27193 100644
--- a/src/google/protobuf/compiler/plugin.cc
+++ b/src/google/protobuf/compiler/plugin.cc
@@ -33,8 +33,6 @@
 #include "google/protobuf/compiler/plugin.h"
 
 #include <iostream>
-#include <set>
-
 #ifdef _WIN32
 #include <fcntl.h>
 #else
diff --git a/src/google/protobuf/compiler/python/pyi_generator.cc b/src/google/protobuf/compiler/python/pyi_generator.cc
index bc90a6436c..65616f9a3b 100644
--- a/src/google/protobuf/compiler/python/pyi_generator.cc
+++ b/src/google/protobuf/compiler/python/pyi_generator.cc
@@ -33,6 +33,7 @@
 #include <string>
 #include <utility>
 
+#include "absl/container/flat_hash_set.h"
 #include "absl/strings/ascii.h"
 #include "absl/strings/match.h"
 #include "absl/strings/str_split.h"
@@ -152,7 +153,7 @@ void CheckImportModules(const Descriptor* descriptor,
 
 void PyiGenerator::PrintImportForDescriptor(
     const FileDescriptor& desc,
-    std::set<std::string>* seen_aliases) const {
+    absl::flat_hash_set<std::string>* seen_aliases) const {
   const std::string& filename = desc.name();
   std::string module_name_owned = StrippedModuleName(filename);
   absl::string_view module_name(module_name_owned);
@@ -179,7 +180,7 @@ void PyiGenerator::PrintImportForDescriptor(
 
 void PyiGenerator::PrintImports() const {
   // Prints imported dependent _pb2 files.
-  std::set<std::string> seen_aliases;
+  absl::flat_hash_set<std::string> seen_aliases;
   for (int i = 0; i < file_->dependency_count(); ++i) {
     const FileDescriptor* dep = file_->dependency(i);
     PrintImportForDescriptor(*dep, &seen_aliases);
diff --git a/src/google/protobuf/compiler/python/pyi_generator.h b/src/google/protobuf/compiler/python/pyi_generator.h
index bd7e71f90f..199d782f95 100644
--- a/src/google/protobuf/compiler/python/pyi_generator.h
+++ b/src/google/protobuf/compiler/python/pyi_generator.h
@@ -35,10 +35,10 @@
 #ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__
 #define GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__
 
-#include <set>
 #include <string>
 
 #include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
 #include "absl/synchronization/mutex.h"
 #include "google/protobuf/compiler/code_generator.h"
 
@@ -77,8 +77,9 @@ class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenera
                 std::string* error) const override;
 
  private:
-  void PrintImportForDescriptor(const FileDescriptor& desc,
-                                std::set<std::string>* seen_aliases) const;
+  void PrintImportForDescriptor(
+      const FileDescriptor& desc,
+      absl::flat_hash_set<std::string>* seen_aliases) const;
   template <typename DescriptorT>
   void Annotate(const std::string& label, const DescriptorT* descriptor) const;
   void PrintImports() const;
diff --git a/src/google/protobuf/compiler/scc.h b/src/google/protobuf/compiler/scc.h
index ec370b19be..c9a112af71 100644
--- a/src/google/protobuf/compiler/scc.h
+++ b/src/google/protobuf/compiler/scc.h
@@ -36,6 +36,7 @@
 #include "google/protobuf/stubs/logging.h"
 #include "google/protobuf/stubs/common.h"
 #include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
 #include "absl/memory/memory.h"
 #include "google/protobuf/descriptor.h"
 
@@ -147,7 +148,7 @@ class PROTOC_EXPORT SCCAnalyzer {
 
   // Add the SCC's that are children of this SCC to its children.
   void AddChildren(SCC* scc) {
-    std::set<const SCC*> seen;
+    absl::flat_hash_set<const SCC*> seen;
     for (auto descriptor : scc->descriptors) {
       for (auto child_msg : DepsGenerator()(descriptor)) {
         GOOGLE_CHECK(child_msg);