OLD | NEW |
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 namespace google { | 53 namespace google { |
54 namespace protobuf { | 54 namespace protobuf { |
55 namespace compiler { | 55 namespace compiler { |
56 namespace cpp { | 56 namespace cpp { |
57 | 57 |
58 // =================================================================== | 58 // =================================================================== |
59 | 59 |
60 FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) | 60 FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) |
61 : file_(file), | 61 : file_(file), |
62 options_(options), | 62 options_(options), |
63 message_generators_owner_( | 63 message_generators_( |
64 new google::protobuf::scoped_ptr<MessageGenerator>[ file->message_type
_count() ]), | 64 new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_
count()]), |
65 enum_generators_owner_( | 65 enum_generators_( |
66 new google::protobuf::scoped_ptr<EnumGenerator>[ file->enum_type_count
() ]), | 66 new google::protobuf::scoped_ptr<EnumGenerator>[file->enum_type_count(
)]), |
67 service_generators_owner_( | 67 service_generators_( |
68 new google::protobuf::scoped_ptr<ServiceGenerator>[ file->service_coun
t() ]), | 68 new google::protobuf::scoped_ptr<ServiceGenerator>[file->service_count
()]), |
69 extension_generators_owner_( | 69 extension_generators_( |
70 new google::protobuf::scoped_ptr<ExtensionGenerator>[ file->extension_
count() ]) { | 70 new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_c
ount()]) { |
71 | 71 |
72 for (int i = 0; i < file->message_type_count(); i++) { | 72 for (int i = 0; i < file->message_type_count(); i++) { |
73 message_generators_owner_[i].reset( | 73 message_generators_[i].reset( |
74 new MessageGenerator(file->message_type(i), options)); | 74 new MessageGenerator(file->message_type(i), options)); |
75 message_generators_owner_[i]->Flatten(&message_generators_); | |
76 } | |
77 | |
78 for (int i = 0; i < message_generators_.size(); i++) { | |
79 message_generators_[i]->AddGenerators(&enum_generators_, | |
80 &extension_generators_); | |
81 } | 75 } |
82 | 76 |
83 for (int i = 0; i < file->enum_type_count(); i++) { | 77 for (int i = 0; i < file->enum_type_count(); i++) { |
84 enum_generators_owner_[i].reset( | 78 enum_generators_[i].reset( |
85 new EnumGenerator(file->enum_type(i), options)); | 79 new EnumGenerator(file->enum_type(i), options)); |
86 enum_generators_.push_back(enum_generators_owner_[i].get()); | |
87 } | 80 } |
88 | 81 |
89 for (int i = 0; i < file->service_count(); i++) { | 82 for (int i = 0; i < file->service_count(); i++) { |
90 service_generators_owner_[i].reset( | 83 service_generators_[i].reset( |
91 new ServiceGenerator(file->service(i), options)); | 84 new ServiceGenerator(file->service(i), options)); |
92 service_generators_.push_back(service_generators_owner_[i].get()); | |
93 } | 85 } |
94 | 86 |
95 for (int i = 0; i < file->extension_count(); i++) { | 87 for (int i = 0; i < file->extension_count(); i++) { |
96 extension_generators_owner_[i].reset( | 88 extension_generators_[i].reset( |
97 new ExtensionGenerator(file->extension(i), options)); | 89 new ExtensionGenerator(file->extension(i), options)); |
98 extension_generators_.push_back(extension_generators_owner_[i].get()); | |
99 } | 90 } |
100 | 91 |
101 package_parts_ = Split(file_->package(), ".", true); | 92 SplitStringUsing(file_->package(), ".", &package_parts_); |
102 } | 93 } |
103 | 94 |
104 FileGenerator::~FileGenerator() {} | 95 FileGenerator::~FileGenerator() {} |
105 | 96 |
106 void FileGenerator::GenerateHeader(io::Printer* printer) { | 97 void FileGenerator::GenerateProtoHeader(io::Printer* printer, |
| 98 const string& info_path) { |
| 99 if (!options_.proto_h) { |
| 100 return; |
| 101 } |
| 102 |
| 103 string filename_identifier = FilenameIdentifier(file_->name()); |
| 104 GenerateTopHeaderGuard(printer, filename_identifier); |
| 105 |
| 106 |
| 107 GenerateLibraryIncludes(printer); |
| 108 |
| 109 for (int i = 0; i < file_->public_dependency_count(); i++) { |
| 110 const FileDescriptor* dep = file_->public_dependency(i); |
| 111 const char* extension = ".proto.h"; |
| 112 string dependency = StripProto(dep->name()) + extension; |
| 113 printer->Print( |
| 114 "#include \"$dependency$\" // IWYU pragma: export\n", |
| 115 "dependency", dependency); |
| 116 } |
| 117 |
| 118 GenerateMetadataPragma(printer, info_path); |
| 119 |
107 printer->Print( | 120 printer->Print( |
108 "// @@protoc_insertion_point(includes)\n"); | 121 "// @@protoc_insertion_point(includes)\n"); |
109 | 122 |
110 | 123 |
111 GenerateForwardDeclarations(printer); | 124 GenerateForwardDeclarations(printer); |
112 | 125 |
113 // Open namespace. | 126 // Open namespace. |
114 GenerateNamespaceOpeners(printer); | 127 GenerateNamespaceOpeners(printer); |
115 | 128 |
116 GenerateGlobalStateFunctionDeclarations(printer); | 129 GenerateGlobalStateFunctionDeclarations(printer); |
(...skipping 29 matching lines...) Expand all Loading... |
146 // Close up namespace. | 159 // Close up namespace. |
147 GenerateNamespaceClosers(printer); | 160 GenerateNamespaceClosers(printer); |
148 | 161 |
149 // We need to specialize some templates in the ::google::protobuf namespace: | 162 // We need to specialize some templates in the ::google::protobuf namespace: |
150 GenerateProto2NamespaceEnumSpecializations(printer); | 163 GenerateProto2NamespaceEnumSpecializations(printer); |
151 | 164 |
152 printer->Print( | 165 printer->Print( |
153 "\n" | 166 "\n" |
154 "// @@protoc_insertion_point(global_scope)\n" | 167 "// @@protoc_insertion_point(global_scope)\n" |
155 "\n"); | 168 "\n"); |
156 } | |
157 | |
158 void FileGenerator::GenerateProtoHeader(io::Printer* printer, | |
159 const string& info_path) { | |
160 if (!options_.proto_h) { | |
161 return; | |
162 } | |
163 | |
164 string filename_identifier = FilenameIdentifier(file_->name()); | |
165 GenerateTopHeaderGuard(printer, filename_identifier); | |
166 | |
167 | |
168 GenerateLibraryIncludes(printer); | |
169 | |
170 for (int i = 0; i < file_->public_dependency_count(); i++) { | |
171 const FileDescriptor* dep = file_->public_dependency(i); | |
172 const char* extension = ".proto.h"; | |
173 string dependency = StripProto(dep->name()) + extension; | |
174 printer->Print( | |
175 "#include \"$dependency$\" // IWYU pragma: export\n", | |
176 "dependency", dependency); | |
177 } | |
178 | |
179 GenerateMetadataPragma(printer, info_path); | |
180 | |
181 GenerateHeader(printer); | |
182 | 169 |
183 GenerateBottomHeaderGuard(printer, filename_identifier); | 170 GenerateBottomHeaderGuard(printer, filename_identifier); |
184 } | 171 } |
185 | 172 |
186 void FileGenerator::GeneratePBHeader(io::Printer* printer, | 173 void FileGenerator::GeneratePBHeader(io::Printer* printer, |
187 const string& info_path) { | 174 const string& info_path) { |
188 string filename_identifier = | 175 string filename_identifier = |
189 FilenameIdentifier(file_->name() + (options_.proto_h ? ".pb.h" : "")); | 176 FilenameIdentifier(file_->name() + (options_.proto_h ? ".pb.h" : "")); |
190 GenerateTopHeaderGuard(printer, filename_identifier); | 177 GenerateTopHeaderGuard(printer, filename_identifier); |
191 | 178 |
192 if (options_.proto_h) { | 179 if (options_.proto_h) { |
193 printer->Print("#include \"$basename$.proto.h\" // IWYU pragma: export\n", | 180 printer->Print("#include \"$basename$.proto.h\" // IWYU pragma: export\n", |
194 "basename", StripProto(file_->name())); | 181 "basename", StripProto(file_->name())); |
195 } else { | 182 } else { |
196 GenerateLibraryIncludes(printer); | 183 GenerateLibraryIncludes(printer); |
197 } | 184 } |
198 GenerateDependencyIncludes(printer); | 185 GenerateDependencyIncludes(printer); |
199 GenerateMetadataPragma(printer, info_path); | 186 GenerateMetadataPragma(printer, info_path); |
200 | 187 |
| 188 printer->Print( |
| 189 "// @@protoc_insertion_point(includes)\n"); |
| 190 |
| 191 |
| 192 |
| 193 // Open namespace. |
| 194 GenerateNamespaceOpeners(printer); |
| 195 |
201 if (!options_.proto_h) { | 196 if (!options_.proto_h) { |
202 GenerateHeader(printer); | 197 GenerateGlobalStateFunctionDeclarations(printer); |
203 } else { | 198 GenerateMessageForwardDeclarations(printer); |
204 // This is unfortunately necessary for some plugins. I don't see why we | |
205 // need two of the same insertion points. | |
206 // TODO(gerbens) remove this. | |
207 printer->Print( | |
208 "// @@protoc_insertion_point(includes)\n"); | |
209 | 199 |
210 // Open namespace. | 200 printer->Print("\n"); |
211 GenerateNamespaceOpeners(printer); | |
212 printer->Print( | |
213 "\n" | |
214 "// @@protoc_insertion_point(namespace_scope)\n"); | |
215 // Close up namespace. | |
216 GenerateNamespaceClosers(printer); | |
217 | 201 |
218 printer->Print( | 202 GenerateEnumDefinitions(printer); |
219 "\n" | 203 |
220 "// @@protoc_insertion_point(global_scope)\n" | 204 printer->Print(kThickSeparator); |
221 "\n"); | 205 printer->Print("\n"); |
| 206 |
| 207 GenerateMessageDefinitions(printer); |
| 208 |
| 209 printer->Print("\n"); |
| 210 printer->Print(kThickSeparator); |
| 211 printer->Print("\n"); |
| 212 |
| 213 GenerateServiceDefinitions(printer); |
| 214 |
| 215 GenerateExtensionIdentifiers(printer); |
| 216 |
| 217 printer->Print("\n"); |
| 218 printer->Print(kThickSeparator); |
| 219 printer->Print("\n"); |
| 220 |
| 221 GenerateInlineFunctionDefinitions(printer); |
222 } | 222 } |
223 | 223 |
| 224 printer->Print( |
| 225 "\n" |
| 226 "// @@protoc_insertion_point(namespace_scope)\n"); |
| 227 |
| 228 // Close up namespace. |
| 229 GenerateNamespaceClosers(printer); |
| 230 |
| 231 if (!options_.proto_h) { |
| 232 // We need to specialize some templates in the ::google::protobuf namespace: |
| 233 GenerateProto2NamespaceEnumSpecializations(printer); |
| 234 } |
| 235 |
| 236 printer->Print( |
| 237 "\n" |
| 238 "// @@protoc_insertion_point(global_scope)\n" |
| 239 "\n"); |
| 240 |
224 GenerateBottomHeaderGuard(printer, filename_identifier); | 241 GenerateBottomHeaderGuard(printer, filename_identifier); |
225 } | 242 } |
226 | 243 |
227 void FileGenerator::GenerateSource(io::Printer* printer) { | 244 void FileGenerator::GenerateSource(io::Printer* printer) { |
228 const bool use_system_include = IsWellKnownMessage(file_); | 245 const bool use_system_include = IsWellKnownMessage(file_); |
229 string header = | 246 string header = |
230 StripProto(file_->name()) + (options_.proto_h ? ".proto.h" : ".pb.h"); | 247 StripProto(file_->name()) + (options_.proto_h ? ".proto.h" : ".pb.h"); |
231 printer->Print( | 248 printer->Print( |
232 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" | 249 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" |
233 "// source: $filename$\n" | 250 "// source: $filename$\n" |
234 "\n" | 251 "\n" |
235 // The generated code calls accessors that might be deprecated. We don't | 252 // The generated code calls accessors that might be deprecated. We don't |
236 // want the compiler to warn in generated code. | 253 // want the compiler to warn in generated code. |
237 "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n" | 254 "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n" |
238 "#include $left$$header$$right$\n" | 255 "#include $left$$header$$right$\n" |
239 "\n" | 256 "\n" |
240 "#include <algorithm>\n" // for swap() | 257 "#include <algorithm>\n" // for swap() |
241 "\n" | 258 "\n" |
242 "#include <google/protobuf/stubs/common.h>\n" | 259 "#include <google/protobuf/stubs/common.h>\n" |
243 "#include <google/protobuf/stubs/port.h>\n" | 260 "#include <google/protobuf/stubs/port.h>\n" |
244 "#include <google/protobuf/stubs/once.h>\n" | 261 "#include <google/protobuf/stubs/once.h>\n" |
245 "#include <google/protobuf/io/coded_stream.h>\n" | 262 "#include <google/protobuf/io/coded_stream.h>\n" |
246 "#include <google/protobuf/wire_format_lite_inl.h>\n", | 263 "#include <google/protobuf/wire_format_lite_inl.h>\n", |
247 "filename", file_->name(), | 264 "filename", file_->name(), |
248 "header", header, | 265 "header", header, |
249 "left", use_system_include ? "<" : "\"", | 266 "left", use_system_include ? "<" : "\"", |
250 "right", use_system_include ? ">" : "\""); | 267 "right", use_system_include ? ">" : "\""); |
251 | 268 |
252 // Unknown fields implementation in lite mode uses StringOutputStream | 269 // Unknown fields implementation in lite mode uses StringOutputStream |
253 if (!UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) { | 270 if (!UseUnknownFieldSet(file_, options_) && file_->message_type_count() > 0) { |
254 printer->Print( | 271 printer->Print( |
255 "#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n"); | 272 "#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n"); |
256 } | 273 } |
257 | 274 |
258 if (HasDescriptorMethods(file_, options_)) { | 275 if (HasDescriptorMethods(file_, options_)) { |
259 printer->Print( | 276 printer->Print( |
260 "#include <google/protobuf/descriptor.h>\n" | 277 "#include <google/protobuf/descriptor.h>\n" |
261 "#include <google/protobuf/generated_message_reflection.h>\n" | 278 "#include <google/protobuf/generated_message_reflection.h>\n" |
262 "#include <google/protobuf/reflection_ops.h>\n" | 279 "#include <google/protobuf/reflection_ops.h>\n" |
263 "#include <google/protobuf/wire_format.h>\n"); | 280 "#include <google/protobuf/wire_format.h>\n"); |
264 } | 281 } |
265 | 282 |
266 if (options_.proto_h) { | 283 if (options_.proto_h) { |
267 // Use the smaller .proto.h files. | 284 // Use the smaller .proto.h files. |
268 for (int i = 0; i < file_->dependency_count(); i++) { | 285 for (int i = 0; i < file_->dependency_count(); i++) { |
269 const FileDescriptor* dep = file_->dependency(i); | 286 const FileDescriptor* dep = file_->dependency(i); |
270 const char* extension = ".proto.h"; | 287 const char* extension = ".proto.h"; |
271 string dependency = StripProto(dep->name()) + extension; | 288 string dependency = StripProto(dep->name()) + extension; |
272 printer->Print( | 289 printer->Print( |
273 "#include \"$dependency$\"\n", | 290 "#include \"$dependency$\"\n", |
274 "dependency", dependency); | 291 "dependency", dependency); |
275 } | 292 } |
276 } | 293 } |
277 | 294 |
278 printer->Print( | 295 printer->Print( |
279 "// @@protoc_insertion_point(includes)\n"); | 296 "// @@protoc_insertion_point(includes)\n"); |
280 | 297 |
281 GenerateNamespaceOpeners(printer); | 298 GenerateNamespaceOpeners(printer); |
282 | 299 |
283 for (int i = 0; i < message_generators_.size(); i++) { | |
284 if (IsMapEntryMessage(message_generators_[i]->descriptor_)) continue; | |
285 printer->Print( | |
286 "class $classname$DefaultTypeInternal : " | |
287 "public ::google::protobuf::internal::ExplicitlyConstructed<$classname$>
{};\n" | |
288 "$classname$DefaultTypeInternal _$classname$_default_instance_;\n", | |
289 "classname", message_generators_[i]->classname_); | |
290 } | |
291 | |
292 for (int i = 0; i < message_generators_.size(); i++) { | |
293 message_generators_[i]->index_in_metadata_ = i; | |
294 } | |
295 for (int i = 0; i < enum_generators_.size(); i++) { | |
296 enum_generators_[i]->index_in_metadata_ = i; | |
297 } | |
298 if (HasGenericServices(file_, options_)) { | |
299 for (int i = 0; i < service_generators_.size(); i++) { | |
300 service_generators_[i]->index_in_metadata_ = i; | |
301 } | |
302 } | |
303 | |
304 if (HasDescriptorMethods(file_, options_)) { | 300 if (HasDescriptorMethods(file_, options_)) { |
305 printer->Print( | 301 printer->Print( |
306 "\n" | 302 "\n" |
307 "namespace {\n" | 303 "namespace {\n" |
308 "\n"); | 304 "\n"); |
309 | 305 for (int i = 0; i < file_->message_type_count(); i++) { |
310 if (!message_generators_.empty()) { | 306 message_generators_[i]->GenerateDescriptorDeclarations(printer); |
311 printer->Print("::google::protobuf::Metadata file_level_metadata[$size$];\
n", | |
312 "size", SimpleItoa(message_generators_.size())); | |
313 } | 307 } |
314 if (!enum_generators_.empty()) { | 308 for (int i = 0; i < file_->enum_type_count(); i++) { |
315 printer->Print( | 309 printer->Print( |
316 "const ::google::protobuf::EnumDescriptor* " | 310 "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n"
, |
317 "file_level_enum_descriptors[$size$];\n", | 311 "name", ClassName(file_->enum_type(i), false)); |
318 "size", SimpleItoa(enum_generators_.size())); | |
319 } | |
320 if (HasGenericServices(file_, options_) && file_->service_count() > 0) { | |
321 printer->Print( | |
322 "const ::google::protobuf::ServiceDescriptor* " | |
323 "file_level_service_descriptors[$size$];\n", | |
324 "size", SimpleItoa(file_->service_count())); | |
325 } | 312 } |
326 | 313 |
327 for (int i = 0; i < message_generators_.size(); i++) { | 314 if (HasGenericServices(file_, options_)) { |
328 message_generators_[i]->GenerateDescriptorDeclarations(printer); | 315 for (int i = 0; i < file_->service_count(); i++) { |
| 316 printer->Print( |
| 317 "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NUL
L;\n", |
| 318 "name", file_->service(i)->name()); |
| 319 } |
329 } | 320 } |
330 | 321 |
331 printer->Print( | 322 printer->Print( |
332 "\n" | 323 "\n" |
333 "} // namespace\n" | 324 "} // namespace\n" |
334 "\n"); | 325 "\n"); |
335 } | 326 } |
336 | 327 |
337 // Define our externally-visible BuildDescriptors() function. (For the lite | 328 // Define our externally-visible BuildDescriptors() function. (For the lite |
338 // library, all this does is initialize default instances.) | 329 // library, all this does is initialize default instances.) |
339 GenerateBuildDescriptors(printer); | 330 GenerateBuildDescriptors(printer); |
340 | 331 |
341 // Generate enums. | 332 // Generate enums. |
342 for (int i = 0; i < enum_generators_.size(); i++) { | 333 for (int i = 0; i < file_->enum_type_count(); i++) { |
343 enum_generators_[i]->GenerateMethods(printer); | 334 enum_generators_[i]->GenerateMethods(printer); |
344 } | 335 } |
345 | 336 |
346 // Generate classes. | 337 // Generate classes. |
347 for (int i = 0; i < message_generators_.size(); i++) { | 338 for (int i = 0; i < file_->message_type_count(); i++) { |
| 339 if (i == 0 && HasGeneratedMethods(file_, options_)) { |
| 340 printer->Print( |
| 341 "\n" |
| 342 "namespace {\n" |
| 343 "\n" |
| 344 "static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;\n" |
| 345 "GOOGLE_ATTRIBUTE_NOINLINE static void MergeFromFail(int line) {\n" |
| 346 " GOOGLE_CHECK(false) << __FILE__ << \":\" << line;\n" |
| 347 "}\n" |
| 348 "\n" |
| 349 "} // namespace\n" |
| 350 "\n"); |
| 351 } |
348 printer->Print("\n"); | 352 printer->Print("\n"); |
349 printer->Print(kThickSeparator); | 353 printer->Print(kThickSeparator); |
350 printer->Print("\n"); | 354 printer->Print("\n"); |
351 message_generators_[i]->GenerateClassMethods(printer); | 355 message_generators_[i]->GenerateClassMethods(printer); |
352 | 356 |
353 printer->Print("#if PROTOBUF_INLINE_NOT_IN_HEADERS\n"); | 357 printer->Print("#if PROTOBUF_INLINE_NOT_IN_HEADERS\n"); |
354 // Generate class inline methods. | 358 // Generate class inline methods. |
355 message_generators_[i]->GenerateInlineMethods(printer, | 359 message_generators_[i]->GenerateInlineMethods(printer, |
356 /* is_inline = */ false); | 360 /* is_inline = */ false); |
357 printer->Print("#endif // PROTOBUF_INLINE_NOT_IN_HEADERS\n"); | 361 printer->Print("#endif // PROTOBUF_INLINE_NOT_IN_HEADERS\n"); |
358 } | 362 } |
359 | 363 |
360 if (HasGenericServices(file_, options_)) { | 364 if (HasGenericServices(file_, options_)) { |
361 // Generate services. | 365 // Generate services. |
362 for (int i = 0; i < service_generators_.size(); i++) { | 366 for (int i = 0; i < file_->service_count(); i++) { |
363 if (i == 0) printer->Print("\n"); | 367 if (i == 0) printer->Print("\n"); |
364 printer->Print(kThickSeparator); | 368 printer->Print(kThickSeparator); |
365 printer->Print("\n"); | 369 printer->Print("\n"); |
366 service_generators_[i]->GenerateImplementation(printer); | 370 service_generators_[i]->GenerateImplementation(printer); |
367 } | 371 } |
368 } | 372 } |
369 | 373 |
370 // Define extensions. | 374 // Define extensions. |
371 for (int i = 0; i < extension_generators_.size(); i++) { | 375 for (int i = 0; i < file_->extension_count(); i++) { |
372 extension_generators_[i]->GenerateDefinition(printer); | 376 extension_generators_[i]->GenerateDefinition(printer); |
373 } | 377 } |
374 | 378 |
375 printer->Print( | 379 printer->Print( |
376 "\n" | 380 "\n" |
377 "// @@protoc_insertion_point(namespace_scope)\n"); | 381 "// @@protoc_insertion_point(namespace_scope)\n"); |
378 | 382 |
379 GenerateNamespaceClosers(printer); | 383 GenerateNamespaceClosers(printer); |
380 | 384 |
381 printer->Print( | 385 printer->Print( |
382 "\n" | 386 "\n" |
383 "// @@protoc_insertion_point(global_scope)\n"); | 387 "// @@protoc_insertion_point(global_scope)\n"); |
384 } | 388 } |
385 | 389 |
386 class FileGenerator::ForwardDeclarations { | 390 class FileGenerator::ForwardDeclarations { |
387 public: | 391 public: |
388 ~ForwardDeclarations() { | 392 ~ForwardDeclarations() { |
389 for (std::map<string, ForwardDeclarations*>::iterator | 393 for (map<string, ForwardDeclarations *>::iterator it = namespaces_.begin(), |
390 it = namespaces_.begin(), | 394 end = namespaces_.end(); |
391 end = namespaces_.end(); | |
392 it != end; ++it) { | 395 it != end; ++it) { |
393 delete it->second; | 396 delete it->second; |
394 } | 397 } |
395 namespaces_.clear(); | 398 namespaces_.clear(); |
396 } | 399 } |
397 | 400 |
398 ForwardDeclarations* AddOrGetNamespace(const string& ns_name) { | 401 ForwardDeclarations* AddOrGetNamespace(const string& ns_name) { |
399 ForwardDeclarations*& ns = namespaces_[ns_name]; | 402 ForwardDeclarations*& ns = namespaces_[ns_name]; |
400 if (ns == NULL) { | 403 if (ns == NULL) { |
401 ns = new ForwardDeclarations; | 404 ns = new ForwardDeclarations; |
402 } | 405 } |
403 return ns; | 406 return ns; |
404 } | 407 } |
405 | 408 |
406 std::map<string, const Descriptor*>& classes() { return classes_; } | 409 map<string, const Descriptor*>& classes() { return classes_; } |
407 std::map<string, const EnumDescriptor*>& enums() { return enums_; } | 410 map<string, const EnumDescriptor*>& enums() { return enums_; } |
408 | 411 |
409 void Print(io::Printer* printer, const Options& options) const { | 412 void Print(io::Printer* printer) const { |
410 for (std::map<string, const EnumDescriptor *>::const_iterator | 413 for (map<string, const EnumDescriptor *>::const_iterator |
411 it = enums_.begin(), | 414 it = enums_.begin(), |
412 end = enums_.end(); | 415 end = enums_.end(); |
413 it != end; ++it) { | 416 it != end; ++it) { |
414 printer->Print("enum $enumname$ : int;\n", "enumname", it->first); | 417 printer->Print("enum $enumname$ : int;\n", "enumname", it->first); |
415 printer->Annotate("enumname", it->second); | 418 printer->Annotate("enumname", it->second); |
416 printer->Print("bool $enumname$_IsValid(int value);\n", "enumname", | 419 printer->Print("bool $enumname$_IsValid(int value);\n", "enumname", |
417 it->first); | 420 it->first); |
418 } | 421 } |
419 for (std::map<string, const Descriptor*>::const_iterator | 422 for (map<string, const Descriptor *>::const_iterator it = classes_.begin(), |
420 it = classes_.begin(), | 423 end = classes_.end(); |
421 end = classes_.end(); | |
422 it != end; ++it) { | 424 it != end; ++it) { |
423 printer->Print("class $classname$;\n", "classname", it->first); | 425 printer->Print("class $classname$;\n", "classname", it->first); |
424 printer->Annotate("classname", it->second); | 426 printer->Annotate("classname", it->second); |
425 | |
426 printer->Print( | |
427 "class $classname$DefaultTypeInternal;\n" | |
428 "$dllexport_decl$" | |
429 "extern $classname$DefaultTypeInternal " | |
430 "_$classname$_default_instance_;\n", // NOLINT | |
431 "dllexport_decl", | |
432 options.dllexport_decl.empty() ? "" : options.dllexport_decl + " ", | |
433 "classname", | |
434 it->first); | |
435 } | 427 } |
436 for (std::map<string, ForwardDeclarations *>::const_iterator | 428 for (map<string, ForwardDeclarations *>::const_iterator |
437 it = namespaces_.begin(), | 429 it = namespaces_.begin(), |
438 end = namespaces_.end(); | 430 end = namespaces_.end(); |
439 it != end; ++it) { | 431 it != end; ++it) { |
440 printer->Print("namespace $nsname$ {\n", | 432 printer->Print("namespace $nsname$ {\n", |
441 "nsname", it->first); | 433 "nsname", it->first); |
442 it->second->Print(printer, options); | 434 it->second->Print(printer); |
443 printer->Print("} // namespace $nsname$\n", | 435 printer->Print("} // namespace $nsname$\n", |
444 "nsname", it->first); | 436 "nsname", it->first); |
445 } | 437 } |
446 } | 438 } |
447 | 439 |
448 | 440 |
449 private: | 441 private: |
450 std::map<string, ForwardDeclarations*> namespaces_; | 442 map<string, ForwardDeclarations*> namespaces_; |
451 std::map<string, const Descriptor*> classes_; | 443 map<string, const Descriptor*> classes_; |
452 std::map<string, const EnumDescriptor*> enums_; | 444 map<string, const EnumDescriptor*> enums_; |
453 }; | 445 }; |
454 | 446 |
455 void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { | 447 void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { |
456 // AddDescriptors() is a file-level procedure which adds the encoded | 448 // AddDescriptors() is a file-level procedure which adds the encoded |
457 // FileDescriptorProto for this .proto file to the global DescriptorPool for | 449 // FileDescriptorProto for this .proto file to the global DescriptorPool for |
458 // generated files (DescriptorPool::generated_pool()). It either runs at | 450 // generated files (DescriptorPool::generated_pool()). It either runs at |
459 // static initialization time (by default) or when default_instance() is | 451 // static initialization time (by default) or when default_instance() is |
460 // called for the first time (in LITE_RUNTIME mode with | 452 // called for the first time (in LITE_RUNTIME mode with |
461 // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also | 453 // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also |
462 // constructs default instances and registers extensions. | 454 // constructs default instances and registers extensions. |
463 // | 455 // |
464 // Its sibling, AssignDescriptors(), actually pulls the compiled | 456 // Its sibling, AssignDescriptors(), actually pulls the compiled |
465 // FileDescriptor from the DescriptorPool and uses it to populate all of | 457 // FileDescriptor from the DescriptorPool and uses it to populate all of |
466 // the global variables which store pointers to the descriptor objects. | 458 // the global variables which store pointers to the descriptor objects. |
467 // It also constructs the reflection objects. It is called the first time | 459 // It also constructs the reflection objects. It is called the first time |
468 // anyone calls descriptor() or GetReflection() on one of the types defined | 460 // anyone calls descriptor() or GetReflection() on one of the types defined |
469 // in the file. | 461 // in the file. |
470 | 462 |
471 // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors() | 463 // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors() |
472 // and we only use AddDescriptors() to allocate default instances. | 464 // and we only use AddDescriptors() to allocate default instances. |
| 465 if (HasDescriptorMethods(file_, options_)) { |
| 466 printer->Print( |
| 467 "\n" |
| 468 "void $assigndescriptorsname$() {\n", |
| 469 "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name())); |
| 470 printer->Indent(); |
473 | 471 |
474 if (HasDescriptorMethods(file_, options_)) { | 472 // Make sure the file has found its way into the pool. If a descriptor |
475 if (!message_generators_.empty()) { | 473 // is requested *during* static init then AddDescriptors() may not have |
476 printer->Print( | 474 // been called yet, so we call it manually. Note that it's fine if |
477 "\n" | 475 // AddDescriptors() is called multiple times. |
478 "const ::google::protobuf::uint32* $offsetfunname$() GOOGLE_ATTRIBUTE_
COLD;\n" | 476 printer->Print( |
479 "const ::google::protobuf::uint32* $offsetfunname$() {\n", | 477 "$adddescriptorsname$();\n", |
480 "offsetfunname", GlobalOffsetTableName(file_->name())); | 478 "adddescriptorsname", GlobalAddDescriptorsName(file_->name())); |
481 printer->Indent(); | |
482 | 479 |
483 printer->Print("static const ::google::protobuf::uint32 offsets[] = {\n"); | 480 // Get the file's descriptor from the pool. |
484 printer->Indent(); | 481 printer->Print( |
485 std::vector<std::pair<size_t, size_t> > pairs; | 482 "const ::google::protobuf::FileDescriptor* file =\n" |
486 for (int i = 0; i < message_generators_.size(); i++) { | 483 " ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n
" |
487 pairs.push_back(message_generators_[i]->GenerateOffsets(printer)); | 484 " \"$filename$\");\n" |
| 485 // Note that this GOOGLE_CHECK is necessary to prevent a warning about "fi
le" |
| 486 // being unused when compiling an empty .proto file. |
| 487 "GOOGLE_CHECK(file != NULL);\n", |
| 488 "filename", file_->name()); |
| 489 |
| 490 // Go through all the stuff defined in this file and generated code to |
| 491 // assign the global descriptor pointers based on the file descriptor. |
| 492 for (int i = 0; i < file_->message_type_count(); i++) { |
| 493 message_generators_[i]->GenerateDescriptorInitializer(printer, i); |
| 494 } |
| 495 for (int i = 0; i < file_->enum_type_count(); i++) { |
| 496 enum_generators_[i]->GenerateDescriptorInitializer(printer, i); |
| 497 } |
| 498 if (HasGenericServices(file_, options_)) { |
| 499 for (int i = 0; i < file_->service_count(); i++) { |
| 500 service_generators_[i]->GenerateDescriptorInitializer(printer, i); |
488 } | 501 } |
489 printer->Outdent(); | 502 } |
490 printer->Outdent(); | |
491 printer->Print( | |
492 " };\n" | |
493 " return offsets;\n" | |
494 "}\n" | |
495 "\n"); | |
496 | 503 |
497 printer->Print( | 504 printer->Outdent(); |
498 "static const ::google::protobuf::internal::MigrationSchema schemas[]
= {\n"); | 505 printer->Print( |
499 printer->Indent(); | 506 "}\n" |
500 { | 507 "\n"); |
501 int offset = 0; | |
502 for (int i = 0; i < message_generators_.size(); i++) { | |
503 message_generators_[i]->GenerateSchema(printer, offset, | |
504 pairs[i].second); | |
505 offset += pairs[i].first; | |
506 } | |
507 } | |
508 printer->Outdent(); | |
509 printer->Print( | |
510 "};\n" | |
511 "\n" | |
512 "static const ::google::protobuf::internal::DefaultInstanceData " | |
513 "file_default_instances[] = {\n"); | |
514 printer->Indent(); | |
515 for (int i = 0; i < message_generators_.size(); i++) { | |
516 const Descriptor* descriptor = message_generators_[i]->descriptor_; | |
517 if (IsMapEntryMessage(descriptor)) continue; | |
518 | |
519 string oneof_default = "NULL"; | |
520 if (message_generators_[i]->descriptor_->oneof_decl_count()) { | |
521 oneof_default = | |
522 "&" + ClassName(descriptor, false) + "_default_oneof_instance_"; | |
523 } | |
524 printer->Print( | |
525 "{reinterpret_cast<const " | |
526 "::google::protobuf::Message*>(&_$classname$_default_instance_), " | |
527 "$oneof_default$},\n", | |
528 "classname", ClassName(descriptor, false), "oneof_default", | |
529 oneof_default); | |
530 } | |
531 printer->Outdent(); | |
532 printer->Print( | |
533 "};\n" | |
534 "\n"); | |
535 } else { | |
536 // we still need these symbols to exist | |
537 printer->Print( | |
538 "inline ::google::protobuf::uint32* $offsetfunname$() { return NULL; }
\n" | |
539 "static const ::google::protobuf::internal::MigrationSchema* schemas =
NULL;\n" | |
540 "static const ::google::protobuf::internal::DefaultInstanceData* " | |
541 "file_default_instances = NULL;\n", | |
542 "offsetfunname", | |
543 GlobalOffsetTableName(file_->name())); | |
544 } | |
545 | 508 |
546 // --------------------------------------------------------------- | 509 // --------------------------------------------------------------- |
547 | 510 |
548 // protobuf_AssignDescriptorsOnce(): The first time it is called, calls | 511 // protobuf_AssignDescriptorsOnce(): The first time it is called, calls |
549 // AssignDescriptors(). All later times, waits for the first call to | 512 // AssignDescriptors(). All later times, waits for the first call to |
550 // complete and then returns. | 513 // complete and then returns. |
551 string message_factory = "NULL"; | |
552 printer->Print( | 514 printer->Print( |
553 "namespace {\n" | 515 "namespace {\n" |
554 "\n" | 516 "\n" |
555 "void protobuf_AssignDescriptors() {\n" | 517 "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n" |
556 // Make sure the file has found its way into the pool. If a descriptor | 518 "inline void protobuf_AssignDescriptorsOnce() {\n" |
557 // is requested *during* static init then AddDescriptors() may not have | 519 " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n
" |
558 // been called yet, so we call it manually. Note that it's fine if | 520 " &$assigndescriptorsname$);\n" |
559 // AddDescriptors() is called multiple times. | 521 "}\n" |
560 " $adddescriptorsname$();\n" | 522 "\n", |
561 " ::google::protobuf::MessageFactory* factory = $factory$;\n" | 523 "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name())); |
562 " AssignDescriptors(\n" | |
563 " \"$filename$\", schemas, file_default_instances, " | |
564 "$offsetfunname$(), factory,\n" | |
565 " $metadata$, $enum_descriptors$, $service_descriptors$);\n" | |
566 "}\n" | |
567 "\n" | |
568 "void protobuf_AssignDescriptorsOnce() {\n" | |
569 " static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n" | |
570 " ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors
);\n" | |
571 "}\n" | |
572 "\n", | |
573 "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), | |
574 "offsetfunname", GlobalOffsetTableName(file_->name()), "filename", | |
575 file_->name(), "metadata", | |
576 !message_generators_.empty() ? "file_level_metadata" : "NULL", | |
577 "enum_descriptors", | |
578 !enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL", | |
579 "service_descriptors", | |
580 HasGenericServices(file_, options_) && file_->service_count() > 0 | |
581 ? "file_level_service_descriptors" | |
582 : "NULL", | |
583 "factory", message_factory); | |
584 | 524 |
585 // Only here because of useless string reference that we don't want in | 525 // protobuf_RegisterTypes(): Calls |
586 // protobuf_AssignDescriptorsOnce, because that is called from all the | 526 // MessageFactory::InternalRegisterGeneratedType() for each message type. |
587 // GetMetadata member methods. | |
588 printer->Print( | 527 printer->Print( |
589 "void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD
;\n" | 528 "void protobuf_RegisterTypes(const ::std::string&) {\n" |
590 "void protobuf_RegisterTypes(const ::std::string&) {\n" | 529 " protobuf_AssignDescriptorsOnce();\n"); |
591 " protobuf_AssignDescriptorsOnce();\n"); | |
592 printer->Indent(); | 530 printer->Indent(); |
593 | 531 |
594 // All normal messages can be done generically | 532 for (int i = 0; i < file_->message_type_count(); i++) { |
595 if (!message_generators_.empty()) { | |
596 printer->Print( | |
597 "::google::protobuf::internal::RegisterAllTypes(file_level_metadata, $si
ze$);\n", | |
598 "size", SimpleItoa(message_generators_.size())); | |
599 } | |
600 | |
601 // Map types are treated special | |
602 // TODO(gerbens) find a way to treat maps more like normal messages. | |
603 for (int i = 0; i < message_generators_.size(); i++) { | |
604 message_generators_[i]->GenerateTypeRegistrations(printer); | 533 message_generators_[i]->GenerateTypeRegistrations(printer); |
605 } | 534 } |
606 | 535 |
607 printer->Outdent(); | 536 printer->Outdent(); |
608 printer->Print( | 537 printer->Print( |
609 "}\n" | 538 "}\n" |
610 "\n" | 539 "\n" |
611 "} // namespace\n"); | 540 "} // namespace\n"); |
612 } | 541 } |
613 | 542 |
614 // ----------------------------------------------------------------- | 543 // ----------------------------------------------------------------- |
615 | 544 |
616 // ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown. | 545 // ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown. |
617 printer->Print( | 546 printer->Print( |
618 "\n" | 547 "\n" |
619 "void $shutdownfilename$() {\n", | 548 "void $shutdownfilename$() {\n", |
620 "shutdownfilename", GlobalShutdownFileName(file_->name())); | 549 "shutdownfilename", GlobalShutdownFileName(file_->name())); |
621 printer->Indent(); | 550 printer->Indent(); |
622 | 551 |
623 for (int i = 0; i < message_generators_.size(); i++) { | 552 for (int i = 0; i < file_->message_type_count(); i++) { |
624 message_generators_[i]->GenerateShutdownCode(printer); | 553 message_generators_[i]->GenerateShutdownCode(printer); |
625 } | 554 } |
626 | 555 |
627 printer->Outdent(); | 556 printer->Outdent(); |
628 printer->Print( | 557 printer->Print( |
629 "}\n\n"); | 558 "}\n\n"); |
630 | 559 |
631 // ----------------------------------------------------------------- | 560 // ----------------------------------------------------------------- |
632 | 561 |
633 // Now generate the InitDefaults() function. | 562 // Now generate the AddDescriptors() function. |
634 printer->Print( | 563 PrintHandlingOptionalStaticInitializers( |
635 "void $initdefaultsname$_impl() {\n" | 564 file_, options_, printer, |
636 " GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n" | 565 // With static initializers. |
637 "", | 566 // Note that we don't need any special synchronization in the following |
| 567 // code |
| 568 // because it is called at static init time before any threads exist. |
| 569 "void $adddescriptorsname$() {\n" |
| 570 " static bool already_here = false;\n" |
| 571 " if (already_here) return;\n" |
| 572 " already_here = true;\n" |
| 573 " GOOGLE_PROTOBUF_VERIFY_VERSION;\n" |
| 574 "\n", |
| 575 // Without. |
| 576 "void $adddescriptorsname$_impl() {\n" |
| 577 " GOOGLE_PROTOBUF_VERIFY_VERSION;\n" |
| 578 "\n", |
638 // Vars. | 579 // Vars. |
639 "initdefaultsname", GlobalInitDefaultsName(file_->name())); | 580 "adddescriptorsname", GlobalAddDescriptorsName(file_->name())); |
640 | 581 |
641 printer->Indent(); | 582 printer->Indent(); |
642 | 583 |
643 // Call the InitDefaults() methods for all of our dependencies, to make | 584 // Call the AddDescriptors() methods for all of our dependencies, to make |
644 // sure they get added first. | 585 // sure they get added first. |
645 for (int i = 0; i < file_->dependency_count(); i++) { | 586 for (int i = 0; i < file_->dependency_count(); i++) { |
646 const FileDescriptor* dependency = file_->dependency(i); | 587 const FileDescriptor* dependency = file_->dependency(i); |
647 // Print the namespace prefix for the dependency. | 588 // Print the namespace prefix for the dependency. |
648 string add_desc_name = QualifiedFileLevelSymbol( | 589 string add_desc_name = QualifiedFileLevelSymbol( |
649 dependency->package(), GlobalInitDefaultsName(dependency->name())); | 590 dependency->package(), GlobalAddDescriptorsName(dependency->name())); |
650 // Call its AddDescriptors function. | 591 // Call its AddDescriptors function. |
651 printer->Print( | 592 printer->Print( |
652 "$name$();\n", | 593 "$name$();\n", |
653 "name", add_desc_name); | 594 "name", add_desc_name); |
654 } | 595 } |
655 | 596 |
656 // Force initialization of primitive values we depend on. | |
657 printer->Print("::google::protobuf::internal::InitProtobufDefaults();\n"); | |
658 | |
659 // Allocate and initialize default instances. This can't be done lazily | |
660 // since default instances are returned by simple accessors and are used with | |
661 // extensions. Speaking of which, we also register extensions at this time. | |
662 for (int i = 0; i < message_generators_.size(); i++) { | |
663 message_generators_[i]->GenerateDefaultInstanceAllocator(printer); | |
664 } | |
665 for (int i = 0; i < extension_generators_.size(); i++) { | |
666 extension_generators_[i]->GenerateRegistration(printer); | |
667 } | |
668 for (int i = 0; i < message_generators_.size(); i++) { | |
669 message_generators_[i]->GenerateDefaultInstanceInitializer(printer); | |
670 } | |
671 printer->Outdent(); | |
672 printer->Print( | |
673 "}\n" | |
674 "\n" | |
675 "void $initdefaultsname$() {\n" | |
676 " static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n" | |
677 " ::google::protobuf::GoogleOnceInit(&once, &$initdefaultsname$_impl);\n" | |
678 "}\n", | |
679 "initdefaultsname", GlobalInitDefaultsName(file_->name())); | |
680 | |
681 // ----------------------------------------------------------------- | |
682 | |
683 // Now generate the AddDescriptors() function. | |
684 printer->Print( | |
685 "void $adddescriptorsname$_impl() {\n" | |
686 " $initdefaultsname$();\n", | |
687 // Vars. | |
688 "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), | |
689 "initdefaultsname", GlobalInitDefaultsName(file_->name())); | |
690 | |
691 printer->Indent(); | |
692 if (HasDescriptorMethods(file_, options_)) { | 597 if (HasDescriptorMethods(file_, options_)) { |
693 // Embed the descriptor. We simply serialize the entire | 598 // Embed the descriptor. We simply serialize the entire FileDescriptorProto |
694 // FileDescriptorProto | |
695 // and embed it as a string literal, which is parsed and built into real | 599 // and embed it as a string literal, which is parsed and built into real |
696 // descriptors at initialization time. | 600 // descriptors at initialization time. |
697 FileDescriptorProto file_proto; | 601 FileDescriptorProto file_proto; |
698 file_->CopyTo(&file_proto); | 602 file_->CopyTo(&file_proto); |
699 string file_data; | 603 string file_data; |
700 file_proto.SerializeToString(&file_data); | 604 file_proto.SerializeToString(&file_data); |
701 | 605 |
702 printer->Print("static const char descriptor[] = {\n"); | |
703 printer->Indent(); | |
704 | |
705 #ifdef _MSC_VER | 606 #ifdef _MSC_VER |
706 bool breakdown_large_file = true; | 607 bool breakdown_large_file = true; |
707 #else | 608 #else |
708 bool breakdown_large_file = false; | 609 bool breakdown_large_file = false; |
709 #endif | 610 #endif |
710 if (breakdown_large_file && file_data.size() > 66538) { | 611 // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535 |
711 // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535 | 612 // bytes in length". Declare a static array of characters rather than use a |
712 // bytes in length". Declare a static array of characters rather than use | 613 // string literal. |
713 // a string literal. Only write 25 bytes per line. | 614 if (breakdown_large_file && file_data.size() > 65535) { |
| 615 // This has to be explicitly marked as a signed char because the generated |
| 616 // code puts negative values in the array, and sometimes plain char is |
| 617 // unsigned. That implicit narrowing conversion is not allowed in C++11. |
| 618 // <http://stackoverflow.com/questions/4434140/narrowing-conversions-in-c0
x-is-it-just-me-or-does-this-sound-like-a-breakin> |
| 619 // has details on why. |
| 620 printer->Print( |
| 621 "static const signed char descriptor[] = {\n"); |
| 622 printer->Indent(); |
| 623 |
| 624 // Only write 25 bytes per line. |
714 static const int kBytesPerLine = 25; | 625 static const int kBytesPerLine = 25; |
715 for (int i = 0; i < file_data.size();) { | 626 for (int i = 0; i < file_data.size();) { |
716 for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) { | 627 for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) { |
717 printer->Print("'$char$', ", "char", | 628 printer->Print( |
718 CEscape(file_data.substr(i, 1))); | 629 "$char$, ", |
719 } | 630 "char", SimpleItoa(file_data[i])); |
720 printer->Print("\n"); | 631 } |
| 632 printer->Print( |
| 633 "\n"); |
721 } | 634 } |
| 635 |
| 636 printer->Outdent(); |
| 637 printer->Print( |
| 638 "};\n"); |
| 639 |
| 640 printer->Print( |
| 641 "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(descript
or, $size$);\n", |
| 642 "size", SimpleItoa(file_data.size())); |
| 643 |
722 } else { | 644 } else { |
| 645 printer->Print( |
| 646 "::google::protobuf::DescriptorPool::InternalAddGeneratedFile("); |
| 647 |
723 // Only write 40 bytes per line. | 648 // Only write 40 bytes per line. |
724 static const int kBytesPerLine = 40; | 649 static const int kBytesPerLine = 40; |
725 for (int i = 0; i < file_data.size(); i += kBytesPerLine) { | 650 for (int i = 0; i < file_data.size(); i += kBytesPerLine) { |
726 printer->Print(" \"$data$\"\n", "data", | 651 printer->Print("\n \"$data$\"", |
727 EscapeTrigraphs(CEscape( | 652 "data", |
728 file_data.substr(i, kBytesPerLine)))); | 653 EscapeTrigraphs( |
729 } | 654 CEscape(file_data.substr(i, kBytesPerLine)))); |
730 } | 655 } |
731 | |
732 printer->Outdent(); | |
733 printer->Print("};\n"); | |
734 printer->Print( | 656 printer->Print( |
735 "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(\n" | 657 ", $size$);\n", |
736 " descriptor, $size$);\n", | |
737 "size", SimpleItoa(file_data.size())); | 658 "size", SimpleItoa(file_data.size())); |
| 659 } |
738 | 660 |
739 // Call MessageFactory::InternalRegisterGeneratedFile(). | 661 // Call MessageFactory::InternalRegisterGeneratedFile(). |
740 printer->Print( | 662 printer->Print( |
741 "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n" | 663 "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n" |
742 " \"$filename$\", &protobuf_RegisterTypes);\n", | 664 " \"$filename$\", &protobuf_RegisterTypes);\n", |
743 "filename", file_->name()); | 665 "filename", file_->name()); |
744 } | 666 } |
745 | 667 |
746 // Call the AddDescriptors() methods for all of our dependencies, to make | 668 // Allocate and initialize default instances. This can't be done lazily |
747 // sure they get added first. | 669 // since default instances are returned by simple accessors and are used with |
748 for (int i = 0; i < file_->dependency_count(); i++) { | 670 // extensions. Speaking of which, we also register extensions at this time. |
749 const FileDescriptor* dependency = file_->dependency(i); | 671 for (int i = 0; i < file_->message_type_count(); i++) { |
750 // Print the namespace prefix for the dependency. | 672 message_generators_[i]->GenerateDefaultInstanceAllocator(printer); |
751 string add_desc_name = QualifiedFileLevelSymbol( | 673 } |
752 dependency->package(), GlobalAddDescriptorsName(dependency->name())); | 674 for (int i = 0; i < file_->extension_count(); i++) { |
753 // Call its AddDescriptors function. | 675 extension_generators_[i]->GenerateRegistration(printer); |
754 printer->Print("$adddescriptorsname$();\n", "adddescriptorsname", | 676 } |
755 add_desc_name); | 677 for (int i = 0; i < file_->message_type_count(); i++) { |
| 678 message_generators_[i]->GenerateDefaultInstanceInitializer(printer); |
756 } | 679 } |
757 | 680 |
758 printer->Print( | 681 printer->Print( |
759 "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n", | 682 "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n", |
760 "shutdownfilename", GlobalShutdownFileName(file_->name())); | 683 "shutdownfilename", GlobalShutdownFileName(file_->name())); |
761 | 684 |
762 printer->Outdent(); | 685 printer->Outdent(); |
763 printer->Print( | 686 printer->Print( |
764 "}\n" | 687 "}\n" |
765 "\n" | 688 "\n"); |
766 "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n" | |
767 "void $adddescriptorsname$() {\n" | |
768 " ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n" | |
769 " &$adddescriptorsname$_impl);\n" | |
770 "}\n", | |
771 "adddescriptorsname", GlobalAddDescriptorsName(file_->name())); | |
772 | 689 |
773 if (!StaticInitializersForced(file_, options_)) { | 690 PrintHandlingOptionalStaticInitializers( |
774 printer->Print("#ifndef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"); | 691 file_, options_, printer, |
775 } | |
776 printer->Print( | |
777 // With static initializers. | 692 // With static initializers. |
778 "// Force AddDescriptors() to be called at static initialization time.\n" | 693 "// Force AddDescriptors() to be called at static initialization time.\n" |
779 "struct StaticDescriptorInitializer_$filename$ {\n" | 694 "struct StaticDescriptorInitializer_$filename$ {\n" |
780 " StaticDescriptorInitializer_$filename$() {\n" | 695 " StaticDescriptorInitializer_$filename$() {\n" |
781 " $adddescriptorsname$();\n" | 696 " $adddescriptorsname$();\n" |
782 " }\n" | 697 " }\n" |
783 "} static_descriptor_initializer_$filename$_;\n", | 698 "} static_descriptor_initializer_$filename$_;\n", |
| 699 // Without. |
| 700 "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n" |
| 701 "void $adddescriptorsname$() {\n" |
| 702 " ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n" |
| 703 " &$adddescriptorsname$_impl);\n" |
| 704 "}\n", |
784 // Vars. | 705 // Vars. |
785 "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), "filename", | 706 "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), "filename", |
786 FilenameIdentifier(file_->name())); | 707 FilenameIdentifier(file_->name())); |
787 if (!StaticInitializersForced(file_, options_)) { | |
788 printer->Print("#endif // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"); | |
789 } | |
790 } | 708 } |
791 | 709 |
792 void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) { | 710 void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) { |
793 if (package_parts_.size() > 0) printer->Print("\n"); | 711 if (package_parts_.size() > 0) printer->Print("\n"); |
794 | 712 |
795 for (int i = 0; i < package_parts_.size(); i++) { | 713 for (int i = 0; i < package_parts_.size(); i++) { |
796 printer->Print("namespace $part$ {\n", | 714 printer->Print("namespace $part$ {\n", |
797 "part", package_parts_[i]); | 715 "part", package_parts_[i]); |
798 } | 716 } |
799 } | 717 } |
800 | 718 |
801 void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) { | 719 void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) { |
802 if (package_parts_.size() > 0) printer->Print("\n"); | 720 if (package_parts_.size() > 0) printer->Print("\n"); |
803 | 721 |
804 for (int i = package_parts_.size() - 1; i >= 0; i--) { | 722 for (int i = package_parts_.size() - 1; i >= 0; i--) { |
805 printer->Print("} // namespace $part$\n", | 723 printer->Print("} // namespace $part$\n", |
806 "part", package_parts_[i]); | 724 "part", package_parts_[i]); |
807 } | 725 } |
808 } | 726 } |
809 | 727 |
810 void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) { | 728 void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) { |
811 ForwardDeclarations decls; | 729 ForwardDeclarations decls; |
812 for (int i = 0; i < file_->dependency_count(); i++) { | 730 for (int i = 0; i < file_->dependency_count(); i++) { |
813 FileGenerator dependency(file_->dependency(i), options_); | 731 FileGenerator dependency(file_->dependency(i), options_); |
814 dependency.FillForwardDeclarations(&decls); | 732 dependency.FillForwardDeclarations(&decls); |
815 } | 733 } |
816 FillForwardDeclarations(&decls); | 734 FillForwardDeclarations(&decls); |
817 decls.Print(printer, options_); | 735 decls.Print(printer); |
818 } | 736 } |
819 | 737 |
820 void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) { | 738 void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) { |
821 for (int i = 0; i < file_->public_dependency_count(); i++) { | 739 for (int i = 0; i < file_->public_dependency_count(); i++) { |
822 FileGenerator dependency(file_->public_dependency(i), options_); | 740 FileGenerator dependency(file_->public_dependency(i), options_); |
823 dependency.FillForwardDeclarations(decls); | 741 dependency.FillForwardDeclarations(decls); |
824 } | 742 } |
825 for (int i = 0; i < package_parts_.size(); i++) { | 743 for (int i = 0; i < package_parts_.size(); i++) { |
826 decls = decls->AddOrGetNamespace(package_parts_[i]); | 744 decls = decls->AddOrGetNamespace(package_parts_[i]); |
827 } | 745 } |
828 // Generate enum definitions. | 746 // Generate enum definitions. |
829 for (int i = 0; i < enum_generators_.size(); i++) { | 747 for (int i = 0; i < file_->message_type_count(); i++) { |
| 748 message_generators_[i]->FillEnumForwardDeclarations(&decls->enums()); |
| 749 } |
| 750 for (int i = 0; i < file_->enum_type_count(); i++) { |
830 enum_generators_[i]->FillForwardDeclaration(&decls->enums()); | 751 enum_generators_[i]->FillForwardDeclaration(&decls->enums()); |
831 } | 752 } |
832 // Generate forward declarations of classes. | 753 // Generate forward declarations of classes. |
833 for (int i = 0; i < message_generators_.size(); i++) { | 754 for (int i = 0; i < file_->message_type_count(); i++) { |
834 message_generators_[i]->FillMessageForwardDeclarations( | 755 message_generators_[i]->FillMessageForwardDeclarations( |
835 &decls->classes()); | 756 &decls->classes()); |
836 } | 757 } |
837 } | 758 } |
838 | 759 |
839 void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer, | 760 void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer, |
840 const string& filename_identifier) { | 761 const string& filename_identifier) { |
841 // Generate top of header. | 762 // Generate top of header. |
842 printer->Print( | 763 printer->Print( |
843 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" | 764 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 "#endif\n" | 800 "#endif\n" |
880 "\n", | 801 "\n", |
881 "min_header_version", | 802 "min_header_version", |
882 SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc), | 803 SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc), |
883 "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION)); | 804 "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION)); |
884 | 805 |
885 // OK, it's now safe to #include other files. | 806 // OK, it's now safe to #include other files. |
886 printer->Print( | 807 printer->Print( |
887 "#include <google/protobuf/arena.h>\n" | 808 "#include <google/protobuf/arena.h>\n" |
888 "#include <google/protobuf/arenastring.h>\n" | 809 "#include <google/protobuf/arenastring.h>\n" |
889 "#include <google/protobuf/generated_message_util.h>\n" | 810 "#include <google/protobuf/generated_message_util.h>\n"); |
890 "#include <google/protobuf/metadata.h>\n"); | 811 if (UseUnknownFieldSet(file_, options_)) { |
891 | 812 printer->Print( |
892 if (!message_generators_.empty()) { | 813 "#include <google/protobuf/metadata.h>\n"); |
| 814 } |
| 815 if (file_->message_type_count() > 0) { |
893 if (HasDescriptorMethods(file_, options_)) { | 816 if (HasDescriptorMethods(file_, options_)) { |
894 printer->Print( | 817 printer->Print( |
895 "#include <google/protobuf/message.h>\n"); | 818 "#include <google/protobuf/message.h>\n"); |
896 } else { | 819 } else { |
897 printer->Print( | 820 printer->Print( |
898 "#include <google/protobuf/message_lite.h>\n"); | 821 "#include <google/protobuf/message_lite.h>\n"); |
899 } | 822 } |
900 } | 823 } |
901 printer->Print( | 824 printer->Print( |
902 "#include <google/protobuf/repeated_field.h>" | 825 "#include <google/protobuf/repeated_field.h>\n" |
903 " // IWYU pragma: export\n" | 826 "#include <google/protobuf/extension_set.h>\n"); |
904 "#include <google/protobuf/extension_set.h>" | |
905 " // IWYU pragma: export\n"); | |
906 if (HasMapFields(file_)) { | 827 if (HasMapFields(file_)) { |
907 printer->Print( | 828 printer->Print( |
908 "#include <google/protobuf/map.h>\n"); | 829 "#include <google/protobuf/map.h>\n"); |
909 if (HasDescriptorMethods(file_, options_)) { | 830 if (HasDescriptorMethods(file_, options_)) { |
910 printer->Print( | 831 printer->Print( |
911 "#include <google/protobuf/map_field_inl.h>\n"); | 832 "#include <google/protobuf/map_field_inl.h>\n"); |
912 } else { | 833 } else { |
913 printer->Print( | 834 printer->Print( |
914 "#include <google/protobuf/map_field_lite.h>\n"); | 835 "#include <google/protobuf/map_field_lite.h>\n"); |
915 } | 836 } |
916 } | 837 } |
917 | 838 |
918 if (HasEnumDefinitions(file_)) { | 839 if (HasEnumDefinitions(file_)) { |
919 if (HasDescriptorMethods(file_, options_)) { | 840 if (HasDescriptorMethods(file_, options_)) { |
920 printer->Print( | 841 printer->Print( |
921 "#include <google/protobuf/generated_enum_reflection.h>\n"); | 842 "#include <google/protobuf/generated_enum_reflection.h>\n"); |
922 } else { | 843 } else { |
923 printer->Print( | 844 printer->Print( |
924 "#include <google/protobuf/generated_enum_util.h>\n"); | 845 "#include <google/protobuf/generated_enum_util.h>\n"); |
925 } | 846 } |
926 } | 847 } |
927 | 848 |
928 if (HasGenericServices(file_, options_)) { | 849 if (HasGenericServices(file_, options_)) { |
929 printer->Print( | 850 printer->Print( |
930 "#include <google/protobuf/service.h>\n"); | 851 "#include <google/protobuf/service.h>\n"); |
931 } | 852 } |
932 | 853 |
933 if (UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) { | 854 if (UseUnknownFieldSet(file_, options_) && file_->message_type_count() > 0) { |
934 printer->Print( | 855 printer->Print( |
935 "#include <google/protobuf/unknown_field_set.h>\n"); | 856 "#include <google/protobuf/unknown_field_set.h>\n"); |
936 } | 857 } |
937 | 858 |
938 | 859 |
939 if (IsAnyMessage(file_)) { | 860 if (IsAnyMessage(file_)) { |
940 printer->Print( | 861 printer->Print( |
941 "#include <google/protobuf/any.h>\n"); | 862 "#include <google/protobuf/any.h>\n"); |
942 } | 863 } |
943 } | 864 } |
944 | 865 |
945 void FileGenerator::GenerateMetadataPragma(io::Printer* printer, | 866 void FileGenerator::GenerateMetadataPragma(io::Printer* printer, |
946 const string& info_path) { | 867 const string& info_path) { |
947 if (!info_path.empty() && !options_.annotation_pragma_name.empty() && | 868 if (!info_path.empty() && !options_.annotation_pragma_name.empty() && |
948 !options_.annotation_guard_name.empty()) { | 869 !options_.annotation_guard_name.empty()) { |
949 printer->Print( | 870 printer->Print( |
950 "#ifdef $guard$\n" | 871 "#ifdef $guard$\n" |
951 "#pragma $pragma$ \"$info_path$\"\n" | 872 "#pragma $pragma$ \"$info_path$\"\n" |
952 "#endif // $guard$\n", | 873 "#endif // $guard$\n", |
953 "guard", options_.annotation_guard_name, "pragma", | 874 "guard", options_.annotation_guard_name, "pragma", |
954 options_.annotation_pragma_name, "info_path", info_path); | 875 options_.annotation_pragma_name, "info_path", info_path); |
955 } | 876 } |
956 } | 877 } |
957 | 878 |
958 void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) { | 879 void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) { |
959 std::set<string> public_import_names; | 880 set<string> public_import_names; |
960 for (int i = 0; i < file_->public_dependency_count(); i++) { | 881 for (int i = 0; i < file_->public_dependency_count(); i++) { |
961 public_import_names.insert(file_->public_dependency(i)->name()); | 882 public_import_names.insert(file_->public_dependency(i)->name()); |
962 } | 883 } |
963 | 884 |
964 for (int i = 0; i < file_->dependency_count(); i++) { | 885 for (int i = 0; i < file_->dependency_count(); i++) { |
965 const bool use_system_include = IsWellKnownMessage(file_->dependency(i)); | 886 const bool use_system_include = IsWellKnownMessage(file_->dependency(i)); |
966 const string& name = file_->dependency(i)->name(); | 887 const string& name = file_->dependency(i)->name(); |
967 bool public_import = (public_import_names.count(name) != 0); | 888 bool public_import = (public_import_names.count(name) != 0); |
968 | 889 |
969 | 890 |
970 printer->Print( | 891 printer->Print( |
971 "#include $left$$dependency$.pb.h$right$$iwyu$\n", | 892 "#include $left$$dependency$.pb.h$right$$iwyu$\n", |
972 "dependency", StripProto(name), | 893 "dependency", StripProto(name), |
973 "iwyu", (public_import) ? " // IWYU pragma: export" : "", | 894 "iwyu", (public_import) ? " // IWYU pragma: export" : "", |
974 "left", use_system_include ? "<" : "\"", | 895 "left", use_system_include ? "<" : "\"", |
975 "right", use_system_include ? ">" : "\""); | 896 "right", use_system_include ? ">" : "\""); |
976 } | 897 } |
977 } | 898 } |
978 | 899 |
979 void FileGenerator::GenerateGlobalStateFunctionDeclarations( | 900 void FileGenerator::GenerateGlobalStateFunctionDeclarations( |
980 io::Printer* printer) { | 901 io::Printer* printer) { |
981 // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile | 902 // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile |
982 // functions, so that we can declare them to be friends of each class. | 903 // functions, so that we can declare them to be friends of each class. |
983 printer->Print( | 904 printer->Print( |
984 "\n" | 905 "\n" |
985 "// Internal implementation detail -- do not call these.\n" | 906 "// Internal implementation detail -- do not call these.\n" |
986 "void $dllexport_decl$$adddescriptorsname$();\n" | 907 "void $dllexport_decl$$adddescriptorsname$();\n", |
987 "void $dllexport_decl$$initdefaultsname$();\n", | 908 "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), |
988 "initdefaultsname", GlobalInitDefaultsName(file_->name()), | 909 "dllexport_decl", |
989 "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), | 910 options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); |
990 "dllexport_decl", | 911 |
991 options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); | 912 printer->Print( |
| 913 // Note that we don't put dllexport_decl on these because they are only |
| 914 // called by the .pb.cc file in which they are defined. |
| 915 "void $assigndescriptorsname$();\n" |
| 916 "void $shutdownfilename$();\n" |
| 917 "\n", |
| 918 "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()), |
| 919 "shutdownfilename", GlobalShutdownFileName(file_->name())); |
| 920 } |
| 921 |
| 922 void FileGenerator::GenerateMessageForwardDeclarations(io::Printer* printer) { |
| 923 map<string, const Descriptor*> classes; |
| 924 for (int i = 0; i < file_->message_type_count(); i++) { |
| 925 message_generators_[i]->FillMessageForwardDeclarations(&classes); |
| 926 } |
| 927 for (map<string, const Descriptor *>::const_iterator it = classes.begin(), |
| 928 end = classes.end(); |
| 929 it != end; ++it) { |
| 930 printer->Print("class $classname$;\n", "classname", it->first); |
| 931 printer->Annotate("classname", it->second); |
| 932 } |
992 } | 933 } |
993 | 934 |
994 void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) { | 935 void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) { |
995 // Generate class definitions. | 936 // Generate class definitions. |
996 for (int i = 0; i < message_generators_.size(); i++) { | 937 for (int i = 0; i < file_->message_type_count(); i++) { |
997 if (i > 0) { | 938 if (i > 0) { |
998 printer->Print("\n"); | 939 printer->Print("\n"); |
999 printer->Print(kThinSeparator); | 940 printer->Print(kThinSeparator); |
1000 printer->Print("\n"); | 941 printer->Print("\n"); |
1001 } | 942 } |
1002 message_generators_[i]->GenerateClassDefinition(printer); | 943 message_generators_[i]->GenerateClassDefinition(printer); |
1003 } | 944 } |
1004 } | 945 } |
1005 | 946 |
1006 void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) { | 947 void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) { |
1007 // Generate enum definitions. | 948 // Generate enum definitions. |
1008 for (int i = 0; i < enum_generators_.size(); i++) { | 949 for (int i = 0; i < file_->message_type_count(); i++) { |
| 950 message_generators_[i]->GenerateEnumDefinitions(printer); |
| 951 } |
| 952 for (int i = 0; i < file_->enum_type_count(); i++) { |
1009 enum_generators_[i]->GenerateDefinition(printer); | 953 enum_generators_[i]->GenerateDefinition(printer); |
1010 } | 954 } |
1011 } | 955 } |
1012 | 956 |
1013 void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) { | 957 void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) { |
1014 if (HasGenericServices(file_, options_)) { | 958 if (HasGenericServices(file_, options_)) { |
1015 // Generate service definitions. | 959 // Generate service definitions. |
1016 for (int i = 0; i < service_generators_.size(); i++) { | 960 for (int i = 0; i < file_->service_count(); i++) { |
1017 if (i > 0) { | 961 if (i > 0) { |
1018 printer->Print("\n"); | 962 printer->Print("\n"); |
1019 printer->Print(kThinSeparator); | 963 printer->Print(kThinSeparator); |
1020 printer->Print("\n"); | 964 printer->Print("\n"); |
1021 } | 965 } |
1022 service_generators_[i]->GenerateDeclarations(printer); | 966 service_generators_[i]->GenerateDeclarations(printer); |
1023 } | 967 } |
1024 | 968 |
1025 printer->Print("\n"); | 969 printer->Print("\n"); |
1026 printer->Print(kThickSeparator); | 970 printer->Print(kThickSeparator); |
1027 printer->Print("\n"); | 971 printer->Print("\n"); |
1028 } | 972 } |
1029 } | 973 } |
1030 | 974 |
1031 void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) { | 975 void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) { |
1032 // Declare extension identifiers. These are in global scope and so only | 976 // Declare extension identifiers. |
1033 // the global scope extensions. | |
1034 for (int i = 0; i < file_->extension_count(); i++) { | 977 for (int i = 0; i < file_->extension_count(); i++) { |
1035 extension_generators_owner_[i]->GenerateDeclaration(printer); | 978 extension_generators_[i]->GenerateDeclaration(printer); |
1036 } | 979 } |
1037 } | 980 } |
1038 | 981 |
1039 void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) { | 982 void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) { |
1040 // An aside about inline functions in .proto.h mode: | 983 // An aside about inline functions in .proto.h mode: |
1041 // | 984 // |
1042 // The PROTOBUF_INLINE_NOT_IN_HEADERS symbol controls conditionally | 985 // The PROTOBUF_INLINE_NOT_IN_HEADERS symbol controls conditionally |
1043 // moving much of the inline functions to the .pb.cc file, which can be a | 986 // moving much of the inline functions to the .pb.cc file, which can be a |
1044 // significant performance benefit for compilation time, at the expense | 987 // significant performance benefit for compilation time, at the expense |
1045 // of non-inline function calls. | 988 // of non-inline function calls. |
(...skipping 20 matching lines...) Expand all Loading... |
1066 // 3. Functions on the message that are used by the dependent base: the | 1009 // 3. Functions on the message that are used by the dependent base: the |
1067 // dependent base class down casts itself to the message | 1010 // dependent base class down casts itself to the message |
1068 // implementation class to access these functions (the has_* bit | 1011 // implementation class to access these functions (the has_* bit |
1069 // manipulation functions). Unlike #1, these functions must | 1012 // manipulation functions). Unlike #1, these functions must |
1070 // unconditionally remain in the header. These are emitted by | 1013 // unconditionally remain in the header. These are emitted by |
1071 // GenerateDependentInlineMethods, even though they are not actually | 1014 // GenerateDependentInlineMethods, even though they are not actually |
1072 // dependent. | 1015 // dependent. |
1073 | 1016 |
1074 printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); | 1017 printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); |
1075 // Generate class inline methods. | 1018 // Generate class inline methods. |
1076 for (int i = 0; i < message_generators_.size(); i++) { | 1019 for (int i = 0; i < file_->message_type_count(); i++) { |
1077 if (i > 0) { | 1020 if (i > 0) { |
1078 printer->Print(kThinSeparator); | 1021 printer->Print(kThinSeparator); |
1079 printer->Print("\n"); | 1022 printer->Print("\n"); |
1080 } | 1023 } |
1081 message_generators_[i]->GenerateInlineMethods(printer, | 1024 message_generators_[i]->GenerateInlineMethods(printer, |
1082 /* is_inline = */ true); | 1025 /* is_inline = */ true); |
1083 } | 1026 } |
1084 printer->Print("#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); | 1027 printer->Print("#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); |
1085 | 1028 |
1086 for (int i = 0; i < message_generators_.size(); i++) { | 1029 for (int i = 0; i < file_->message_type_count(); i++) { |
1087 if (i > 0) { | 1030 if (i > 0) { |
1088 printer->Print(kThinSeparator); | 1031 printer->Print(kThinSeparator); |
1089 printer->Print("\n"); | 1032 printer->Print("\n"); |
1090 } | 1033 } |
1091 // Methods of the dependent base class must always be inline in the header. | 1034 // Methods of the dependent base class must always be inline in the header. |
1092 message_generators_[i]->GenerateDependentInlineMethods(printer); | 1035 message_generators_[i]->GenerateDependentInlineMethods(printer); |
1093 } | 1036 } |
1094 } | 1037 } |
1095 | 1038 |
1096 void FileGenerator::GenerateProto2NamespaceEnumSpecializations( | 1039 void FileGenerator::GenerateProto2NamespaceEnumSpecializations( |
1097 io::Printer* printer) { | 1040 io::Printer* printer) { |
1098 // Emit GetEnumDescriptor specializations into google::protobuf namespace: | 1041 // Emit GetEnumDescriptor specializations into google::protobuf namespace: |
1099 if (HasEnumDefinitions(file_)) { | 1042 if (HasEnumDefinitions(file_)) { |
1100 // The SWIG conditional is to avoid a null-pointer dereference | 1043 // The SWIG conditional is to avoid a null-pointer dereference |
1101 // (bug 1984964) in swig-1.3.21 resulting from the following syntax: | 1044 // (bug 1984964) in swig-1.3.21 resulting from the following syntax: |
1102 // namespace X { void Y<Z::W>(); } | 1045 // namespace X { void Y<Z::W>(); } |
1103 // which appears in GetEnumDescriptor() specializations. | 1046 // which appears in GetEnumDescriptor() specializations. |
1104 printer->Print( | 1047 printer->Print( |
1105 "\n" | 1048 "\n" |
1106 "#ifndef SWIG\n" | 1049 "#ifndef SWIG\n" |
1107 "namespace google {\nnamespace protobuf {\n" | 1050 "namespace google {\nnamespace protobuf {\n" |
1108 "\n"); | 1051 "\n"); |
1109 for (int i = 0; i < enum_generators_.size(); i++) { | 1052 for (int i = 0; i < file_->message_type_count(); i++) { |
| 1053 message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); |
| 1054 } |
| 1055 for (int i = 0; i < file_->enum_type_count(); i++) { |
1110 enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); | 1056 enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); |
1111 } | 1057 } |
1112 printer->Print( | 1058 printer->Print( |
1113 "\n" | 1059 "\n" |
1114 "} // namespace protobuf\n} // namespace google\n" | 1060 "} // namespace protobuf\n} // namespace google\n" |
1115 "#endif // SWIG\n"); | 1061 "#endif // SWIG\n"); |
1116 } | 1062 } |
1117 } | 1063 } |
1118 | 1064 |
1119 } // namespace cpp | 1065 } // namespace cpp |
1120 } // namespace compiler | 1066 } // namespace compiler |
1121 } // namespace protobuf | 1067 } // namespace protobuf |
1122 } // namespace google | 1068 } // namespace google |
OLD | NEW |