PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/jni-build/jni/include/google/protobuf/src/google/protobuf/compiler/objectivec/objectivec_file.cc

https://gitlab.com/zharfi/GunSafety
C++ | 370 lines | 289 code | 38 blank | 43 comment | 45 complexity | e5088ed61704fe843bda7c9097d5cbea MD5 | raw file
  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 <google/protobuf/compiler/objectivec/objectivec_file.h>
  31. #include <google/protobuf/compiler/objectivec/objectivec_enum.h>
  32. #include <google/protobuf/compiler/objectivec/objectivec_extension.h>
  33. #include <google/protobuf/compiler/objectivec/objectivec_message.h>
  34. #include <google/protobuf/compiler/code_generator.h>
  35. #include <google/protobuf/io/printer.h>
  36. #include <google/protobuf/io/zero_copy_stream_impl.h>
  37. #include <google/protobuf/stubs/stl_util.h>
  38. #include <google/protobuf/stubs/strutil.h>
  39. #include <sstream>
  40. namespace google {
  41. namespace protobuf {
  42. // This is also found in GPBBootstrap.h, and needs to be kept in sync. It
  43. // is the version check done to ensure generated code works with the current
  44. // runtime being used.
  45. const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30000;
  46. namespace compiler {
  47. namespace objectivec {
  48. FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
  49. : file_(file),
  50. root_class_name_(FileClassName(file)),
  51. is_public_dep_(false),
  52. options_(options) {
  53. for (int i = 0; i < file_->enum_type_count(); i++) {
  54. EnumGenerator *generator = new EnumGenerator(file_->enum_type(i));
  55. enum_generators_.push_back(generator);
  56. }
  57. for (int i = 0; i < file_->message_type_count(); i++) {
  58. MessageGenerator *generator =
  59. new MessageGenerator(root_class_name_, file_->message_type(i), options_);
  60. message_generators_.push_back(generator);
  61. }
  62. for (int i = 0; i < file_->extension_count(); i++) {
  63. ExtensionGenerator *generator =
  64. new ExtensionGenerator(root_class_name_, file_->extension(i));
  65. extension_generators_.push_back(generator);
  66. }
  67. }
  68. FileGenerator::~FileGenerator() {
  69. STLDeleteContainerPointers(dependency_generators_.begin(),
  70. dependency_generators_.end());
  71. STLDeleteContainerPointers(enum_generators_.begin(), enum_generators_.end());
  72. STLDeleteContainerPointers(message_generators_.begin(),
  73. message_generators_.end());
  74. STLDeleteContainerPointers(extension_generators_.begin(),
  75. extension_generators_.end());
  76. }
  77. void FileGenerator::GenerateHeader(io::Printer *printer) {
  78. printer->Print(
  79. "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
  80. "// source: $filename$\n"
  81. "\n",
  82. "filename", file_->name());
  83. printer->Print(
  84. "#import \"GPBProtocolBuffers.h\"\n"
  85. "\n");
  86. // Add some verification that the generated code matches the source the
  87. // code is being compiled with.
  88. printer->Print(
  89. "#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != $protoc_gen_objc_version$\n"
  90. "#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.\n"
  91. "#endif\n"
  92. "\n",
  93. "protoc_gen_objc_version",
  94. SimpleItoa(GOOGLE_PROTOBUF_OBJC_GEN_VERSION));
  95. const vector<FileGenerator *> &dependency_generators = DependencyGenerators();
  96. for (vector<FileGenerator *>::const_iterator iter =
  97. dependency_generators.begin();
  98. iter != dependency_generators.end(); ++iter) {
  99. if ((*iter)->IsPublicDependency()) {
  100. printer->Print("#import \"$header$.pbobjc.h\"\n",
  101. "header", (*iter)->Path());
  102. }
  103. }
  104. printer->Print(
  105. "// @@protoc_insertion_point(imports)\n"
  106. "\n"
  107. "CF_EXTERN_C_BEGIN\n"
  108. "\n");
  109. set<string> fwd_decls;
  110. for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
  111. iter != message_generators_.end(); ++iter) {
  112. (*iter)->DetermineForwardDeclarations(&fwd_decls);
  113. }
  114. for (set<string>::const_iterator i(fwd_decls.begin());
  115. i != fwd_decls.end(); ++i) {
  116. printer->Print("$value$;\n", "value", *i);
  117. }
  118. if (fwd_decls.begin() != fwd_decls.end()) {
  119. printer->Print("\n");
  120. }
  121. printer->Print(
  122. "NS_ASSUME_NONNULL_BEGIN\n"
  123. "\n");
  124. // need to write out all enums first
  125. for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin();
  126. iter != enum_generators_.end(); ++iter) {
  127. (*iter)->GenerateHeader(printer);
  128. }
  129. for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
  130. iter != message_generators_.end(); ++iter) {
  131. (*iter)->GenerateEnumHeader(printer);
  132. }
  133. // For extensions to chain together, the Root gets created even if there
  134. // are no extensions.
  135. printer->Print(
  136. "#pragma mark - $root_class_name$\n"
  137. "\n"
  138. "@interface $root_class_name$ : GPBRootObject\n"
  139. "\n"
  140. "// The base class provides:\n"
  141. "// + (GPBExtensionRegistry *)extensionRegistry;\n"
  142. "// which is an GPBExtensionRegistry that includes all the extensions defined by\n"
  143. "// this file and all files that it depends on.\n"
  144. "\n"
  145. "@end\n"
  146. "\n",
  147. "root_class_name", root_class_name_);
  148. if (extension_generators_.size() > 0) {
  149. // The dynamic methods block is only needed if there are extensions.
  150. printer->Print(
  151. "@interface $root_class_name$ (DynamicMethods)\n",
  152. "root_class_name", root_class_name_);
  153. for (vector<ExtensionGenerator *>::iterator iter =
  154. extension_generators_.begin();
  155. iter != extension_generators_.end(); ++iter) {
  156. (*iter)->GenerateMembersHeader(printer);
  157. }
  158. printer->Print("@end\n\n");
  159. } // extension_generators_.size() > 0
  160. for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
  161. iter != message_generators_.end(); ++iter) {
  162. (*iter)->GenerateMessageHeader(printer);
  163. }
  164. printer->Print(
  165. "NS_ASSUME_NONNULL_END\n"
  166. "\n"
  167. "CF_EXTERN_C_END\n"
  168. "\n"
  169. "// @@protoc_insertion_point(global_scope)\n");
  170. }
  171. void FileGenerator::GenerateSource(io::Printer *printer) {
  172. printer->Print(
  173. "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
  174. "// source: $filename$\n"
  175. "\n",
  176. "filename", file_->name());
  177. string header_file = Path() + ".pbobjc.h";
  178. printer->Print(
  179. "#import \"GPBProtocolBuffers_RuntimeSupport.h\"\n"
  180. "#import \"$header_file$\"\n",
  181. "header_file", header_file);
  182. const vector<FileGenerator *> &dependency_generators =
  183. DependencyGenerators();
  184. for (vector<FileGenerator *>::const_iterator iter =
  185. dependency_generators.begin();
  186. iter != dependency_generators.end(); ++iter) {
  187. if (!(*iter)->IsPublicDependency()) {
  188. printer->Print("#import \"$header$.pbobjc.h\"\n",
  189. "header", (*iter)->Path());
  190. }
  191. }
  192. printer->Print(
  193. "// @@protoc_insertion_point(imports)\n"
  194. "\n");
  195. printer->Print(
  196. "#pragma mark - $root_class_name$\n"
  197. "\n"
  198. "@implementation $root_class_name$\n\n",
  199. "root_class_name", root_class_name_);
  200. // Generate the extension initialization structures for the top level and
  201. // any nested messages.
  202. ostringstream extensions_stringstream;
  203. if (file_->extension_count() + file_->message_type_count() > 0) {
  204. io::OstreamOutputStream extensions_outputstream(&extensions_stringstream);
  205. io::Printer extensions_printer(&extensions_outputstream, '$');
  206. for (vector<ExtensionGenerator *>::iterator iter =
  207. extension_generators_.begin();
  208. iter != extension_generators_.end(); ++iter) {
  209. (*iter)->GenerateStaticVariablesInitialization(&extensions_printer);
  210. }
  211. for (vector<MessageGenerator *>::iterator iter =
  212. message_generators_.begin();
  213. iter != message_generators_.end(); ++iter) {
  214. (*iter)->GenerateStaticVariablesInitialization(&extensions_printer);
  215. }
  216. extensions_stringstream.flush();
  217. }
  218. // If there were any extensions or this file has any dependencies, output
  219. // a registry to override to create the file specific registry.
  220. const string& extensions_str = extensions_stringstream.str();
  221. if (extensions_str.length() > 0 || file_->dependency_count() > 0) {
  222. printer->Print(
  223. "+ (GPBExtensionRegistry*)extensionRegistry {\n"
  224. " // This is called by +initialize so there is no need to worry\n"
  225. " // about thread safety and initialization of registry.\n"
  226. " static GPBExtensionRegistry* registry = nil;\n"
  227. " if (!registry) {\n"
  228. " GPBDebugCheckRuntimeVersion();\n"
  229. " registry = [[GPBExtensionRegistry alloc] init];\n");
  230. printer->Indent();
  231. printer->Indent();
  232. if (extensions_str.length() > 0) {
  233. printer->Print(
  234. "static GPBExtensionDescription descriptions[] = {\n");
  235. printer->Indent();
  236. printer->Print(extensions_str.c_str());
  237. printer->Outdent();
  238. printer->Print(
  239. "};\n"
  240. "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) {\n"
  241. " GPBExtensionDescriptor *extension =\n"
  242. " [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&descriptions[i]];\n"
  243. " [registry addExtension:extension];\n"
  244. " [self globallyRegisterExtension:extension];\n"
  245. " [extension release];\n"
  246. "}\n");
  247. }
  248. const vector<FileGenerator *> &dependency_generators =
  249. DependencyGenerators();
  250. for (vector<FileGenerator *>::const_iterator iter =
  251. dependency_generators.begin();
  252. iter != dependency_generators.end(); ++iter) {
  253. printer->Print(
  254. "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
  255. "dependency", (*iter)->RootClassName());
  256. }
  257. printer->Outdent();
  258. printer->Outdent();
  259. printer->Print(
  260. " }\n"
  261. " return registry;\n"
  262. "}\n"
  263. "\n");
  264. }
  265. printer->Print("@end\n\n");
  266. // File descriptor only needed if there are messages to use it.
  267. if (message_generators_.size() > 0) {
  268. string syntax;
  269. switch (file_->syntax()) {
  270. case FileDescriptor::SYNTAX_UNKNOWN:
  271. syntax = "GPBFileSyntaxUnknown";
  272. break;
  273. case FileDescriptor::SYNTAX_PROTO2:
  274. syntax = "GPBFileSyntaxProto2";
  275. break;
  276. case FileDescriptor::SYNTAX_PROTO3:
  277. syntax = "GPBFileSyntaxProto3";
  278. break;
  279. }
  280. printer->Print(
  281. "#pragma mark - $root_class_name$_FileDescriptor\n"
  282. "\n"
  283. "static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n"
  284. " // This is called by +initialize so there is no need to worry\n"
  285. " // about thread safety of the singleton.\n"
  286. " static GPBFileDescriptor *descriptor = NULL;\n"
  287. " if (!descriptor) {\n"
  288. " GPBDebugCheckRuntimeVersion();\n"
  289. " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
  290. " syntax:$syntax$];\n"
  291. " }\n"
  292. " return descriptor;\n"
  293. "}\n"
  294. "\n",
  295. "root_class_name", root_class_name_,
  296. "package", file_->package(),
  297. "syntax", syntax);
  298. }
  299. for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin();
  300. iter != enum_generators_.end(); ++iter) {
  301. (*iter)->GenerateSource(printer);
  302. }
  303. for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
  304. iter != message_generators_.end(); ++iter) {
  305. (*iter)->GenerateSource(printer);
  306. }
  307. printer->Print(
  308. "\n"
  309. "// @@protoc_insertion_point(global_scope)\n");
  310. }
  311. const string FileGenerator::Path() const { return FilePath(file_); }
  312. const vector<FileGenerator *> &FileGenerator::DependencyGenerators() {
  313. if (file_->dependency_count() != dependency_generators_.size()) {
  314. set<string> public_import_names;
  315. for (int i = 0; i < file_->public_dependency_count(); i++) {
  316. public_import_names.insert(file_->public_dependency(i)->name());
  317. }
  318. for (int i = 0; i < file_->dependency_count(); i++) {
  319. FileGenerator *generator =
  320. new FileGenerator(file_->dependency(i), options_);
  321. const string& name = file_->dependency(i)->name();
  322. bool public_import = (public_import_names.count(name) != 0);
  323. generator->SetIsPublicDependency(public_import);
  324. dependency_generators_.push_back(generator);
  325. }
  326. }
  327. return dependency_generators_;
  328. }
  329. } // namespace objectivec
  330. } // namespace compiler
  331. } // namespace protobuf
  332. } // namespace google