objectivec_message.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #include <algorithm>
  31. #include <iostream>
  32. #include <sstream>
  33. #include <google/protobuf/compiler/objectivec/objectivec_message.h>
  34. #include <google/protobuf/compiler/objectivec/objectivec_enum.h>
  35. #include <google/protobuf/compiler/objectivec/objectivec_extension.h>
  36. #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
  37. #include <google/protobuf/stubs/stl_util.h>
  38. #include <google/protobuf/stubs/strutil.h>
  39. #include <google/protobuf/io/printer.h>
  40. #include <google/protobuf/io/coded_stream.h>
  41. #include <google/protobuf/io/zero_copy_stream_impl.h>
  42. #include <google/protobuf/wire_format.h>
  43. #include <google/protobuf/wire_format_lite.h>
  44. #include <google/protobuf/descriptor.pb.h>
  45. namespace google {
  46. namespace protobuf {
  47. namespace compiler {
  48. namespace objectivec {
  49. namespace {
  50. struct FieldOrderingByNumber {
  51. inline bool operator()(const FieldDescriptor* a,
  52. const FieldDescriptor* b) const {
  53. return a->number() < b->number();
  54. }
  55. };
  56. int OrderGroupForFieldDescriptor(const FieldDescriptor* descriptor) {
  57. // The first item in the object structure is our uint32[] for has bits.
  58. // We then want to order things to make the instances as small as
  59. // possible. So we follow the has bits with:
  60. // 1. Anything always 4 bytes - float, *32, enums
  61. // 2. Anything that is always a pointer (they will be 8 bytes on 64 bit
  62. // builds and 4 bytes on 32bit builds.
  63. // 3. Anything always 8 bytes - double, *64
  64. //
  65. // NOTE: Bools aren't listed, they were stored in the has bits.
  66. //
  67. // Why? Using 64bit builds as an example, this means worse case, we have
  68. // enough bools that we overflow 1 byte from 4 byte alignment, so 3 bytes
  69. // are wasted before the 4 byte values. Then if we have an odd number of
  70. // those 4 byte values, the 8 byte values will be pushed down by 32bits to
  71. // keep them aligned. But the structure will end 8 byte aligned, so no
  72. // waste on the end. If you did the reverse order, you could waste 4 bytes
  73. // before the first 8 byte value (after the has array), then a single
  74. // bool on the end would need 7 bytes of padding to make the overall
  75. // structure 8 byte aligned; so 11 bytes, wasted total.
  76. // Anything repeated is a GPB*Array/NSArray, so pointer.
  77. if (descriptor->is_repeated()) {
  78. return 3;
  79. }
  80. switch (descriptor->type()) {
  81. // All always 8 bytes.
  82. case FieldDescriptor::TYPE_DOUBLE:
  83. case FieldDescriptor::TYPE_INT64:
  84. case FieldDescriptor::TYPE_SINT64:
  85. case FieldDescriptor::TYPE_UINT64:
  86. case FieldDescriptor::TYPE_SFIXED64:
  87. case FieldDescriptor::TYPE_FIXED64:
  88. return 4;
  89. // Pointers (string and bytes are NSString and NSData); 8 or 4 bytes
  90. // depending on the build architecture.
  91. case FieldDescriptor::TYPE_GROUP:
  92. case FieldDescriptor::TYPE_MESSAGE:
  93. case FieldDescriptor::TYPE_STRING:
  94. case FieldDescriptor::TYPE_BYTES:
  95. return 3;
  96. // All always 4 bytes (enums are int32s).
  97. case FieldDescriptor::TYPE_FLOAT:
  98. case FieldDescriptor::TYPE_INT32:
  99. case FieldDescriptor::TYPE_SINT32:
  100. case FieldDescriptor::TYPE_UINT32:
  101. case FieldDescriptor::TYPE_SFIXED32:
  102. case FieldDescriptor::TYPE_FIXED32:
  103. case FieldDescriptor::TYPE_ENUM:
  104. return 2;
  105. // 0 bytes. Stored in the has bits.
  106. case FieldDescriptor::TYPE_BOOL:
  107. return 99; // End of the list (doesn't really matter).
  108. }
  109. // Some compilers report reaching end of function even though all cases of
  110. // the enum are handed in the switch.
  111. GOOGLE_LOG(FATAL) << "Can't get here.";
  112. return 0;
  113. }
  114. struct FieldOrderingByStorageSize {
  115. inline bool operator()(const FieldDescriptor* a,
  116. const FieldDescriptor* b) const {
  117. // Order by grouping.
  118. const int order_group_a = OrderGroupForFieldDescriptor(a);
  119. const int order_group_b = OrderGroupForFieldDescriptor(b);
  120. if (order_group_a != order_group_b) {
  121. return order_group_a < order_group_b;
  122. }
  123. // Within the group, order by field number (provides stable ordering).
  124. return a->number() < b->number();
  125. }
  126. };
  127. struct ExtensionRangeOrdering {
  128. bool operator()(const Descriptor::ExtensionRange* a,
  129. const Descriptor::ExtensionRange* b) const {
  130. return a->start < b->start;
  131. }
  132. };
  133. // Sort the fields of the given Descriptor by number into a new[]'d array
  134. // and return it.
  135. const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
  136. const FieldDescriptor** fields =
  137. new const FieldDescriptor* [descriptor->field_count()];
  138. for (int i = 0; i < descriptor->field_count(); i++) {
  139. fields[i] = descriptor->field(i);
  140. }
  141. std::sort(fields, fields + descriptor->field_count(), FieldOrderingByNumber());
  142. return fields;
  143. }
  144. // Sort the fields of the given Descriptor by storage size into a new[]'d
  145. // array and return it.
  146. const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) {
  147. const FieldDescriptor** fields =
  148. new const FieldDescriptor* [descriptor->field_count()];
  149. for (int i = 0; i < descriptor->field_count(); i++) {
  150. fields[i] = descriptor->field(i);
  151. }
  152. std::sort(fields, fields + descriptor->field_count(),
  153. FieldOrderingByStorageSize());
  154. return fields;
  155. }
  156. } // namespace
  157. MessageGenerator::MessageGenerator(const std::string& root_classname,
  158. const Descriptor* descriptor,
  159. const Options& options)
  160. : root_classname_(root_classname),
  161. descriptor_(descriptor),
  162. field_generators_(descriptor, options),
  163. class_name_(ClassName(descriptor_)),
  164. deprecated_attribute_(GetOptionalDeprecatedAttribute(
  165. descriptor, descriptor->file(), false, true)) {
  166. for (int i = 0; i < descriptor_->extension_count(); i++) {
  167. extension_generators_.emplace_back(
  168. new ExtensionGenerator(class_name_, descriptor_->extension(i)));
  169. }
  170. for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
  171. OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i));
  172. oneof_generators_.emplace_back(generator);
  173. }
  174. for (int i = 0; i < descriptor_->enum_type_count(); i++) {
  175. EnumGenerator* generator = new EnumGenerator(descriptor_->enum_type(i));
  176. enum_generators_.emplace_back(generator);
  177. }
  178. for (int i = 0; i < descriptor_->nested_type_count(); i++) {
  179. MessageGenerator* generator =
  180. new MessageGenerator(root_classname_,
  181. descriptor_->nested_type(i),
  182. options);
  183. nested_message_generators_.emplace_back(generator);
  184. }
  185. }
  186. MessageGenerator::~MessageGenerator() {}
  187. void MessageGenerator::GenerateStaticVariablesInitialization(
  188. io::Printer* printer) {
  189. for (const auto& generator : extension_generators_) {
  190. generator->GenerateStaticVariablesInitialization(printer);
  191. }
  192. for (const auto& generator : nested_message_generators_) {
  193. generator->GenerateStaticVariablesInitialization(printer);
  194. }
  195. }
  196. void MessageGenerator::DetermineForwardDeclarations(
  197. std::set<std::string>* fwd_decls) {
  198. if (!IsMapEntryMessage(descriptor_)) {
  199. for (int i = 0; i < descriptor_->field_count(); i++) {
  200. const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
  201. field_generators_.get(fieldDescriptor)
  202. .DetermineForwardDeclarations(fwd_decls);
  203. }
  204. }
  205. for (const auto& generator : nested_message_generators_) {
  206. generator->DetermineForwardDeclarations(fwd_decls);
  207. }
  208. }
  209. void MessageGenerator::DetermineObjectiveCClassDefinitions(
  210. std::set<std::string>* fwd_decls) {
  211. if (!IsMapEntryMessage(descriptor_)) {
  212. for (int i = 0; i < descriptor_->field_count(); i++) {
  213. const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
  214. field_generators_.get(fieldDescriptor)
  215. .DetermineObjectiveCClassDefinitions(fwd_decls);
  216. }
  217. }
  218. for (const auto& generator : extension_generators_) {
  219. generator->DetermineObjectiveCClassDefinitions(fwd_decls);
  220. }
  221. for (const auto& generator : nested_message_generators_) {
  222. generator->DetermineObjectiveCClassDefinitions(fwd_decls);
  223. }
  224. const Descriptor* containing_descriptor = descriptor_->containing_type();
  225. if (containing_descriptor != NULL) {
  226. std::string containing_class = ClassName(containing_descriptor);
  227. fwd_decls->insert(ObjCClassDeclaration(containing_class));
  228. }
  229. }
  230. bool MessageGenerator::IncludesOneOfDefinition() const {
  231. if (!oneof_generators_.empty()) {
  232. return true;
  233. }
  234. for (const auto& generator : nested_message_generators_) {
  235. if (generator->IncludesOneOfDefinition()) {
  236. return true;
  237. }
  238. }
  239. return false;
  240. }
  241. void MessageGenerator::GenerateEnumHeader(io::Printer* printer) {
  242. for (const auto& generator : enum_generators_) {
  243. generator->GenerateHeader(printer);
  244. }
  245. for (const auto& generator : nested_message_generators_) {
  246. generator->GenerateEnumHeader(printer);
  247. }
  248. }
  249. void MessageGenerator::GenerateExtensionRegistrationSource(
  250. io::Printer* printer) {
  251. for (const auto& generator : extension_generators_) {
  252. generator->GenerateRegistrationSource(printer);
  253. }
  254. for (const auto& generator : nested_message_generators_) {
  255. generator->GenerateExtensionRegistrationSource(printer);
  256. }
  257. }
  258. void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
  259. // This a a map entry message, just recurse and do nothing directly.
  260. if (IsMapEntryMessage(descriptor_)) {
  261. for (const auto& generator : nested_message_generators_) {
  262. generator->GenerateMessageHeader(printer);
  263. }
  264. return;
  265. }
  266. printer->Print(
  267. "#pragma mark - $classname$\n"
  268. "\n",
  269. "classname", class_name_);
  270. if (descriptor_->field_count()) {
  271. std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
  272. SortFieldsByNumber(descriptor_));
  273. printer->Print("typedef GPB_ENUM($classname$_FieldNumber) {\n",
  274. "classname", class_name_);
  275. printer->Indent();
  276. for (int i = 0; i < descriptor_->field_count(); i++) {
  277. field_generators_.get(sorted_fields[i])
  278. .GenerateFieldNumberConstant(printer);
  279. }
  280. printer->Outdent();
  281. printer->Print("};\n\n");
  282. }
  283. for (const auto& generator : oneof_generators_) {
  284. generator->GenerateCaseEnum(printer);
  285. }
  286. std::string message_comments;
  287. SourceLocation location;
  288. if (descriptor_->GetSourceLocation(&location)) {
  289. message_comments = BuildCommentsString(location, false);
  290. } else {
  291. message_comments = "";
  292. }
  293. printer->Print(
  294. "$comments$$deprecated_attribute$GPB_FINAL @interface $classname$ : GPBMessage\n\n",
  295. "classname", class_name_,
  296. "deprecated_attribute", deprecated_attribute_,
  297. "comments", message_comments);
  298. std::vector<char> seen_oneofs(oneof_generators_.size(), 0);
  299. for (int i = 0; i < descriptor_->field_count(); i++) {
  300. const FieldDescriptor* field = descriptor_->field(i);
  301. const OneofDescriptor *oneof = field->real_containing_oneof();
  302. if (oneof) {
  303. const int oneof_index = oneof->index();
  304. if (!seen_oneofs[oneof_index]) {
  305. seen_oneofs[oneof_index] = 1;
  306. oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
  307. printer);
  308. }
  309. }
  310. field_generators_.get(field).GeneratePropertyDeclaration(printer);
  311. }
  312. printer->Print("@end\n\n");
  313. for (int i = 0; i < descriptor_->field_count(); i++) {
  314. field_generators_.get(descriptor_->field(i))
  315. .GenerateCFunctionDeclarations(printer);
  316. }
  317. if (!oneof_generators_.empty()) {
  318. for (const auto& generator : oneof_generators_) {
  319. generator->GenerateClearFunctionDeclaration(printer);
  320. }
  321. printer->Print("\n");
  322. }
  323. if (descriptor_->extension_count() > 0) {
  324. printer->Print("@interface $classname$ (DynamicMethods)\n\n",
  325. "classname", class_name_);
  326. for (const auto& generator : extension_generators_) {
  327. generator->GenerateMembersHeader(printer);
  328. }
  329. printer->Print("@end\n\n");
  330. }
  331. for (const auto& generator : nested_message_generators_) {
  332. generator->GenerateMessageHeader(printer);
  333. }
  334. }
  335. void MessageGenerator::GenerateSource(io::Printer* printer) {
  336. if (!IsMapEntryMessage(descriptor_)) {
  337. printer->Print(
  338. "#pragma mark - $classname$\n"
  339. "\n",
  340. "classname", class_name_);
  341. if (!deprecated_attribute_.empty()) {
  342. // No warnings when compiling the impl of this deprecated class.
  343. printer->Print(
  344. "#pragma clang diagnostic push\n"
  345. "#pragma clang diagnostic ignored \"-Wdeprecated-implementations\"\n"
  346. "\n");
  347. }
  348. printer->Print("@implementation $classname$\n\n",
  349. "classname", class_name_);
  350. for (const auto& generator : oneof_generators_) {
  351. generator->GeneratePropertyImplementation(printer);
  352. }
  353. for (int i = 0; i < descriptor_->field_count(); i++) {
  354. field_generators_.get(descriptor_->field(i))
  355. .GeneratePropertyImplementation(printer);
  356. }
  357. std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
  358. SortFieldsByNumber(descriptor_));
  359. std::unique_ptr<const FieldDescriptor*[]> size_order_fields(
  360. SortFieldsByStorageSize(descriptor_));
  361. std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
  362. sorted_extensions.reserve(descriptor_->extension_range_count());
  363. for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
  364. sorted_extensions.push_back(descriptor_->extension_range(i));
  365. }
  366. std::sort(sorted_extensions.begin(), sorted_extensions.end(),
  367. ExtensionRangeOrdering());
  368. // Assign has bits:
  369. // 1. FieldGeneratorMap::CalculateHasBits() loops through the fields seeing
  370. // who needs has bits and assigning them.
  371. // 2. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative
  372. // index that groups all the elements in the oneof.
  373. size_t num_has_bits = field_generators_.CalculateHasBits();
  374. size_t sizeof_has_storage = (num_has_bits + 31) / 32;
  375. if (sizeof_has_storage == 0) {
  376. // In the case where no field needs has bits, don't let the _has_storage_
  377. // end up as zero length (zero length arrays are sort of a grey area
  378. // since it has to be at the start of the struct). This also ensures a
  379. // field with only oneofs keeps the required negative indices they need.
  380. sizeof_has_storage = 1;
  381. }
  382. // Tell all the fields the oneof base.
  383. for (const auto& generator : oneof_generators_) {
  384. generator->SetOneofIndexBase(sizeof_has_storage);
  385. }
  386. field_generators_.SetOneofIndexBase(sizeof_has_storage);
  387. // sizeof_has_storage needs enough bits for the single fields that aren't in
  388. // any oneof, and then one int32 for each oneof (to store the field number).
  389. sizeof_has_storage += oneof_generators_.size();
  390. printer->Print(
  391. "\n"
  392. "typedef struct $classname$__storage_ {\n"
  393. " uint32_t _has_storage_[$sizeof_has_storage$];\n",
  394. "classname", class_name_,
  395. "sizeof_has_storage", StrCat(sizeof_has_storage));
  396. printer->Indent();
  397. for (int i = 0; i < descriptor_->field_count(); i++) {
  398. field_generators_.get(size_order_fields[i])
  399. .GenerateFieldStorageDeclaration(printer);
  400. }
  401. printer->Outdent();
  402. printer->Print("} $classname$__storage_;\n\n", "classname", class_name_);
  403. printer->Print(
  404. "// This method is threadsafe because it is initially called\n"
  405. "// in +initialize for each subclass.\n"
  406. "+ (GPBDescriptor *)descriptor {\n"
  407. " static GPBDescriptor *descriptor = nil;\n"
  408. " if (!descriptor) {\n");
  409. TextFormatDecodeData text_format_decode_data;
  410. bool has_fields = descriptor_->field_count() > 0;
  411. bool need_defaults = field_generators_.DoesAnyFieldHaveNonZeroDefault();
  412. std::string field_description_type;
  413. if (need_defaults) {
  414. field_description_type = "GPBMessageFieldDescriptionWithDefault";
  415. } else {
  416. field_description_type = "GPBMessageFieldDescription";
  417. }
  418. if (has_fields) {
  419. printer->Indent();
  420. printer->Indent();
  421. printer->Print(
  422. "static $field_description_type$ fields[] = {\n",
  423. "field_description_type", field_description_type);
  424. printer->Indent();
  425. for (int i = 0; i < descriptor_->field_count(); ++i) {
  426. const FieldGenerator& field_generator =
  427. field_generators_.get(sorted_fields[i]);
  428. field_generator.GenerateFieldDescription(printer, need_defaults);
  429. if (field_generator.needs_textformat_name_support()) {
  430. text_format_decode_data.AddString(sorted_fields[i]->number(),
  431. field_generator.generated_objc_name(),
  432. field_generator.raw_field_name());
  433. }
  434. }
  435. printer->Outdent();
  436. printer->Print(
  437. "};\n");
  438. printer->Outdent();
  439. printer->Outdent();
  440. }
  441. std::map<std::string, std::string> vars;
  442. vars["classname"] = class_name_;
  443. vars["rootclassname"] = root_classname_;
  444. vars["fields"] = has_fields ? "fields" : "NULL";
  445. if (has_fields) {
  446. vars["fields_count"] =
  447. "(uint32_t)(sizeof(fields) / sizeof(" + field_description_type + "))";
  448. } else {
  449. vars["fields_count"] = "0";
  450. }
  451. std::vector<std::string> init_flags;
  452. init_flags.push_back("GPBDescriptorInitializationFlag_UsesClassRefs");
  453. init_flags.push_back("GPBDescriptorInitializationFlag_Proto3OptionalKnown");
  454. if (need_defaults) {
  455. init_flags.push_back("GPBDescriptorInitializationFlag_FieldsWithDefault");
  456. }
  457. if (descriptor_->options().message_set_wire_format()) {
  458. init_flags.push_back("GPBDescriptorInitializationFlag_WireFormat");
  459. }
  460. vars["init_flags"] = BuildFlagsString(FLAGTYPE_DESCRIPTOR_INITIALIZATION,
  461. init_flags);
  462. printer->Print(
  463. vars,
  464. " GPBDescriptor *localDescriptor =\n"
  465. " [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
  466. " rootClass:[$rootclassname$ class]\n"
  467. " file:$rootclassname$_FileDescriptor()\n"
  468. " fields:$fields$\n"
  469. " fieldCount:$fields_count$\n"
  470. " storageSize:sizeof($classname$__storage_)\n"
  471. " flags:$init_flags$];\n");
  472. if (!oneof_generators_.empty()) {
  473. printer->Print(
  474. " static const char *oneofs[] = {\n");
  475. for (const auto& generator : oneof_generators_) {
  476. printer->Print(" \"$name$\",\n", "name",
  477. generator->DescriptorName());
  478. }
  479. printer->Print(
  480. " };\n"
  481. " [localDescriptor setupOneofs:oneofs\n"
  482. " count:(uint32_t)(sizeof(oneofs) / sizeof(char*))\n"
  483. " firstHasIndex:$first_has_index$];\n",
  484. "first_has_index", oneof_generators_[0]->HasIndexAsString());
  485. }
  486. if (text_format_decode_data.num_entries() != 0) {
  487. const std::string text_format_data_str(text_format_decode_data.Data());
  488. printer->Print(
  489. "#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
  490. " static const char *extraTextFormatInfo =");
  491. static const int kBytesPerLine = 40; // allow for escaping
  492. for (int i = 0; i < text_format_data_str.size(); i += kBytesPerLine) {
  493. printer->Print(
  494. "\n \"$data$\"",
  495. "data", EscapeTrigraphs(
  496. CEscape(text_format_data_str.substr(i, kBytesPerLine))));
  497. }
  498. printer->Print(
  499. ";\n"
  500. " [localDescriptor setupExtraTextInfo:extraTextFormatInfo];\n"
  501. "#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n");
  502. }
  503. if (!sorted_extensions.empty()) {
  504. printer->Print(
  505. " static const GPBExtensionRange ranges[] = {\n");
  506. for (int i = 0; i < sorted_extensions.size(); i++) {
  507. printer->Print(" { .start = $start$, .end = $end$ },\n",
  508. "start", StrCat(sorted_extensions[i]->start),
  509. "end", StrCat(sorted_extensions[i]->end));
  510. }
  511. printer->Print(
  512. " };\n"
  513. " [localDescriptor setupExtensionRanges:ranges\n"
  514. " count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n");
  515. }
  516. if (descriptor_->containing_type() != NULL) {
  517. std::string containing_class = ClassName(descriptor_->containing_type());
  518. std::string parent_class_ref = ObjCClass(containing_class);
  519. printer->Print(
  520. " [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n",
  521. "parent_class_ref", parent_class_ref);
  522. }
  523. std::string suffix_added;
  524. ClassName(descriptor_, &suffix_added);
  525. if (!suffix_added.empty()) {
  526. printer->Print(
  527. " [localDescriptor setupMessageClassNameSuffix:@\"$suffix$\"];\n",
  528. "suffix", suffix_added);
  529. }
  530. printer->Print(
  531. " #if defined(DEBUG) && DEBUG\n"
  532. " NSAssert(descriptor == nil, @\"Startup recursed!\");\n"
  533. " #endif // DEBUG\n"
  534. " descriptor = localDescriptor;\n"
  535. " }\n"
  536. " return descriptor;\n"
  537. "}\n\n"
  538. "@end\n\n");
  539. if (!deprecated_attribute_.empty()) {
  540. printer->Print(
  541. "#pragma clang diagnostic pop\n"
  542. "\n");
  543. }
  544. for (int i = 0; i < descriptor_->field_count(); i++) {
  545. field_generators_.get(descriptor_->field(i))
  546. .GenerateCFunctionImplementations(printer);
  547. }
  548. for (const auto& generator : oneof_generators_) {
  549. generator->GenerateClearFunctionImplementation(printer);
  550. }
  551. }
  552. for (const auto& generator : enum_generators_) {
  553. generator->GenerateSource(printer);
  554. }
  555. for (const auto& generator : nested_message_generators_) {
  556. generator->GenerateSource(printer);
  557. }
  558. }
  559. } // namespace objectivec
  560. } // namespace compiler
  561. } // namespace protobuf
  562. } // namespace google