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