Internal change.

PiperOrigin-RevId: 970073736
diff --git a/src/google/protobuf/compiler/java/full/message_builder.cc b/src/google/protobuf/compiler/java/full/message_builder.cc
index e546e22..6781472 100644
--- a/src/google/protobuf/compiler/java/full/message_builder.cc
+++ b/src/google/protobuf/compiler/java/full/message_builder.cc
@@ -77,24 +77,6 @@
   ABSL_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
   return name_resolver->GetImmutableClassName(value_field->message_type());
 }
-
-bool BitfieldTracksMutability(const FieldDescriptor* const descriptor) {
-  if (!descriptor->is_repeated() || IsMapField(descriptor)) {
-    return false;
-  }
-  // TODO: update this to migrate repeated fields to use
-  // ProtobufList (which tracks immutability internally). That allows us to use
-  // the presence bit to skip work on the repeated field if it is not populated.
-  // Once all repeated fields are held in ProtobufLists, this method shouldn't
-  // be needed.
-  switch (descriptor->type()) {
-    case FieldDescriptor::TYPE_GROUP:
-    case FieldDescriptor::TYPE_MESSAGE:
-      return true;
-    default:
-      return false;
-  }
-}
 }  // namespace
 
 MessageBuilderGenerator::MessageBuilderGenerator(
@@ -150,11 +132,7 @@
   }
 
   // Integers for bit fields.
