aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/protobuf/patches/text-format-print-field-raii.patch
blob: 8ceb28835b685e885893b4cb39ee2c5a05c599fb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
--- a/contrib/libs/protobuf/src/google/protobuf/text_format.cc	(revision 0aeb3fd964b80cb80d7b17e28f06b65f974da75a)
+++ b/contrib/libs/protobuf/src/google/protobuf/text_format.cc	(date 1751482029353)
@@ -47,6 +47,7 @@
 #include <vector>

 #include "y_absl/container/btree_set.h"
+#include "y_absl/memory/memory.h"
 #include "y_absl/strings/ascii.h"
 #include "y_absl/strings/escaping.h"
 #include "y_absl/strings/numbers.h"
@@ -2341,32 +2342,38 @@
 };

 namespace internal {
+
+struct MapEntries {
+  std::vector<std::unique_ptr<const Message>> owned_entries;
+  std::vector<const Message*> all_entries;
+};
+
 class MapFieldPrinterHelper {
  public:
   // DynamicMapSorter::Sort cannot be used because it enforces syncing with
   // repeated field.
-  static bool SortMap(const Message& message, const Reflection* reflection,
-                      const FieldDescriptor* field,
-                      std::vector<const Message*>* sorted_map_field);
+  static MapEntries SortMap(const Message& message,
+                            const Reflection* reflection,
+                            const FieldDescriptor* field);
   static void CopyKey(const MapKey& key, Message* message,
                       const FieldDescriptor* field_desc);
   static void CopyValue(const MapValueRef& value, Message* message,
                         const FieldDescriptor* field_desc);
 };

-// Returns true if elements contained in sorted_map_field need to be released.
-bool MapFieldPrinterHelper::SortMap(
-    const Message& message, const Reflection* reflection,
-    const FieldDescriptor* field,
-    std::vector<const Message*>* sorted_map_field) {
-  bool need_release = false;
+MapEntries MapFieldPrinterHelper::SortMap(const Message& message,
+                                          const Reflection* reflection,
+                                          const FieldDescriptor* field) {
   const MapFieldBase& base = *reflection->GetMapData(message, field);

+  std::vector<const Message*> all_entries;
+  std::vector<std::unique_ptr<const Message>> owned_entries;
   if (base.IsRepeatedFieldValid()) {
     const RepeatedPtrField<Message>& map_field =
         reflection->GetRepeatedPtrFieldInternal<Message>(message, field);
+    all_entries.reserve(map_field.size());
     for (int i = 0; i < map_field.size(); ++i) {
-      sorted_map_field->push_back(
+      all_entries.push_back(
           const_cast<RepeatedPtrField<Message>*>(&map_field)->Mutable(i));
     }
   } else {
@@ -2375,23 +2382,25 @@
     const Descriptor* map_entry_desc = field->message_type();
     const Message* prototype =
         reflection->GetMessageFactory()->GetPrototype(map_entry_desc);
+    all_entries.reserve(reflection->MapSize(message, field));
+    owned_entries.reserve(reflection->MapSize(message, field));
     for (MapIterator iter =
              reflection->MapBegin(const_cast<Message*>(&message), field);
          iter != reflection->MapEnd(const_cast<Message*>(&message), field);
          ++iter) {
-      Message* map_entry_message = prototype->New();
-      CopyKey(iter.GetKey(), map_entry_message, map_entry_desc->field(0));
-      CopyValue(iter.GetValueRef(), map_entry_message,
+      std::unique_ptr<Message> map_entry_message =
+          y_absl::WrapUnique(prototype->New());
+      CopyKey(iter.GetKey(), map_entry_message.get(), map_entry_desc->field(0));
+      CopyValue(iter.GetValueRef(), map_entry_message.get(),
                 map_entry_desc->field(1));
-      sorted_map_field->push_back(map_entry_message);
+      all_entries.push_back(map_entry_message.get());
+      owned_entries.push_back(std::move(map_entry_message));
     }
-    need_release = true;
   }

-  MapEntryMessageComparator comparator(field->message_type());
-  std::stable_sort(sorted_map_field->begin(), sorted_map_field->end(),
-                   comparator);
-  return need_release;
+  std::stable_sort(all_entries.begin(), all_entries.end(),
+                   MapEntryMessageComparator(field->message_type()));
+  return {std::move(owned_entries), std::move(all_entries)};
 }

 void MapFieldPrinterHelper::CopyKey(const MapKey& key, Message* message,
@@ -2487,13 +2496,11 @@
     count = 1;
   }

-  std::vector<const Message*> sorted_map_field;
-  bool need_release = false;
   bool is_map = field->is_map();
-  if (is_map) {
-    need_release = internal::MapFieldPrinterHelper::SortMap(
-        message, reflection, field, &sorted_map_field);
-  }
+  const internal::MapEntries map_entries =
+      is_map
+          ? internal::MapFieldPrinterHelper::SortMap(message, reflection, field)
+          : internal::MapEntries();

   for (int j = 0; j < count; ++j) {
     const int field_index = field->is_repeated() ? j : -1;
@@ -2504,7 +2511,7 @@
       const FastFieldValuePrinter* printer = GetFieldPrinter(field);
       const Message& sub_message =
           field->is_repeated()
-              ? (is_map ? *sorted_map_field[j]
+              ? (is_map ? *map_entries.all_entries[j]
                         : reflection->GetRepeatedMessage(message, field, j))
               : reflection->GetMessage(message, field);
       printer->PrintMessageStart(sub_message, field_index, count,
@@ -2528,12 +2535,6 @@
       }
     }
   }
-
-  if (need_release) {
-    for (const Message* message_to_delete : sorted_map_field) {
-      delete message_to_delete;
-    }
-  }
 }

 void TextFormat::Printer::PrintShortRepeatedField(