|
46 | 46 | #include "google/protobuf/compiler/objectivec/names.h" |
47 | 47 | #include "google/protobuf/compiler/objectivec/oneof.h" |
48 | 48 | #include "google/protobuf/compiler/objectivec/text_format_decode_data.h" |
| 49 | +#include "google/protobuf/descriptor.h" |
49 | 50 | #include "google/protobuf/descriptor.pb.h" |
50 | 51 | #include "google/protobuf/io/printer.h" |
51 | 52 |
|
@@ -153,6 +154,39 @@ struct ExtensionRangeOrdering { |
153 | 154 | } |
154 | 155 | }; |
155 | 156 |
|
| 157 | +// This is a reduced case of Descriptor::ExtensionRange with just start and end. |
| 158 | +struct SimpleExtensionRange { |
| 159 | + SimpleExtensionRange(int start, int end) : start(start), end(end){}; |
| 160 | + int start; // inclusive |
| 161 | + int end; // exclusive |
| 162 | + |
| 163 | + // Descriptors expose extension ranges in the order they were defined in the |
| 164 | + // file, but this reorders and merges the ranges that are contiguous (i.e. - |
| 165 | + // [(21,30),(10,20)] -> [(10,30)]) |
| 166 | + static std::vector<SimpleExtensionRange> Normalize( |
| 167 | + const Descriptor* descriptor) { |
| 168 | + std::vector<const Descriptor::ExtensionRange*> sorted_extensions; |
| 169 | + sorted_extensions.reserve(descriptor->extension_range_count()); |
| 170 | + for (int i = 0; i < descriptor->extension_range_count(); ++i) { |
| 171 | + sorted_extensions.push_back(descriptor->extension_range(i)); |
| 172 | + } |
| 173 | + |
| 174 | + std::sort(sorted_extensions.begin(), sorted_extensions.end(), |
| 175 | + ExtensionRangeOrdering()); |
| 176 | + |
| 177 | + std::vector<SimpleExtensionRange> result; |
| 178 | + result.reserve(sorted_extensions.size()); |
| 179 | + for (const auto ext : sorted_extensions) { |
| 180 | + if (!result.empty() && result.back().end == ext->start) { |
| 181 | + result.back().end = ext->end; |
| 182 | + } else { |
| 183 | + result.emplace_back(ext->start, ext->end); |
| 184 | + } |
| 185 | + } |
| 186 | + return result; |
| 187 | + } |
| 188 | +}; |
| 189 | + |
156 | 190 | // Sort the fields of the given Descriptor by number into a new[]'d array |
157 | 191 | // and return it. |
158 | 192 | const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { |
@@ -387,14 +421,8 @@ void MessageGenerator::GenerateSource(io::Printer* printer) const { |
387 | 421 | std::unique_ptr<const FieldDescriptor*[]> size_order_fields( |
388 | 422 | SortFieldsByStorageSize(descriptor_)); |
389 | 423 |
|
390 | | - std::vector<const Descriptor::ExtensionRange*> sorted_extensions; |
391 | | - sorted_extensions.reserve(descriptor_->extension_range_count()); |
392 | | - for (int i = 0; i < descriptor_->extension_range_count(); ++i) { |
393 | | - sorted_extensions.push_back(descriptor_->extension_range(i)); |
394 | | - } |
395 | | - |
396 | | - std::sort(sorted_extensions.begin(), sorted_extensions.end(), |
397 | | - ExtensionRangeOrdering()); |
| 424 | + std::vector<SimpleExtensionRange> sorted_extensions( |
| 425 | + SimpleExtensionRange::Normalize(descriptor_)); |
398 | 426 |
|
399 | 427 | printer->Print( |
400 | 428 | // clang-format off |
@@ -528,10 +556,10 @@ void MessageGenerator::GenerateSource(io::Printer* printer) const { |
528 | 556 | } |
529 | 557 | if (!sorted_extensions.empty()) { |
530 | 558 | printer->Print(" static const GPBExtensionRange ranges[] = {\n"); |
531 | | - for (int i = 0; i < sorted_extensions.size(); i++) { |
| 559 | + for (const auto& extension_range : sorted_extensions) { |
532 | 560 | printer->Print(" { .start = $start$, .end = $end$ },\n", "start", |
533 | | - absl::StrCat(sorted_extensions[i]->start), "end", |
534 | | - absl::StrCat(sorted_extensions[i]->end)); |
| 561 | + absl::StrCat(extension_range.start), "end", |
| 562 | + absl::StrCat(extension_range.end)); |
535 | 563 | } |
536 | 564 | // clang-format off |
537 | 565 | printer->Print( |
|
0 commit comments