-  int totalBits = 0;
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    totalBits += field_generators_.get(descriptor_->field(i)).GetNumBits();
-  }
-  int totalInts = (totalBits + 31) / 32;
+  int totalInts = (descriptor_->field_count() + 31) / 32;
   for (int i = 0; i < totalInts; i++) {
     printer->Print("private int $bit_field_name$;\n", "bit_field_name",
                    GetBitFieldName(i));
@@ -582,20 +560,10 @@
 
   printer->Indent();
 
-  // Handle the repeated fields first so that the "mutable bits" are cleared.
-  bool has_repeated_fields = false;
-  for (int i = 0; i < descriptor_->field_count(); ++i) {
-    if (BitfieldTracksMutability(descriptor_->field(i))) {
-      has_repeated_fields = true;
-      printer->Print("buildPartialRepeatedFields(result);\n");
-      break;
-    }
-  }
-
   // One buildPartial_autosplit_#() per from_bit_field
-  int totalBuilderInts = (descriptor_->field_count() + 31) / 32;
-  if (totalBuilderInts > 0) {
-    for (int i = 0; i < totalBuilderInts; ++i) {
+  int totalInts = (descriptor_->field_count() + 31) / 32;
+  if (totalInts > 0) {
+    for (int i = 0; i < totalInts; ++i) {
       printer->Print(
           "if ($bit_field_name$ != 0) { "
           "buildPartial_autosplit_$shard$(result); }\n",
@@ -615,26 +583,9 @@
       "\n",
       "classname", name_resolver_->GetImmutableClassName(descriptor_));
 
-  // Build Repeated Fields
-  if (has_repeated_fields) {
-    printer->Print(
-        "private void buildPartialRepeatedFields($classname$ result) {\n",
-        "classname", name_resolver_->GetImmutableClassName(descriptor_));
-    printer->Indent();
-    for (int i = 0; i < descriptor_->field_count(); ++i) {
-      if (BitfieldTracksMutability(descriptor_->field(i))) {
-        const ImmutableFieldGenerator& field =
-            field_generators_.get(descriptor_->field(i));
-        field.GenerateBuildingCode(printer);
-      }
-    }
-    printer->Outdent();
-    printer->Print("}\n\n");
-  }
-
   // Build all fields in shards organized by bitfield membership.
   int start_field = 0;
-  for (int i = 0; i < totalBuilderInts; i++) {
+  for (int i = 0; i < totalInts; i++) {
     start_field = GenerateBuildPartialShard(printer, i, start_field);
   }
 
@@ -665,34 +616,21 @@
 
   int bit = 0;
   int next = first_field;
-  for (; bit < 32 && next < descriptor_->field_count(); ++next) {
+  for (; bit < 32 && next < descriptor_->field_count(); ++next, ++bit) {
     const ImmutableFieldGenerator& field =
         field_generators_.get(descriptor_->field(next));
-    bit += field.GetNumBits();
 
     // Skip oneof fields that are handled separately
     if (IsRealOneof(descriptor_->field(next))) {
       continue;
     }
 
-    // Skip repeated fields because they are currently handled
-    // in separate buildPartial sub-methods.
-    if (BitfieldTracksMutability(descriptor_->field(next))) {
-      continue;
-    }
-    // Skip fields without presence bits in the builder
-    if (field.GetNumBits() == 0) {
-      continue;
-    }
-
     // Track message bits if necessary
-    if (field.GetNumBits() > 0) {
-      int to_bitfield = field.GetBitIndex() / 32;
-      if (declared_to_bitfields.count(to_bitfield) == 0) {
-        printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name",
-                       GetBitFieldName(to_bitfield));
-        declared_to_bitfields.insert(to_bitfield);
-      }
+    int to_bitfield = field.GetBitIndex() / 32;
+    if (declared_to_bitfields.count(to_bitfield) == 0) {
+      printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name",
+                     GetBitFieldName(to_bitfield));
+      declared_to_bitfields.insert(to_bitfield);
     }
 
     // Copy the field from the builder to the message
diff --git a/src/google/protobuf/compiler/java/full/message_field.cc b/src/google/protobuf/compiler/java/full/message_field.cc
index 5a2c949..1ca8782 100644
--- a/src/google/protobuf/compiler/java/full/message_field.cc
+++ b/src/google/protobuf/compiler/java/full/message_field.cc
@@ -49,6 +49,9 @@
   (*variables)["group_or_message"] =
       (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
                                                            : "Message";
+  (*variables)["empty_list"] =
+      absl::StrCat("emptyList(", (*variables)["type"], ".class)");
+
   // TODO: Add @deprecated javadoc when generating javadoc is supported
   // by the proto compiler
   (*variables)["deprecation"] =
@@ -359,6 +362,7 @@
       "            isClean());\n"
       "    $name$_ = null;\n"
       "  }\n"
+      "  $set_has_field_bit$\n"
       "  return $name$Builder_;\n"
       "}\n");
 }
@@ -968,9 +972,10 @@
 
 void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
     io::Printer* printer) const {
-  printer->Print(variables_,
-                 "@SuppressWarnings(\"serial\")\n"
-                 "private java.util.List<$type$> $name$_;\n");
+  printer->Print(
+      variables_,
+      "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_ =\n"
+      "    $empty_list$;\n");
   PrintExtraFieldInfo(variables_, printer);
   GenerateGetListMethod(printer);
   GenerateGetOrBuilderListMethod(printer);
@@ -981,30 +986,29 @@
 
 void RepeatedImmutableMessageFieldGenerator::GenerateEnsureIsMutableMethod(
     io::Printer* printer) const {
-  printer->Print(
-      variables_,
-      "private void ensure$capitalized_name$IsMutable() {\n"
-      "  if (!$get_mutable_bit_builder$) {\n"
-      "    $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
-      "    $set_mutable_bit_builder$;\n"
-      "   }\n"
-      "}\n"
-      "\n");
+  printer->Print(variables_,
+                 "private void ensure$capitalized_name$IsMutable() {\n"
+                 "  if (!$name$_.isModifiable()) {\n"
+                 "    $name$_ = makeMutableCopy($name$_);\n"
+                 "  }\n"
+                 "  $set_has_field_bit$\n"
+                 "}\n");
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetListMethod(
     io::Printer* printer) const {
   // List<Field> getRepeatedFieldList()
   WriteFieldDocComment(printer, descriptor_, context_->options());
-  PrintNestedBuilderFunction(
-      printer,
-      "$deprecation$public java.util.List<$type$> "
-      "${$get$capitalized_name$List$}$()",
+  PrintNestedBuilderFunction(printer,
+                             "$deprecation$public java.util.List<$type$> "
+                             "${$get$capitalized_name$List$}$()",
 
-      "return java.util.Collections.unmodifiableList($name$_);\n",
-      "return $name$Builder_.getMessageList();\n",
+                             "$name$_.makeImmutable();\n"
+                             "return $name$_;\n",
 
-      nullptr);
+                             "return $name$Builder_.getMessageList();\n",
+
+                             nullptr);
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetCountMethod(
@@ -1046,8 +1050,9 @@
       "ensure$capitalized_name$IsMutable();\n"
       "$name$_.set(index, value);\n"
       "$on_changed$\n",
-      "$name$Builder_.setMessage(index, value);\n", "return this;\n",
-      Semantic::kSet);
+      "$name$Builder_.setMessage(index, "
+      "value);\n$set_has_field_bit$\n$on_changed$\n",
+      "return this;\n", Semantic::kSet);
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderSetBuilderMethod(
@@ -1078,7 +1083,9 @@
 
       "$on_changed$\n",
 
-      "$name$Builder_.addMessage(value);\n",
+      "$name$Builder_.addMessage(value);\n"
+      "$set_has_field_bit$\n"
+      "$on_changed$\n",
 
       "return this;\n", Semantic::kSet);
 }
@@ -1097,7 +1104,9 @@
       "$name$_.add(index, value);\n"
       "$on_changed$\n",
 
-      "$name$Builder_.addMessage(index, value);\n",
+      "$name$Builder_.addMessage(index, value);\n"
+      "$set_has_field_bit$\n"
+      "$on_changed$\n",
 
       "return this;\n", Semantic::kSet);
 }
@@ -1138,14 +1147,17 @@
       "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
       "    java.lang.Iterable<? extends $type$> values)",
 
-      "ensure$capitalized_name$IsMutable();\n"
-      "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
-      "    values, $name$_);\n"
-      "$on_changed$\n",
+      "$name$_ = com.google.protobuf.Internal.ProtobufList.concatenate(\n"
+      "    $name$_, values);\n",
 
       "$name$Builder_.addAllMessages(values);\n",
 
-      "return this;\n", Semantic::kSet);
+      "if (get$capitalized_name$Count() > 0) {\n"
+      "  $set_has_field_bit$;\n"
+      "}\n"
+      "$on_changed$\n"
+      "return this;\n",
+      Semantic::kSet);
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearMethod(
@@ -1155,13 +1167,14 @@
   PrintNestedBuilderFunction(
       printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
 
-      "$name$_ = java.util.Collections.emptyList();\n"
-      "$clear_mutable_bit_builder$;\n"
-      "$on_changed$\n",
+      "$name$_ = $empty_list$;\n",
 
       "$name$Builder_.clear();\n",
 
-      "return this;\n", Semantic::kSet);
+      "$clear_has_field_bit$\n"
+      "$on_changed$\n"
+      "return this;\n",
+      Semantic::kSet);
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderRemoveMethod(
@@ -1173,12 +1186,16 @@
       "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)",
 
       "ensure$capitalized_name$IsMutable();\n"
-      "$name$_.remove(index);\n"
-      "$on_changed$\n",
+      "$name$_.remove(index);\n",
 
       "$name$Builder_.remove(index);\n",
 
-      "return this;\n", Semantic::kSet);
+      "if (get$capitalized_name$Count() == 0) {\n"
+      "  $clear_has_field_bit$;\n"
+      "}\n"
+      "$on_changed$\n"
+      "return this;\n",
+      Semantic::kSet);
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetBuilderMethod(
@@ -1224,7 +1241,8 @@
       "  if ($name$Builder_ != null) {\n"
       "    return $name$Builder_.getMessageOrBuilderList();\n"
       "  } else {\n"
-      "    return java.util.Collections.unmodifiableList($name$_);\n"
+      "    $name$_.makeImmutable();\n"
+      "    return $name$_;\n"
       "  }\n"
       "}\n");
   printer->Annotate("{", "}", descriptor_);
@@ -1232,11 +1250,13 @@
 
 void RepeatedImmutableMessageFieldGenerator::
     GenerateBuilderAddBuilderNoArgsMethod(io::Printer* printer) const {
-  // Field.Builder addRepeatedField()
+  // Field.Builder addRepeatedFieldBuilder()
   WriteFieldDocComment(printer, descriptor_, context_->options());
   printer->Print(variables_,
                  "$deprecation$public $type$.Builder "
                  "${$add$capitalized_name$Builder$}$() {\n"
+                 "  $set_has_field_bit$\n"
+                 "  $on_changed$\n"
                  "  return "
                  "internalGet$capitalized_name$FieldBuilder().addBuilder(\n"
                  "      $type$.getDefaultInstance());\n"
@@ -1252,6 +1272,8 @@
       variables_,
       "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n"
       "    int index) {\n"
+      "  $set_has_field_bit$\n"
+      "  $on_changed$\n"
       "  return "
       "internalGet$capitalized_name$FieldBuilder().addBuilder(\n"
       "      index, $type$.getDefaultInstance());\n"
@@ -1284,30 +1306,23 @@
                  "com.google.protobuf.RepeatedFieldBuilder<\n"
                  "        $type$, $type$.Builder, $type$OrBuilder>(\n"
                  "            $name$_,\n"
-                 "            $get_mutable_bit_builder$,\n"
+                 "            $name$_.isModifiable(),\n"
                  "            getParentForChildren(),\n"
                  "            isClean());\n"
                  "    $name$_ = null;\n"
                  "  }\n"
+                 "  $set_has_field_bit$\n"
+                 "  $on_changed$\n"
                  "  return $name$Builder_;\n"
                  "}\n");
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
     io::Printer* printer) const {
-  // Used when the builder is null.
-  // One field is the list and the other field keeps track of whether the
-  // list is immutable. If it's immutable, the invariant is that it must
-  // either an instance of Collections.emptyList() or it's an ArrayList
-  // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
-  // a reference to the underlying ArrayList. This invariant allows us to
-  // share instances of lists between protocol buffers avoiding expensive
-  // memory allocations. Note, immutable is a strong guarantee here -- not
-  // just that the list cannot be modified via the reference but that the
-  // list can never be modified.
-  printer->Print(variables_,
-                 "private java.util.List<$type$> $name$_ =\n"
-                 "  java.util.Collections.emptyList();\n");
+  printer->Print(
+      variables_,
+      "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_ =\n"
+      "    emptyList($type$.class);\n");
 
   GenerateEnsureIsMutableMethod(printer);
 
@@ -1339,7 +1354,6 @@
   GenerateBuilderGetBuilderListMethod(printer);
   GenerateBuilderInternalGetFieldBuilderMethod(printer);
 }
-
 void RepeatedImmutableMessageFieldGenerator::
     GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
   printer->Print(variables_, "internalGet$capitalized_name$FieldBuilder();\n");
@@ -1347,18 +1361,16 @@
 
 void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode(
     io::Printer* printer) const {
-  printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
+  printer->Print(variables_, "$name$_ = $empty_list$;\n");
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode(
     io::Printer* printer) const {
-  PrintNestedBuilderCondition(printer,
-                              "$name$_ = java.util.Collections.emptyList();\n",
+  PrintNestedBuilderCondition(printer, "$name$_ = $empty_list$;\n",
 
                               "$name$_ = null;\n"
                               "$name$Builder_.clear();\n");
-
-  printer->Print(variables_, "$clear_mutable_bit_builder$;\n");
+  printer->Print(variables_, "$clear_has_field_bit$;\n");
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode(
@@ -1373,7 +1385,7 @@
       "if (!other.$name$_.isEmpty()) {\n"
       "  if ($name$_.isEmpty()) {\n"
       "    $name$_ = other.$name$_;\n"
-      "    $clear_mutable_bit_builder$;\n"
+      "    $set_has_field_bit$\n"
       "  } else {\n"
       "    ensure$capitalized_name$IsMutable();\n"
       "    $name$_.addAll(other.$name$_);\n"
@@ -1386,14 +1398,16 @@
       "    $name$Builder_.dispose();\n"
       "    $name$Builder_ = null;\n"
       "    $name$_ = other.$name$_;\n"
-      "    $clear_mutable_bit_builder$;\n"
+      "    $set_has_field_bit$\n"
       "    $name$Builder_ = \n"
       "      com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders "
       "?\n"
       "         internalGet$capitalized_name$FieldBuilder() : null;\n"
       "  } else {\n"
       "    $name$Builder_.addAllMessages(other.$name$_);\n"
+      "    $set_has_field_bit$\n"
       "  }\n"
+      "  $on_changed$\n"
       "}\n");
 }
 
@@ -1402,15 +1416,14 @@
   // The code below (non-nested builder case) ensures that the result has an
   // immutable list. If our list is immutable, we can just reuse it. If not,
   // we make it immutable.
+  printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n");
   PrintNestedBuilderCondition(
       printer,
-      "if ($get_mutable_bit_builder$) {\n"
-      "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
-      "  $clear_mutable_bit_builder$;\n"
-      "}\n"
+      "$name$_.makeImmutable();\n"
       "result.$name$_ = $name$_;\n",
 
-      "result.$name$_ = $name$Builder_.build();\n");
+      "result.$name$_ = $name$Builder_.buildProtobufList();\n");
+  printer->Print("}\n");
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
@@ -1431,7 +1444,9 @@
   PrintNestedBuilderCondition(printer,
                               "ensure$capitalized_name$IsMutable();\n"
                               "$name$_.add(m);\n",
-                              "$name$Builder_.addMessage(m);\n");
+                              "$name$Builder_.addMessage(m);\n"
+                              "$set_has_field_bit$\n"
+                              "$on_changed$\n");
 }
 
 void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode(