objectivec_message.cc 24 KB

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