objectivec_field.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  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 <iostream>
  31. #include <google/protobuf/compiler/objectivec/objectivec_field.h>
  32. #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
  33. #include <google/protobuf/compiler/objectivec/objectivec_enum_field.h>
  34. #include <google/protobuf/compiler/objectivec/objectivec_map_field.h>
  35. #include <google/protobuf/compiler/objectivec/objectivec_message_field.h>
  36. #include <google/protobuf/compiler/objectivec/objectivec_primitive_field.h>
  37. #include <google/protobuf/io/printer.h>
  38. #include <google/protobuf/wire_format.h>
  39. #include <google/protobuf/stubs/common.h>
  40. #include <google/protobuf/stubs/strutil.h>
  41. namespace google {
  42. namespace protobuf {
  43. namespace compiler {
  44. namespace objectivec {
  45. namespace {
  46. void SetCommonFieldVariables(const FieldDescriptor* descriptor,
  47. map<string, string>* variables) {
  48. string camel_case_name = FieldName(descriptor);
  49. string raw_field_name;
  50. if (descriptor->type() == FieldDescriptor::TYPE_GROUP) {
  51. raw_field_name = descriptor->message_type()->name();
  52. } else {
  53. raw_field_name = descriptor->name();
  54. }
  55. // The logic here has to match -[GGPBFieldDescriptor textFormatName].
  56. const string un_camel_case_name(
  57. UnCamelCaseFieldName(camel_case_name, descriptor));
  58. const bool needs_custom_name = (raw_field_name != un_camel_case_name);
  59. SourceLocation location;
  60. if (descriptor->GetSourceLocation(&location)) {
  61. (*variables)["comments"] = BuildCommentsString(location);
  62. } else {
  63. (*variables)["comments"] = "\n";
  64. }
  65. const string& classname = ClassName(descriptor->containing_type());
  66. (*variables)["classname"] = classname;
  67. (*variables)["name"] = camel_case_name;
  68. const string& capitalized_name = FieldNameCapitalized(descriptor);
  69. (*variables)["capitalized_name"] = capitalized_name;
  70. (*variables)["raw_field_name"] = raw_field_name;
  71. (*variables)["field_number_name"] =
  72. classname + "_FieldNumber_" + capitalized_name;
  73. (*variables)["field_number"] = SimpleItoa(descriptor->number());
  74. (*variables)["field_type"] = GetCapitalizedType(descriptor);
  75. (*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor);
  76. std::vector<string> field_flags;
  77. if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated");
  78. if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired");
  79. if (descriptor->is_optional()) field_flags.push_back("GPBFieldOptional");
  80. if (descriptor->is_packed()) field_flags.push_back("GPBFieldPacked");
  81. // ObjC custom flags.
  82. if (descriptor->has_default_value())
  83. field_flags.push_back("GPBFieldHasDefaultValue");
  84. if (needs_custom_name) field_flags.push_back("GPBFieldTextFormatNameCustom");
  85. if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
  86. field_flags.push_back("GPBFieldHasEnumDescriptor");
  87. }
  88. (*variables)["fieldflags"] = BuildFlagsString(field_flags);
  89. (*variables)["default"] = DefaultValue(descriptor);
  90. (*variables)["default_name"] = GPBGenericValueFieldName(descriptor);
  91. (*variables)["dataTypeSpecific_name"] = "className";
  92. (*variables)["dataTypeSpecific_value"] = "NULL";
  93. (*variables)["storage_offset_value"] =
  94. "(uint32_t)offsetof(" + classname + "__storage_, " + camel_case_name + ")";
  95. (*variables)["storage_offset_comment"] = "";
  96. // Clear some common things so they can be set just when needed.
  97. (*variables)["storage_attribute"] = "";
  98. }
  99. } // namespace
  100. FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
  101. const Options& options) {
  102. FieldGenerator* result = NULL;
  103. if (field->is_repeated()) {
  104. switch (GetObjectiveCType(field)) {
  105. case OBJECTIVECTYPE_MESSAGE: {
  106. if (field->is_map()) {
  107. result = new MapFieldGenerator(field, options);
  108. } else {
  109. result = new RepeatedMessageFieldGenerator(field, options);
  110. }
  111. break;
  112. }
  113. case OBJECTIVECTYPE_ENUM:
  114. result = new RepeatedEnumFieldGenerator(field, options);
  115. break;
  116. default:
  117. result = new RepeatedPrimitiveFieldGenerator(field, options);
  118. break;
  119. }
  120. } else {
  121. switch (GetObjectiveCType(field)) {
  122. case OBJECTIVECTYPE_MESSAGE: {
  123. result = new MessageFieldGenerator(field, options);
  124. break;
  125. }
  126. case OBJECTIVECTYPE_ENUM:
  127. result = new EnumFieldGenerator(field, options);
  128. break;
  129. default:
  130. if (IsReferenceType(field)) {
  131. result = new PrimitiveObjFieldGenerator(field, options);
  132. } else {
  133. result = new PrimitiveFieldGenerator(field, options);
  134. }
  135. break;
  136. }
  137. }
  138. result->FinishInitialization();
  139. return result;
  140. }
  141. FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor,
  142. const Options& options)
  143. : descriptor_(descriptor) {
  144. SetCommonFieldVariables(descriptor, &variables_);
  145. }
  146. FieldGenerator::~FieldGenerator() {}
  147. void FieldGenerator::GenerateFieldNumberConstant(io::Printer* printer) const {
  148. printer->Print(
  149. variables_,
  150. "$field_number_name$ = $field_number$,\n");
  151. }
  152. void FieldGenerator::GenerateCFunctionDeclarations(
  153. io::Printer* printer) const {
  154. // Nothing
  155. }
  156. void FieldGenerator::GenerateCFunctionImplementations(
  157. io::Printer* printer) const {
  158. // Nothing
  159. }
  160. void FieldGenerator::DetermineForwardDeclarations(
  161. set<string>* fwd_decls) const {
  162. // Nothing
  163. }
  164. void FieldGenerator::GenerateFieldDescription(
  165. io::Printer* printer, bool include_default) const {
  166. // Printed in the same order as the structure decl.
  167. if (include_default) {
  168. printer->Print(
  169. variables_,
  170. "{\n"
  171. " .defaultValue.$default_name$ = $default$,\n"
  172. " .core.name = \"$name$\",\n"
  173. " .core.dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n"
  174. " .core.number = $field_number_name$,\n"
  175. " .core.hasIndex = $has_index$,\n"
  176. " .core.offset = $storage_offset_value$,$storage_offset_comment$\n"
  177. " .core.flags = $fieldflags$,\n"
  178. " .core.dataType = GPBDataType$field_type$,\n"
  179. "},\n");
  180. } else {
  181. printer->Print(
  182. variables_,
  183. "{\n"
  184. " .name = \"$name$\",\n"
  185. " .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n"
  186. " .number = $field_number_name$,\n"
  187. " .hasIndex = $has_index$,\n"
  188. " .offset = $storage_offset_value$,$storage_offset_comment$\n"
  189. " .flags = $fieldflags$,\n"
  190. " .dataType = GPBDataType$field_type$,\n"
  191. "},\n");
  192. }
  193. }
  194. void FieldGenerator::SetRuntimeHasBit(int has_index) {
  195. variables_["has_index"] = SimpleItoa(has_index);
  196. }
  197. void FieldGenerator::SetNoHasBit(void) {
  198. variables_["has_index"] = "GPBNoHasBit";
  199. }
  200. int FieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
  201. return 0;
  202. }
  203. void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) {
  204. // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
  205. // error cases, so it seems to be ok to use as a back door for errors.
  206. cerr << "Error: should have overriden SetExtraRuntimeHasBitsBase()." << endl;
  207. cerr.flush();
  208. abort();
  209. }
  210. void FieldGenerator::SetOneofIndexBase(int index_base) {
  211. if (descriptor_->containing_oneof() != NULL) {
  212. int index = descriptor_->containing_oneof()->index() + index_base;
  213. // Flip the sign to mark it as a oneof.
  214. variables_["has_index"] = SimpleItoa(-index);
  215. }
  216. }
  217. void FieldGenerator::FinishInitialization(void) {
  218. // If "property_type" wasn't set, make it "storage_type".
  219. if ((variables_.find("property_type") == variables_.end()) &&
  220. (variables_.find("storage_type") != variables_.end())) {
  221. variables_["property_type"] = variable("storage_type");
  222. }
  223. }
  224. SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor,
  225. const Options& options)
  226. : FieldGenerator(descriptor, options) {
  227. // Nothing
  228. }
  229. SingleFieldGenerator::~SingleFieldGenerator() {}
  230. void SingleFieldGenerator::GenerateFieldStorageDeclaration(
  231. io::Printer* printer) const {
  232. printer->Print(variables_, "$storage_type$ $name$;\n");
  233. }
  234. void SingleFieldGenerator::GeneratePropertyDeclaration(
  235. io::Printer* printer) const {
  236. printer->Print(variables_, "$comments$");
  237. printer->Print(
  238. variables_,
  239. "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n"
  240. "\n");
  241. if (WantsHasProperty()) {
  242. printer->Print(
  243. variables_,
  244. "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
  245. }
  246. }
  247. void SingleFieldGenerator::GeneratePropertyImplementation(
  248. io::Printer* printer) const {
  249. if (WantsHasProperty()) {
  250. printer->Print(variables_, "@dynamic has$capitalized_name$, $name$;\n");
  251. } else {
  252. printer->Print(variables_, "@dynamic $name$;\n");
  253. }
  254. }
  255. bool SingleFieldGenerator::WantsHasProperty(void) const {
  256. if (descriptor_->containing_oneof() != NULL) {
  257. // If in a oneof, it uses the oneofcase instead of a has bit.
  258. return false;
  259. }
  260. if (HasFieldPresence(descriptor_->file())) {
  261. // In proto1/proto2, every field has a has_$name$() method.
  262. return true;
  263. }
  264. return false;
  265. }
  266. bool SingleFieldGenerator::RuntimeUsesHasBit(void) const {
  267. if (descriptor_->containing_oneof() != NULL) {
  268. // The oneof tracks what is set instead.
  269. return false;
  270. }
  271. return true;
  272. }
  273. ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor,
  274. const Options& options)
  275. : SingleFieldGenerator(descriptor, options) {
  276. variables_["property_storage_attribute"] = "strong";
  277. if (IsRetainedName(variables_["name"])) {
  278. variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED";
  279. }
  280. }
  281. ObjCObjFieldGenerator::~ObjCObjFieldGenerator() {}
  282. void ObjCObjFieldGenerator::GenerateFieldStorageDeclaration(
  283. io::Printer* printer) const {
  284. printer->Print(variables_, "$storage_type$ *$name$;\n");
  285. }
  286. void ObjCObjFieldGenerator::GeneratePropertyDeclaration(
  287. io::Printer* printer) const {
  288. // Differs from SingleFieldGenerator::GeneratePropertyDeclaration() in that
  289. // it uses pointers and deals with Objective C's rules around storage name
  290. // conventions (init*, new*, etc.)
  291. printer->Print(variables_, "$comments$");
  292. printer->Print(
  293. variables_,
  294. "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n");
  295. if (WantsHasProperty()) {
  296. printer->Print(
  297. variables_,
  298. "/// Test to see if @c $name$ has been set.\n"
  299. "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
  300. }
  301. if (IsInitName(variables_.find("name")->second)) {
  302. // If property name starts with init we need to annotate it to get past ARC.
  303. // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
  304. printer->Print(variables_,
  305. "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
  306. }
  307. printer->Print("\n");
  308. }
  309. RepeatedFieldGenerator::RepeatedFieldGenerator(
  310. const FieldDescriptor* descriptor, const Options& options)
  311. : ObjCObjFieldGenerator(descriptor, options) {
  312. // Default to no comment and let the cases needing it fill it in.
  313. variables_["array_comment"] = "";
  314. }
  315. RepeatedFieldGenerator::~RepeatedFieldGenerator() {}
  316. void RepeatedFieldGenerator::FinishInitialization(void) {
  317. FieldGenerator::FinishInitialization();
  318. if (variables_.find("array_property_type") == variables_.end()) {
  319. variables_["array_property_type"] = variable("array_storage_type");
  320. }
  321. }
  322. void RepeatedFieldGenerator::GenerateFieldStorageDeclaration(
  323. io::Printer* printer) const {
  324. printer->Print(variables_, "$array_storage_type$ *$name$;\n");
  325. }
  326. void RepeatedFieldGenerator::GeneratePropertyImplementation(
  327. io::Printer* printer) const {
  328. printer->Print(variables_, "@dynamic $name$, $name$_Count;\n");
  329. }
  330. void RepeatedFieldGenerator::GeneratePropertyDeclaration(
  331. io::Printer* printer) const {
  332. // Repeated fields don't need the has* properties, but they do expose a
  333. // *Count (to check without autocreation). So for the field property we need
  334. // the same logic as ObjCObjFieldGenerator::GeneratePropertyDeclaration() for
  335. // dealing with needing Objective C's rules around storage name conventions
  336. // (init*, new*, etc.)
  337. printer->Print(
  338. variables_,
  339. "$comments$"
  340. "$array_comment$"
  341. "@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"
  342. "/// The number of items in @c $name$ without causing the array to be created.\n"
  343. "@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n");
  344. if (IsInitName(variables_.find("name")->second)) {
  345. // If property name starts with init we need to annotate it to get past ARC.
  346. // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
  347. printer->Print(variables_,
  348. "- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
  349. }
  350. printer->Print("\n");
  351. }
  352. bool RepeatedFieldGenerator::WantsHasProperty(void) const {
  353. // Consumer check the array size/existance rather than a has bit.
  354. return false;
  355. }
  356. bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const {
  357. return false; // The array having anything is what is used.
  358. }
  359. FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
  360. const Options& options)
  361. : descriptor_(descriptor),
  362. field_generators_(
  363. new scoped_ptr<FieldGenerator>[descriptor->field_count()]),
  364. extension_generators_(
  365. new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) {
  366. // Construct all the FieldGenerators.
  367. for (int i = 0; i < descriptor->field_count(); i++) {
  368. field_generators_[i].reset(
  369. FieldGenerator::Make(descriptor->field(i), options));
  370. }
  371. for (int i = 0; i < descriptor->extension_count(); i++) {
  372. extension_generators_[i].reset(
  373. FieldGenerator::Make(descriptor->extension(i), options));
  374. }
  375. }
  376. FieldGeneratorMap::~FieldGeneratorMap() {}
  377. const FieldGenerator& FieldGeneratorMap::get(
  378. const FieldDescriptor* field) const {
  379. GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
  380. return *field_generators_[field->index()];
  381. }
  382. const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
  383. return *extension_generators_[index];
  384. }
  385. int FieldGeneratorMap::CalculateHasBits(void) {
  386. int total_bits = 0;
  387. for (int i = 0; i < descriptor_->field_count(); i++) {
  388. if (field_generators_[i]->RuntimeUsesHasBit()) {
  389. field_generators_[i]->SetRuntimeHasBit(total_bits);
  390. ++total_bits;
  391. } else {
  392. field_generators_[i]->SetNoHasBit();
  393. }
  394. int extra_bits = field_generators_[i]->ExtraRuntimeHasBitsNeeded();
  395. if (extra_bits) {
  396. field_generators_[i]->SetExtraRuntimeHasBitsBase(total_bits);
  397. total_bits += extra_bits;
  398. }
  399. }
  400. return total_bits;
  401. }
  402. void FieldGeneratorMap::SetOneofIndexBase(int index_base) {
  403. for (int i = 0; i < descriptor_->field_count(); i++) {
  404. field_generators_[i]->SetOneofIndexBase(index_base);
  405. }
  406. }
  407. bool FieldGeneratorMap::DoesAnyFieldHaveNonZeroDefault(void) const {
  408. for (int i = 0; i < descriptor_->field_count(); i++) {
  409. if (HasNonZeroDefaultValue(descriptor_->field(i))) {
  410. return true;
  411. }
  412. }
  413. return false;
  414. }
  415. } // namespace objectivec
  416. } // namespace compiler
  417. } // namespace protobuf
  418. } // namespace google