Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_file.cc

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 19 matching lines...) Expand all
30 30
31 #include <google/protobuf/compiler/objectivec/objectivec_file.h> 31 #include <google/protobuf/compiler/objectivec/objectivec_file.h>
32 #include <google/protobuf/compiler/objectivec/objectivec_enum.h> 32 #include <google/protobuf/compiler/objectivec/objectivec_enum.h>
33 #include <google/protobuf/compiler/objectivec/objectivec_extension.h> 33 #include <google/protobuf/compiler/objectivec/objectivec_extension.h>
34 #include <google/protobuf/compiler/objectivec/objectivec_message.h> 34 #include <google/protobuf/compiler/objectivec/objectivec_message.h>
35 #include <google/protobuf/compiler/code_generator.h> 35 #include <google/protobuf/compiler/code_generator.h>
36 #include <google/protobuf/io/printer.h> 36 #include <google/protobuf/io/printer.h>
37 #include <google/protobuf/io/zero_copy_stream_impl.h> 37 #include <google/protobuf/io/zero_copy_stream_impl.h>
38 #include <google/protobuf/stubs/stl_util.h> 38 #include <google/protobuf/stubs/stl_util.h>
39 #include <google/protobuf/stubs/strutil.h> 39 #include <google/protobuf/stubs/strutil.h>
40 #include <algorithm> // std::find()
41 #include <iostream>
40 #include <sstream> 42 #include <sstream>
41 43
44 // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
45 // error cases, so it seems to be ok to use as a back door for errors.
46
42 namespace google { 47 namespace google {
43 namespace protobuf { 48 namespace protobuf {
44
45 // This is also found in GPBBootstrap.h, and needs to be kept in sync. It
46 // is the version check done to ensure generated code works with the current
47 // runtime being used.
48 const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30001;
49
50 namespace compiler { 49 namespace compiler {
51 namespace objectivec { 50 namespace objectivec {
52 51
52 namespace {
53
54 // This is also found in GPBBootstrap.h, and needs to be kept in sync.
55 const int32 GOOGLE_PROTOBUF_OBJC_VERSION = 30002;
56
57 const char* kHeaderExtension = ".pbobjc.h";
58
59 // Checks if a message contains any extension definitions (on the message or
60 // a nested message under it).
61 bool MessageContainsExtensions(const Descriptor* message) {
62 if (message->extension_count() > 0) {
63 return true;
64 }
65 for (int i = 0; i < message->nested_type_count(); i++) {
66 if (MessageContainsExtensions(message->nested_type(i))) {
67 return true;
68 }
69 }
70 return false;
71 }
72
73 // Checks if the file contains any extensions definitions (at the root or
74 // nested under a message).
75 bool FileContainsExtensions(const FileDescriptor* file) {
76 if (file->extension_count() > 0) {
77 return true;
78 }
79 for (int i = 0; i < file->message_type_count(); i++) {
80 if (MessageContainsExtensions(file->message_type(i))) {
81 return true;
82 }
83 }
84 return false;
85 }
86
87 // Helper for CollectMinimalFileDepsContainingExtensionsWorker that marks all
88 // deps as visited and prunes them from the needed files list.
89 void PruneFileAndDepsMarkingAsVisited(
90 const FileDescriptor* file,
91 vector<const FileDescriptor*>* files,
92 set<const FileDescriptor*>* files_visited) {
93 vector<const FileDescriptor*>::iterator iter =
94 std::find(files->begin(), files->end(), file);
95 if (iter != files->end()) {
96 files->erase(iter);
97 }
98 files_visited->insert(file);
99 for (int i = 0; i < file->dependency_count(); i++) {
100 PruneFileAndDepsMarkingAsVisited(file->dependency(i), files, files_visited);
101 }
102 }
103
104 // Helper for CollectMinimalFileDepsContainingExtensions.
105 void CollectMinimalFileDepsContainingExtensionsWorker(
106 const FileDescriptor* file,
107 vector<const FileDescriptor*>* files,
108 set<const FileDescriptor*>* files_visited) {
109 if (files_visited->find(file) != files_visited->end()) {
110 return;
111 }
112 files_visited->insert(file);
113
114 if (FileContainsExtensions(file)) {
115 files->push_back(file);
116 for (int i = 0; i < file->dependency_count(); i++) {
117 const FileDescriptor* dep = file->dependency(i);
118 PruneFileAndDepsMarkingAsVisited(dep, files, files_visited);
119 }
120 } else {
121 for (int i = 0; i < file->dependency_count(); i++) {
122 const FileDescriptor* dep = file->dependency(i);
123 CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
124 files_visited);
125 }
126 }
127 }
128
129 // Collect the deps of the given file that contain extensions. This can be used to
130 // create the chain of roots that need to be wired together.
131 //
132 // NOTE: If any changes are made to this and the supporting functions, you will
133 // need to manually validate what the generated code is for the test files:
134 // objectivec/Tests/unittest_extension_chain_*.proto
135 // There are comments about what the expected code should be line and limited
136 // testing objectivec/Tests/GPBUnittestProtos2.m around compilation (#imports
137 // specifically).
138 void CollectMinimalFileDepsContainingExtensions(
139 const FileDescriptor* file,
140 vector<const FileDescriptor*>* files) {
141 set<const FileDescriptor*> files_visited;
142 for (int i = 0; i < file->dependency_count(); i++) {
143 const FileDescriptor* dep = file->dependency(i);
144 CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
145 &files_visited);
146 }
147 }
148
149 bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) {
150 for (int i = 0; i < file->dependency_count(); i++) {
151 if (dep == file->dependency(i)) {
152 return true;
153 }
154 }
155 return false;
156 }
157
158 } // namespace
159
53 FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options) 160 FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
54 : file_(file), 161 : file_(file),
55 root_class_name_(FileClassName(file)), 162 root_class_name_(FileClassName(file)),
56 is_public_dep_(false),
57 options_(options) { 163 options_(options) {
58 for (int i = 0; i < file_->enum_type_count(); i++) { 164 for (int i = 0; i < file_->enum_type_count(); i++) {
59 EnumGenerator *generator = new EnumGenerator(file_->enum_type(i)); 165 EnumGenerator *generator = new EnumGenerator(file_->enum_type(i));
60 enum_generators_.push_back(generator); 166 enum_generators_.push_back(generator);
61 } 167 }
62 for (int i = 0; i < file_->message_type_count(); i++) { 168 for (int i = 0; i < file_->message_type_count(); i++) {
63 MessageGenerator *generator = 169 MessageGenerator *generator =
64 new MessageGenerator(root_class_name_, file_->message_type(i), options_) ; 170 new MessageGenerator(root_class_name_, file_->message_type(i), options_) ;
65 message_generators_.push_back(generator); 171 message_generators_.push_back(generator);
66 } 172 }
67 for (int i = 0; i < file_->extension_count(); i++) { 173 for (int i = 0; i < file_->extension_count(); i++) {
68 ExtensionGenerator *generator = 174 ExtensionGenerator *generator =
69 new ExtensionGenerator(root_class_name_, file_->extension(i)); 175 new ExtensionGenerator(root_class_name_, file_->extension(i));
70 extension_generators_.push_back(generator); 176 extension_generators_.push_back(generator);
71 } 177 }
72 } 178 }
73 179
74 FileGenerator::~FileGenerator() { 180 FileGenerator::~FileGenerator() {
75 STLDeleteContainerPointers(dependency_generators_.begin(),
76 dependency_generators_.end());
77 STLDeleteContainerPointers(enum_generators_.begin(), enum_generators_.end()); 181 STLDeleteContainerPointers(enum_generators_.begin(), enum_generators_.end());
78 STLDeleteContainerPointers(message_generators_.begin(), 182 STLDeleteContainerPointers(message_generators_.begin(),
79 message_generators_.end()); 183 message_generators_.end());
80 STLDeleteContainerPointers(extension_generators_.begin(), 184 STLDeleteContainerPointers(extension_generators_.begin(),
81 extension_generators_.end()); 185 extension_generators_.end());
82 } 186 }
83 187
84 void FileGenerator::GenerateHeader(io::Printer *printer) { 188 void FileGenerator::GenerateHeader(io::Printer *printer) {
85 printer->Print( 189 PrintFileRuntimePreamble(printer, "GPBProtocolBuffers.h");
86 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
87 "// source: $filename$\n"
88 "\n",
89 "filename", file_->name());
90
91 printer->Print(
92 "#import \"GPBProtocolBuffers.h\"\n"
93 "\n");
94 190
95 // Add some verification that the generated code matches the source the 191 // Add some verification that the generated code matches the source the
96 // code is being compiled with. 192 // code is being compiled with.
193 // NOTE: This captures the raw numeric values at the time the generator was
194 // compiled, since that will be the versions for the ObjC runtime at that
195 // time. The constants in the generated code will then get their values at
196 // at compile time (so checking against the headers being used to compile).
97 printer->Print( 197 printer->Print(
98 "#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != $protoc_gen_objc_version$\n" 198 "#if GOOGLE_PROTOBUF_OBJC_VERSION < $google_protobuf_objc_version$\n"
99 "#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.\n" 199 "#error This file was generated by a newer version of protoc which is inco mpatible with your Protocol Buffer library sources.\n"
200 "#endif\n"
201 "#if $google_protobuf_objc_version$ < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_V ERSION\n"
202 "#error This file was generated by an older version of protoc which is inc ompatible with your Protocol Buffer library sources.\n"
100 "#endif\n" 203 "#endif\n"
101 "\n", 204 "\n",
102 "protoc_gen_objc_version", 205 "google_protobuf_objc_version", SimpleItoa(GOOGLE_PROTOBUF_OBJC_VERSION));
103 SimpleItoa(GOOGLE_PROTOBUF_OBJC_GEN_VERSION));
104 206
105 const vector<FileGenerator *> &dependency_generators = DependencyGenerators(); 207 // #import any headers for "public imports" in the proto file.
106 for (vector<FileGenerator *>::const_iterator iter = 208 {
107 dependency_generators.begin(); 209 ImportWriter import_writer(
108 iter != dependency_generators.end(); ++iter) { 210 options_.generate_for_named_framework,
109 if ((*iter)->IsPublicDependency()) { 211 options_.named_framework_to_proto_path_mappings_path);
110 printer->Print("#import \"$header$.pbobjc.h\"\n", 212 const string header_extension(kHeaderExtension);
111 "header", (*iter)->Path()); 213 for (int i = 0; i < file_->public_dependency_count(); i++) {
214 import_writer.AddFile(file_->public_dependency(i), header_extension);
112 } 215 }
216 import_writer.Print(printer);
113 } 217 }
114 218
219 // Note:
220 // deprecated-declarations suppression is only needed if some place in this
221 // proto file is something deprecated or if it references something from
222 // another file that is deprecated.
115 printer->Print( 223 printer->Print(
116 "// @@protoc_insertion_point(imports)\n" 224 "// @@protoc_insertion_point(imports)\n"
117 "\n" 225 "\n"
118 "#pragma clang diagnostic push\n" 226 "#pragma clang diagnostic push\n"
119 "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n" 227 "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"
120 "\n" 228 "\n"
121 "CF_EXTERN_C_BEGIN\n" 229 "CF_EXTERN_C_BEGIN\n"
122 "\n"); 230 "\n");
123 231
124 set<string> fwd_decls; 232 set<string> fwd_decls;
(...skipping 22 matching lines...) Expand all
147 for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); 255 for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
148 iter != message_generators_.end(); ++iter) { 256 iter != message_generators_.end(); ++iter) {
149 (*iter)->GenerateEnumHeader(printer); 257 (*iter)->GenerateEnumHeader(printer);
150 } 258 }
151 259
152 // For extensions to chain together, the Root gets created even if there 260 // For extensions to chain together, the Root gets created even if there
153 // are no extensions. 261 // are no extensions.
154 printer->Print( 262 printer->Print(
155 "#pragma mark - $root_class_name$\n" 263 "#pragma mark - $root_class_name$\n"
156 "\n" 264 "\n"
157 "/// Exposes the extension registry for this file.\n" 265 "/**\n"
158 "///\n" 266 " * Exposes the extension registry for this file.\n"
159 "/// The base class provides:\n" 267 " *\n"
160 "/// @code\n" 268 " * The base class provides:\n"
161 "/// + (GPBExtensionRegistry *)extensionRegistry;\n" 269 " * @code\n"
162 "/// @endcode\n" 270 " * + (GPBExtensionRegistry *)extensionRegistry;\n"
163 "/// which is a @c GPBExtensionRegistry that includes all the extensions d efined by\n" 271 " * @endcode\n"
164 "/// this file and all files that it depends on.\n" 272 " * which is a @c GPBExtensionRegistry that includes all the extensions de fined by\n"
273 " * this file and all files that it depends on.\n"
274 " **/\n"
165 "@interface $root_class_name$ : GPBRootObject\n" 275 "@interface $root_class_name$ : GPBRootObject\n"
166 "@end\n" 276 "@end\n"
167 "\n", 277 "\n",
168 "root_class_name", root_class_name_); 278 "root_class_name", root_class_name_);
169 279
170 if (extension_generators_.size() > 0) { 280 if (extension_generators_.size() > 0) {
171 // The dynamic methods block is only needed if there are extensions. 281 // The dynamic methods block is only needed if there are extensions.
172 printer->Print( 282 printer->Print(
173 "@interface $root_class_name$ (DynamicMethods)\n", 283 "@interface $root_class_name$ (DynamicMethods)\n",
174 "root_class_name", root_class_name_); 284 "root_class_name", root_class_name_);
(...skipping 16 matching lines...) Expand all
191 "NS_ASSUME_NONNULL_END\n" 301 "NS_ASSUME_NONNULL_END\n"
192 "\n" 302 "\n"
193 "CF_EXTERN_C_END\n" 303 "CF_EXTERN_C_END\n"
194 "\n" 304 "\n"
195 "#pragma clang diagnostic pop\n" 305 "#pragma clang diagnostic pop\n"
196 "\n" 306 "\n"
197 "// @@protoc_insertion_point(global_scope)\n"); 307 "// @@protoc_insertion_point(global_scope)\n");
198 } 308 }
199 309
200 void FileGenerator::GenerateSource(io::Printer *printer) { 310 void FileGenerator::GenerateSource(io::Printer *printer) {
201 printer->Print( 311 // #import the runtime support.
202 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" 312 PrintFileRuntimePreamble(printer, "GPBProtocolBuffers_RuntimeSupport.h");
203 "// source: $filename$\n"
204 "\n",
205 "filename", file_->name());
206 313
207 string header_file = Path() + ".pbobjc.h"; 314 vector<const FileDescriptor*> deps_with_extensions;
208 printer->Print( 315 CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions);
209 "#import \"GPBProtocolBuffers_RuntimeSupport.h\"\n" 316
210 "#import \"$header_file$\"\n", 317 {
211 "header_file", header_file); 318 ImportWriter import_writer(
212 const vector<FileGenerator *> &dependency_generators = 319 options_.generate_for_named_framework,
213 DependencyGenerators(); 320 options_.named_framework_to_proto_path_mappings_path);
214 for (vector<FileGenerator *>::const_iterator iter = 321 const string header_extension(kHeaderExtension);
215 dependency_generators.begin(); 322
216 iter != dependency_generators.end(); ++iter) { 323 // #import the header for this proto file.
217 if (!(*iter)->IsPublicDependency()) { 324 import_writer.AddFile(file_, header_extension);
218 printer->Print("#import \"$header$.pbobjc.h\"\n", 325
219 "header", (*iter)->Path()); 326 // #import the headers for anything that a plain dependency of this proto
327 // file (that means they were just an include, not a "public" include).
328 set<string> public_import_names;
329 for (int i = 0; i < file_->public_dependency_count(); i++) {
330 public_import_names.insert(file_->public_dependency(i)->name());
331 }
332 for (int i = 0; i < file_->dependency_count(); i++) {
333 const FileDescriptor *dep = file_->dependency(i);
334 bool public_import = (public_import_names.count(dep->name()) != 0);
335 if (!public_import) {
336 import_writer.AddFile(dep, header_extension);
337 }
338 }
339
340 // If any indirect dependency provided extensions, it needs to be directly
341 // imported so it can get merged into the root's extensions registry.
342 // See the Note by CollectMinimalFileDepsContainingExtensions before
343 // changing this.
344 for (vector<const FileDescriptor *>::iterator iter =
345 deps_with_extensions.begin();
346 iter != deps_with_extensions.end(); ++iter) {
347 if (!IsDirectDependency(*iter, file_)) {
348 import_writer.AddFile(*iter, header_extension);
349 }
350 }
351
352 import_writer.Print(printer);
353 }
354
355 bool includes_oneof = false;
356 for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
357 iter != message_generators_.end(); ++iter) {
358 if ((*iter)->IncludesOneOfDefinition()) {
359 includes_oneof = true;
360 break;
220 } 361 }
221 } 362 }
363
364 // Note:
365 // deprecated-declarations suppression is only needed if some place in this
366 // proto file is something deprecated or if it references something from
367 // another file that is deprecated.
222 printer->Print( 368 printer->Print(
223 "// @@protoc_insertion_point(imports)\n" 369 "// @@protoc_insertion_point(imports)\n"
224 "\n" 370 "\n"
225 "#pragma clang diagnostic push\n" 371 "#pragma clang diagnostic push\n"
226 "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n" 372 "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n");
227 "\n"); 373 if (includes_oneof) {
374 // The generated code for oneof's uses direct ivar access, suppress the
375 // warning incase developer turn that on in the context they compile the
376 // generated code.
377 printer->Print(
378 "#pragma clang diagnostic ignored \"-Wdirect-ivar-access\"\n");
379 }
228 380
229 printer->Print( 381 printer->Print(
382 "\n"
230 "#pragma mark - $root_class_name$\n" 383 "#pragma mark - $root_class_name$\n"
231 "\n" 384 "\n"
232 "@implementation $root_class_name$\n\n", 385 "@implementation $root_class_name$\n\n",
233 "root_class_name", root_class_name_); 386 "root_class_name", root_class_name_);
234 387
235 // Generate the extension initialization structures for the top level and 388 const bool file_contains_extensions = FileContainsExtensions(file_);
236 // any nested messages.
237 ostringstream extensions_stringstream;
238 if (file_->extension_count() + file_->message_type_count() > 0) {
239 io::OstreamOutputStream extensions_outputstream(&extensions_stringstream);
240 io::Printer extensions_printer(&extensions_outputstream, '$');
241 for (vector<ExtensionGenerator *>::iterator iter =
242 extension_generators_.begin();
243 iter != extension_generators_.end(); ++iter) {
244 (*iter)->GenerateStaticVariablesInitialization(&extensions_printer);
245 }
246 for (vector<MessageGenerator *>::iterator iter =
247 message_generators_.begin();
248 iter != message_generators_.end(); ++iter) {
249 (*iter)->GenerateStaticVariablesInitialization(&extensions_printer);
250 }
251 extensions_stringstream.flush();
252 }
253 389
254 // If there were any extensions or this file has any dependencies, output 390 // If there were any extensions or this file has any dependencies, output
255 // a registry to override to create the file specific registry. 391 // a registry to override to create the file specific registry.
256 const string& extensions_str = extensions_stringstream.str(); 392 if (file_contains_extensions || !deps_with_extensions.empty()) {
257 if (extensions_str.length() > 0 || file_->dependency_count() > 0) {
258 printer->Print( 393 printer->Print(
259 "+ (GPBExtensionRegistry*)extensionRegistry {\n" 394 "+ (GPBExtensionRegistry*)extensionRegistry {\n"
260 " // This is called by +initialize so there is no need to worry\n" 395 " // This is called by +initialize so there is no need to worry\n"
261 " // about thread safety and initialization of registry.\n" 396 " // about thread safety and initialization of registry.\n"
262 " static GPBExtensionRegistry* registry = nil;\n" 397 " static GPBExtensionRegistry* registry = nil;\n"
263 " if (!registry) {\n" 398 " if (!registry) {\n"
264 " GPBDebugCheckRuntimeVersion();\n" 399 " GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n"
265 " registry = [[GPBExtensionRegistry alloc] init];\n"); 400 " registry = [[GPBExtensionRegistry alloc] init];\n");
266 401
267 printer->Indent(); 402 printer->Indent();
268 printer->Indent(); 403 printer->Indent();
269 404
270 if (extensions_str.length() > 0) { 405 if (file_contains_extensions) {
271 printer->Print( 406 printer->Print(
272 "static GPBExtensionDescription descriptions[] = {\n"); 407 "static GPBExtensionDescription descriptions[] = {\n");
273 printer->Indent(); 408 printer->Indent();
274 printer->Print(extensions_str.c_str()); 409 for (vector<ExtensionGenerator *>::iterator iter =
410 extension_generators_.begin();
411 iter != extension_generators_.end(); ++iter) {
412 (*iter)->GenerateStaticVariablesInitialization(printer);
413 }
414 for (vector<MessageGenerator *>::iterator iter =
415 message_generators_.begin();
416 iter != message_generators_.end(); ++iter) {
417 (*iter)->GenerateStaticVariablesInitialization(printer);
418 }
275 printer->Outdent(); 419 printer->Outdent();
276 printer->Print( 420 printer->Print(
277 "};\n" 421 "};\n"
278 "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]) ; ++i) {\n" 422 "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]) ; ++i) {\n"
279 " GPBExtensionDescriptor *extension =\n" 423 " GPBExtensionDescriptor *extension =\n"
280 " [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&d escriptions[i]];\n" 424 " [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&d escriptions[i]];\n"
281 " [registry addExtension:extension];\n" 425 " [registry addExtension:extension];\n"
282 " [self globallyRegisterExtension:extension];\n" 426 " [self globallyRegisterExtension:extension];\n"
283 " [extension release];\n" 427 " [extension release];\n"
284 "}\n"); 428 "}\n");
285 } 429 }
286 430
287 const vector<FileGenerator *> &dependency_generators = 431 if (deps_with_extensions.empty()) {
288 DependencyGenerators();
289 for (vector<FileGenerator *>::const_iterator iter =
290 dependency_generators.begin();
291 iter != dependency_generators.end(); ++iter) {
292 printer->Print( 432 printer->Print(
293 "[registry addExtensions:[$dependency$ extensionRegistry]];\n", 433 "// None of the imports (direct or indirect) defined extensions, so no need to add\n"
294 "dependency", (*iter)->RootClassName()); 434 "// them to this registry.\n");
435 } else {
436 printer->Print(
437 "// Merge in the imports (direct or indirect) that defined extensions. \n");
438 for (vector<const FileDescriptor *>::iterator iter =
439 deps_with_extensions.begin();
440 iter != deps_with_extensions.end(); ++iter) {
441 const string root_class_name(FileClassName((*iter)));
442 printer->Print(
443 "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
444 "dependency", root_class_name);
445 }
295 } 446 }
296 447
297 printer->Outdent(); 448 printer->Outdent();
298 printer->Outdent(); 449 printer->Outdent();
299 450
300 printer->Print( 451 printer->Print(
301 " }\n" 452 " }\n"
302 " return registry;\n" 453 " return registry;\n"
303 "}\n" 454 "}\n");
304 "\n"); 455 } else {
456 if (file_->dependency_count() > 0) {
457 printer->Print(
458 "// No extensions in the file and none of the imports (direct or indir ect)\n"
459 "// defined extensions, so no need to generate +extensionRegistry.\n") ;
460 } else {
461 printer->Print(
462 "// No extensions in the file and no imports, so no need to generate\n "
463 "// +extensionRegistry.\n");
464 }
305 } 465 }
306 466
307 printer->Print("@end\n\n"); 467 printer->Print("\n@end\n\n");
308 468
309 // File descriptor only needed if there are messages to use it. 469 // File descriptor only needed if there are messages to use it.
310 if (message_generators_.size() > 0) { 470 if (message_generators_.size() > 0) {
311 string syntax; 471 map<string, string> vars;
472 vars["root_class_name"] = root_class_name_;
473 vars["package"] = file_->package();
474 vars["objc_prefix"] = FileClassPrefix(file_);
312 switch (file_->syntax()) { 475 switch (file_->syntax()) {
313 case FileDescriptor::SYNTAX_UNKNOWN: 476 case FileDescriptor::SYNTAX_UNKNOWN:
314 syntax = "GPBFileSyntaxUnknown"; 477 vars["syntax"] = "GPBFileSyntaxUnknown";
315 break; 478 break;
316 case FileDescriptor::SYNTAX_PROTO2: 479 case FileDescriptor::SYNTAX_PROTO2:
317 syntax = "GPBFileSyntaxProto2"; 480 vars["syntax"] = "GPBFileSyntaxProto2";
318 break; 481 break;
319 case FileDescriptor::SYNTAX_PROTO3: 482 case FileDescriptor::SYNTAX_PROTO3:
320 syntax = "GPBFileSyntaxProto3"; 483 vars["syntax"] = "GPBFileSyntaxProto3";
321 break; 484 break;
322 } 485 }
323 printer->Print( 486 printer->Print(vars,
324 "#pragma mark - $root_class_name$_FileDescriptor\n" 487 "#pragma mark - $root_class_name$_FileDescriptor\n"
325 "\n" 488 "\n"
326 "static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n" 489 "static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n"
327 " // This is called by +initialize so there is no need to worry\n" 490 " // This is called by +initialize so there is no need to worry\n"
328 " // about thread safety of the singleton.\n" 491 " // about thread safety of the singleton.\n"
329 " static GPBFileDescriptor *descriptor = NULL;\n" 492 " static GPBFileDescriptor *descriptor = NULL;\n"
330 " if (!descriptor) {\n" 493 " if (!descriptor) {\n"
331 " GPBDebugCheckRuntimeVersion();\n" 494 " GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n");
332 " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package $\"\n" 495 if (vars["objc_prefix"].size() > 0) {
333 " syntax:$syntax$];\ n" 496 printer->Print(
497 vars,
498 " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$packa ge$\"\n"
499 " objcPrefix:@\"$objc_ prefix$\"\n"
500 " syntax:$syntax$] ;\n");
501 } else {
502 printer->Print(
503 vars,
504 " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$packa ge$\"\n"
505 " syntax:$syntax$] ;\n");
506 }
507 printer->Print(
334 " }\n" 508 " }\n"
335 " return descriptor;\n" 509 " return descriptor;\n"
336 "}\n" 510 "}\n"
337 "\n", 511 "\n");
338 "root_class_name", root_class_name_,
339 "package", file_->package(),
340 "syntax", syntax);
341 } 512 }
342 513
343 for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin(); 514 for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin();
344 iter != enum_generators_.end(); ++iter) { 515 iter != enum_generators_.end(); ++iter) {
345 (*iter)->GenerateSource(printer); 516 (*iter)->GenerateSource(printer);
346 } 517 }
347 for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); 518 for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
348 iter != message_generators_.end(); ++iter) { 519 iter != message_generators_.end(); ++iter) {
349 (*iter)->GenerateSource(printer); 520 (*iter)->GenerateSource(printer);
350 } 521 }
351 522
352 printer->Print( 523 printer->Print(
353 "\n" 524 "\n"
354 "#pragma clang diagnostic pop\n" 525 "#pragma clang diagnostic pop\n"
355 "\n" 526 "\n"
356 "// @@protoc_insertion_point(global_scope)\n"); 527 "// @@protoc_insertion_point(global_scope)\n");
357 } 528 }
358 529
359 const string FileGenerator::Path() const { return FilePath(file_); } 530 // Helper to print the import of the runtime support at the top of generated
531 // files. This currently only supports the runtime coming from a framework
532 // as defined by the official CocoaPod.
533 void FileGenerator::PrintFileRuntimePreamble(
534 io::Printer* printer, const string& header_to_import) const {
535 printer->Print(
536 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
537 "// source: $filename$\n"
538 "\n",
539 "filename", file_->name());
360 540
361 const vector<FileGenerator *> &FileGenerator::DependencyGenerators() { 541 const string framework_name(ProtobufLibraryFrameworkName);
362 if (file_->dependency_count() != dependency_generators_.size()) { 542 const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name));
363 set<string> public_import_names; 543 printer->Print(
364 for (int i = 0; i < file_->public_dependency_count(); i++) { 544 "// This CPP symbol can be defined to use imports that match up to the fra mework\n"
365 public_import_names.insert(file_->public_dependency(i)->name()); 545 "// imports needed when using CocoaPods.\n"
366 } 546 "#if !defined($cpp_symbol$)\n"
367 for (int i = 0; i < file_->dependency_count(); i++) { 547 " #define $cpp_symbol$ 0\n"
368 FileGenerator *generator = 548 "#endif\n"
369 new FileGenerator(file_->dependency(i), options_); 549 "\n"
370 const string& name = file_->dependency(i)->name(); 550 "#if $cpp_symbol$\n"
371 bool public_import = (public_import_names.count(name) != 0); 551 " #import <$framework_name$/$header$>\n"
372 generator->SetIsPublicDependency(public_import); 552 "#else\n"
373 dependency_generators_.push_back(generator); 553 " #import \"$header$\"\n"
374 } 554 "#endif\n"
375 } 555 "\n",
376 return dependency_generators_; 556 "cpp_symbol", cpp_symbol,
557 "header", header_to_import,
558 "framework_name", framework_name);
377 } 559 }
378 560
379 } // namespace objectivec 561 } // namespace objectivec
380 } // namespace compiler 562 } // namespace compiler
381 } // namespace protobuf 563 } // namespace protobuf
382 } // namespace google 564 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698