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