diff options
Diffstat (limited to 'src/google/protobuf/compiler')
70 files changed, 3485 insertions, 3556 deletions
diff --git a/src/google/protobuf/compiler/annotation_test_util.cc b/src/google/protobuf/compiler/annotation_test_util.cc index cc8534cc..a0530b9a 100644 --- a/src/google/protobuf/compiler/annotation_test_util.cc +++ b/src/google/protobuf/compiler/annotation_test_util.cc @@ -31,9 +31,6 @@ #include <google/protobuf/compiler/annotation_test_util.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/command_line_interface.h> #include <google/protobuf/io/printer.h> diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc index 11d0f334..aaabd914 100644 --- a/src/google/protobuf/compiler/code_generator.cc +++ b/src/google/protobuf/compiler/code_generator.cc @@ -34,9 +34,9 @@ #include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/compiler/plugin.pb.h> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/plugin.pb.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/stubs/strutil.h> diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 7c45fe75..8380367f 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -58,9 +58,6 @@ #include <limits.h> //For PATH_MAX #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #ifdef __APPLE__ #include <mach-o/dyld.h> @@ -171,8 +168,7 @@ bool VerifyDirectoryExists(const string& path) { // directories listed in |filename|. bool TryCreateParentDirectory(const string& prefix, const string& filename) { // Recursively create parent directories to the output file. - std::vector<string> parts = - Split(filename, "/", true); + std::vector<string> parts = Split(filename, "/", true); string path_so_far = prefix; for (int i = 0; i < parts.size() - 1; i++) { path_so_far += parts[i]; @@ -440,7 +436,7 @@ class CommandLineInterface::MemoryOutputStream bool append_mode_; // StringOutputStream writing to data_. - google::protobuf::scoped_ptr<io::StringOutputStream> inner_; + std::unique_ptr<io::StringOutputStream> inner_; }; // ------------------------------------------------------------------- @@ -835,10 +831,10 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { std::vector<const FileDescriptor*> parsed_files; // null unless descriptor_set_in_names_.empty() - google::protobuf::scoped_ptr<DiskSourceTree> disk_source_tree; - google::protobuf::scoped_ptr<ErrorPrinter> error_collector; - google::protobuf::scoped_ptr<DescriptorPool> descriptor_pool; - google::protobuf::scoped_ptr<DescriptorDatabase> descriptor_database; + std::unique_ptr<DiskSourceTree> disk_source_tree; + std::unique_ptr<ErrorPrinter> error_collector; + std::unique_ptr<DescriptorPool> descriptor_pool; + std::unique_ptr<DescriptorDatabase> descriptor_database; if (descriptor_set_in_names_.empty()) { disk_source_tree.reset(new DiskSourceTree()); if (!InitializeDiskSourceTree(disk_source_tree.get())) { @@ -1395,8 +1391,7 @@ CommandLineInterface::InterpretArgument(const string& name, // with colons. Let's accept that syntax too just to make things more // intuitive. std::vector<string> parts = Split( - value, - CommandLineInterface::kPathSeparator, + value, CommandLineInterface::kPathSeparator, true); for (int i = 0; i < parts.size(); i++) { @@ -1421,7 +1416,7 @@ CommandLineInterface::InterpretArgument(const string& name, // Make sure disk path exists, warn otherwise. if (access(disk_path.c_str(), F_OK) < 0) { - // Try the original path; it may have just happed to have a '=' in it. + // Try the original path; it may have just happened to have a '=' in it. if (access(parts[i].c_str(), F_OK) < 0) { std::cerr << disk_path << ": warning: directory does not exist." << std::endl; @@ -1447,8 +1442,7 @@ CommandLineInterface::InterpretArgument(const string& name, } direct_dependencies_explicitly_set_ = true; - std::vector<string> direct = Split( - value, ":", true); + std::vector<string> direct = Split(value, ":", true); GOOGLE_DCHECK(direct_dependencies_.empty()); direct_dependencies_.insert(direct.begin(), direct.end()); @@ -1481,9 +1475,8 @@ CommandLineInterface::InterpretArgument(const string& name, } descriptor_set_in_names_ = Split( - value, - CommandLineInterface::kPathSeparator, - true); + value, CommandLineInterface::kPathSeparator, + true); } else if (name == "-o" || name == "--descriptor_set_out") { if (!descriptor_set_out_name_.empty()) { @@ -1629,7 +1622,6 @@ CommandLineInterface::InterpretArgument(const string& name, } mode_ = MODE_PRINT; print_mode_ = PRINT_FREE_FIELDS; - } else if (name == "--profile_path") { } else { // Some other flag. Look it up in the generators list. const GeneratorInfo* generator_info = @@ -1908,10 +1900,12 @@ bool CommandLineInterface::GeneratePluginOutput( string* error) { CodeGeneratorRequest request; CodeGeneratorResponse response; + string processed_parameter = parameter; + // Build the request. - if (!parameter.empty()) { - request.set_parameter(parameter); + if (!processed_parameter.empty()) { + request.set_parameter(processed_parameter); } @@ -1948,17 +1942,18 @@ bool CommandLineInterface::GeneratePluginOutput( // Write the files. We do this even if there was a generator error in order // to match the behavior of a compiled-in generator. - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> current_output; + std::unique_ptr<io::ZeroCopyOutputStream> current_output; for (int i = 0; i < response.file_size(); i++) { const CodeGeneratorResponse::File& output_file = response.file(i); if (!output_file.insertion_point().empty()) { + string filename = output_file.name(); // Open a file for insert. // We reset current_output to NULL first so that the old file is closed // before the new one is opened. current_output.reset(); current_output.reset(generator_context->OpenForInsert( - output_file.name(), output_file.insertion_point())); + filename, output_file.insertion_point())); } else if (!output_file.name().empty()) { // Starting a new file. Open it. // We reset current_output to NULL first so that the old file is closed @@ -1997,7 +1992,7 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { } DynamicMessageFactory dynamic_factory(pool); - google::protobuf::scoped_ptr<Message> message(dynamic_factory.GetPrototype(type)->New()); + std::unique_ptr<Message> message(dynamic_factory.GetPrototype(type)->New()); if (mode_ == MODE_ENCODE) { SetFdToTextMode(STDIN_FILENO); diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index d5d85f2d..7d3037a9 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -413,11 +413,6 @@ class LIBPROTOC_EXPORT CommandLineInterface { // dependency file will be written. Otherwise, empty. string dependency_out_name_; - // Path to a file that contains serialized AccessInfo which provides - // relative hotness of fields per message. This helps protoc to generate - // better code. - string profile_path_; - // True if --include_imports was given, meaning that we should // write all transitive dependencies to the DescriptorSet. Otherwise, only // the .proto files listed on the command-line are added. diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index ef7579a2..41eb244a 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -40,9 +40,6 @@ #include <unistd.h> #endif #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <vector> #include <google/protobuf/stubs/stringprintf.h> @@ -344,7 +341,7 @@ void CommandLineInterfaceTest::RunWithArgs(std::vector<string> args) { } } - google::protobuf::scoped_array<const char * > argv(new const char* [args.size()]); + std::unique_ptr<const char * []> argv(new const char* [args.size()]); for (int i = 0; i < args.size(); i++) { args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true); @@ -2298,7 +2295,7 @@ class EncodeDecodeTest : public testing::TestWithParam<EncodeDecodeTestMode> { ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam(); } - google::protobuf::scoped_array<const char * > argv(new const char* [args.size()]); + std::unique_ptr<const char * []> argv(new const char* [args.size()]); for (int i = 0; i < args.size(); i++) { argv[i] = args[i].c_str(); } diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc index f99159f5..4e150fe3 100644 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -44,6 +44,7 @@ #include <map> +#include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/compiler/cpp/cpp_generator.h> #include <google/protobuf/compiler/importer.h> #include <google/protobuf/io/zero_copy_stream_impl.h> @@ -97,9 +98,10 @@ class MockGeneratorContext : public GeneratorContext { File::GetContents(TestSourceDir() + "/" + physical_filename, &actual_contents, true)); EXPECT_TRUE(actual_contents == *expected_contents) - << physical_filename << " needs to be regenerated. Please run " - "generate_descriptor_proto.sh. Then add this file " - "to your CL."; + << physical_filename + << " needs to be regenerated. Please run " + "generate_descriptor_proto.sh. " + "Then add this file to your CL."; } // implements GeneratorContext -------------------------------------- @@ -116,37 +118,50 @@ class MockGeneratorContext : public GeneratorContext { std::map<string, string*> files_; }; -TEST(BootstrapTest, GeneratedDescriptorMatches) { - MockErrorCollector error_collector; +const char kDescriptorParameter[] = "dllexport_decl=LIBPROTOBUF_EXPORT"; +const char kPluginParameter[] = "dllexport_decl=LIBPROTOC_EXPORT"; +const char kNormalParameter[] = ""; + +const char* test_protos[][2] = { + {"google/protobuf/descriptor", kDescriptorParameter}, + {"google/protobuf/compiler/plugin", kPluginParameter}, +}; + +TEST(BootstrapTest, GeneratedFilesMatch) { + // We need a mapping from the actual file to virtual and actual path + // of the data to compare to. + std::map<string, string> vpath_map; + std::map<string, string> rpath_map; + rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto2"] = + "net/proto2/z_generated_example/test_messages_proto2"; + rpath_map["third_party/protobuf/src/google/protobuf/test_messages_proto3"] = + "net/proto2/z_generated_example/test_messages_proto3"; + rpath_map["google/protobuf/proto2_weak"] = + "net/proto2/z_generated_example/proto2_weak"; + DiskSourceTree source_tree; source_tree.MapPath("", TestSourceDir()); - Importer importer(&source_tree, &error_collector); - const FileDescriptor* proto_file = - importer.Import("google/protobuf/descriptor.proto"); - const FileDescriptor* plugin_proto_file = - importer.Import("google/protobuf/compiler/plugin.proto"); - EXPECT_EQ("", error_collector.text_); - ASSERT_TRUE(proto_file != NULL); - ASSERT_TRUE(plugin_proto_file != NULL); - - CppGenerator generator; - MockGeneratorContext context; - string error; - string parameter = "dllexport_decl=LIBPROTOBUF_EXPORT"; - ASSERT_TRUE(generator.Generate(proto_file, parameter, - &context, &error)); - parameter = "dllexport_decl=LIBPROTOC_EXPORT"; - ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter, - &context, &error)); - - context.ExpectFileMatches("google/protobuf/descriptor.pb.h", - "google/protobuf/descriptor.pb.h"); - context.ExpectFileMatches("google/protobuf/descriptor.pb.cc", - "google/protobuf/descriptor.pb.cc"); - context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h", - "google/protobuf/compiler/plugin.pb.h"); - context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc", - "google/protobuf/compiler/plugin.pb.cc"); + + for (auto file_parameter : test_protos) { + MockErrorCollector error_collector; + Importer importer(&source_tree, &error_collector); + const FileDescriptor* file = + importer.Import(file_parameter[0] + string(".proto")); + ASSERT_TRUE(file != nullptr) + << "Can't import file " << file_parameter[0] + string(".proto") << "\n"; + EXPECT_EQ("", error_collector.text_); + CppGenerator generator; + MockGeneratorContext context; + string error; + ASSERT_TRUE(generator.Generate(file, file_parameter[1], &context, &error)); + + string vpath = + FindWithDefault(vpath_map, file_parameter[0], file_parameter[0]); + string rpath = + FindWithDefault(rpath_map, file_parameter[0], file_parameter[0]); + context.ExpectFileMatches(vpath + ".pb.cc", rpath + ".pb.cc"); + context.ExpectFileMatches(vpath + ".pb.h", rpath + ".pb.h"); + } } } // namespace diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc index 8adee0f5..0d6a9e24 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc @@ -179,7 +179,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { void EnumGenerator:: GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { printer->Print( - "template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type " + "template <> struct is_proto_enum< $classname$> : ::std::true_type " "{};\n", "classname", ClassName(descriptor_, true)); if (HasDescriptorMethods(descriptor_->file(), options_)) { diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc index 0a4e0bb9..c416ba10 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc @@ -35,8 +35,8 @@ #include <google/protobuf/compiler/cpp/cpp_extension.h> #include <map> #include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/strutil.h> @@ -120,7 +120,6 @@ void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) { " ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n" " $name$;\n" ); - } void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index 0cf25b33..33ffe574 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -34,21 +34,18 @@ #include <google/protobuf/compiler/cpp/cpp_field.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/compiler/cpp/cpp_primitive_field.h> #include <google/protobuf/compiler/cpp/cpp_string_field.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> #include <google/protobuf/compiler/cpp/cpp_enum_field.h> #include <google/protobuf/compiler/cpp/cpp_map_field.h> #include <google/protobuf/compiler/cpp/cpp_message_field.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/wire_format.h> #include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/logging.h> -#include <google/protobuf/stubs/common.h> +#include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/strutil.h> namespace google { @@ -116,26 +113,30 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { } FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, - const Options& options) + const Options& options, + SCCAnalyzer* scc_analyzer) : descriptor_(descriptor), options_(options), field_generators_( - new google::protobuf::scoped_ptr<FieldGenerator>[descriptor->field_count()]) { + new std::unique_ptr<FieldGenerator>[descriptor->field_count()]) { // Construct all the FieldGenerators. for (int i = 0; i < descriptor->field_count(); i++) { - field_generators_[i].reset(MakeGenerator(descriptor->field(i), options)); + field_generators_[i].reset( + MakeGenerator(descriptor->field(i), options, scc_analyzer)); } } FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field, - const Options& options) { + const Options& options, + SCCAnalyzer* scc_analyzer) { if (field->is_repeated()) { switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: if (field->is_map()) { return new MapFieldGenerator(field, options); } else { - return new RepeatedMessageFieldGenerator(field, options); + return new RepeatedMessageFieldGenerator(field, options, + scc_analyzer); } case FieldDescriptor::CPPTYPE_STRING: switch (field->options().ctype()) { @@ -151,7 +152,7 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field, } else if (field->containing_oneof()) { switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: - return new MessageOneofFieldGenerator(field, options); + return new MessageOneofFieldGenerator(field, options, scc_analyzer); case FieldDescriptor::CPPTYPE_STRING: switch (field->options().ctype()) { default: // StringOneofFieldGenerator handles unknown ctypes. @@ -166,7 +167,7 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field, } else { switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: - return new MessageFieldGenerator(field, options); + return new MessageFieldGenerator(field, options, scc_analyzer); case FieldDescriptor::CPPTYPE_STRING: switch (field->options().ctype()) { default: // StringFieldGenerator handles unknown ctypes. diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index bccfcb9a..6cb466a8 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -37,13 +37,11 @@ #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <string> -#include <google/protobuf/descriptor.h> +#include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/compiler/cpp/cpp_options.h> +#include <google/protobuf/descriptor.h> namespace google { namespace protobuf { @@ -82,38 +80,12 @@ class FieldGenerator { // implementation is empty. virtual void GenerateStaticMembers(io::Printer* /*printer*/) const {} - // Generate prototypes for accessors that will manipulate imported - // messages inline. These are for .proto.h headers. - // - // In .proto.h mode, the headers of imports are not #included. However, - // functions that manipulate the imported message types need access to - // the class definition of the imported message, meaning that the headers - // must be #included. To get around this, functions that manipulate - // imported message objects are defined as dependent functions in a base - // template class. By making them dependent template functions, the - // function templates will not be instantiated until they are called, so - // we can defer to those translation units to #include the necessary - // generated headers. - // - // See: - // http://en.cppreference.com/w/cpp/language/class_template#Implicit_instantiation - // - // Most field types don't need this, so the default implementation is empty. - virtual void GenerateDependentAccessorDeclarations( - io::Printer* printer) const {} - // Generate prototypes for all of the accessor functions related to this // field. These are placed inside the class definition. virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0; - // Generate inline definitions of depenent accessor functions for this field. - // These are placed inside the header after all class definitions. - virtual void GenerateDependentInlineAccessorDefinitions( - io::Printer* printer) const {} - // Generate inline definitions of accessor functions for this field. // These are placed inside the header after all class definitions. - // In non-.proto.h mode, this generates dependent accessor functions as well. virtual void GenerateInlineAccessorDefinitions( io::Printer* printer) const = 0; @@ -207,6 +179,11 @@ class FieldGenerator { // are placed in the message's ByteSize() method. virtual void GenerateByteSize(io::Printer* printer) const = 0; + // Any tags about field layout decisions (such as inlining) to embed in the + // offset. + virtual uint32 CalculateFieldTag() const { return 0; } + virtual bool IsInlined() const { return false; } + protected: const Options& options_; @@ -217,7 +194,8 @@ class FieldGenerator { // Convenience class which constructs FieldGenerators for a Descriptor. class FieldGeneratorMap { public: - FieldGeneratorMap(const Descriptor* descriptor, const Options& options); + FieldGeneratorMap(const Descriptor* descriptor, const Options& options, + SCCAnalyzer* scc_analyzer); ~FieldGeneratorMap(); const FieldGenerator& get(const FieldDescriptor* field) const; @@ -225,10 +203,11 @@ class FieldGeneratorMap { private: const Descriptor* descriptor_; const Options& options_; - google::protobuf::scoped_array<google::protobuf::scoped_ptr<FieldGenerator> > field_generators_; + std::unique_ptr<std::unique_ptr<FieldGenerator> []> field_generators_; static FieldGenerator* MakeGenerator(const FieldDescriptor* field, - const Options& options); + const Options& options, + SCCAnalyzer* scc_analyzer); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); }; diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index a922ee97..42525687 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -35,20 +35,17 @@ #include <google/protobuf/compiler/cpp/cpp_file.h> #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <set> #include <vector> #include <google/protobuf/compiler/cpp/cpp_enum.h> -#include <google/protobuf/compiler/cpp/cpp_service.h> #include <google/protobuf/compiler/cpp/cpp_extension.h> +#include <google/protobuf/compiler/cpp/cpp_field.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/compiler/cpp/cpp_message.h> -#include <google/protobuf/compiler/cpp/cpp_field.h> -#include <google/protobuf/io/printer.h> +#include <google/protobuf/compiler/cpp/cpp_service.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/strutil.h> namespace google { @@ -61,11 +58,11 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) options_(options), scc_analyzer_(options), enum_generators_owner_( - new google::protobuf::scoped_ptr<EnumGenerator>[file->enum_type_count()]), + new std::unique_ptr<EnumGenerator>[file->enum_type_count()]), service_generators_owner_( - new google::protobuf::scoped_ptr<ServiceGenerator>[file->service_count()]), + new std::unique_ptr<ServiceGenerator>[file->service_count()]), extension_generators_owner_( - new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]) { + new std::unique_ptr<ExtensionGenerator>[file->extension_count()]) { std::vector<const Descriptor*> msgs = FlattenMessagesInFile(file); for (int i = 0; i < msgs.size(); i++) { // Deleted in destructor @@ -141,6 +138,9 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { printer->Print( "// @@protoc_insertion_point(includes)\n"); + printer->Print("#define PROTOBUF_INTERNAL_EXPORT_$filename$ $export$\n", + "filename", FileLevelNamespace(file_), + "export", options_.dllexport_decl); GenerateMacroUndefs(printer); GenerateGlobalStateFunctionDeclarations(printer); @@ -223,8 +223,9 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer, GenerateTopHeaderGuard(printer, filename_identifier); if (options_.proto_h) { + string target_basename = StripProto(file_->name()); printer->Print("#include \"$basename$.proto.h\" // IWYU pragma: export\n", - "basename", StripProto(file_->name())); + "basename", target_basename); } else { GenerateLibraryIncludes(printer); } @@ -256,9 +257,10 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer, } void FileGenerator::GenerateSourceIncludes(io::Printer* printer) { + string target_basename = StripProto(file_->name()); const bool use_system_include = IsWellKnownMessage(file_); - string header = - StripProto(file_->name()) + (options_.proto_h ? ".proto.h" : ".pb.h"); + + string header = target_basename + (options_.proto_h ? ".proto.h" : ".pb.h"); printer->Print( "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" "// source: $filename$\n" @@ -269,7 +271,6 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) { "\n" "#include <google/protobuf/stubs/common.h>\n" "#include <google/protobuf/stubs/port.h>\n" - "#include <google/protobuf/stubs/once.h>\n" "#include <google/protobuf/io/coded_stream.h>\n" "#include <google/protobuf/wire_format_lite_inl.h>\n", "filename", file_->name(), @@ -296,7 +297,8 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) { for (int i = 0; i < file_->dependency_count(); i++) { const FileDescriptor* dep = file_->dependency(i); const char* extension = ".proto.h"; - string dependency = StripProto(dep->name()) + extension; + string basename = StripProto(dep->name()); + string dependency = basename + extension; printer->Print( "#include \"$dependency$\"\n", "dependency", dependency); @@ -338,33 +340,34 @@ namespace { // Generates weak symbol declarations for types that are to be considered weakly // referenced. -void GenerateWeakDeclarations( - const FileDescriptor* file, const Options& options, - SCCAnalyzer* scc_analyzer, - io::Printer* printer) { - std::vector<const FieldDescriptor*> fields; - ListAllFields(file, &fields); - +void GenerateInternalForwardDeclarations( + const std::vector<const FieldDescriptor*>& fields, const Options& options, + SCCAnalyzer* scc_analyzer, io::Printer* printer) { // To ensure determinism and minimize the number of namespace statements, // we output the forward declarations sorted on namespace and type / function // name. std::set<std::pair<string, string> > messages; + std::set<std::pair<string, string> > sccs; std::set<std::pair<string, string> > inits; for (int i = 0; i < fields.size(); ++i) { const FieldDescriptor* field = fields[i]; - bool is_weak = IsImplicitWeakField(field, options); + const Descriptor* msg = field->message_type(); + if (msg == nullptr) continue; + bool is_weak = IsImplicitWeakField(field, options, scc_analyzer); + string flns = FileLevelNamespace(msg); + auto scc = scc_analyzer->GetSCC(msg); + string repr = ClassName(scc->GetRepresentative()); + string weak_attr; if (is_weak) { - const Descriptor* msg = field->message_type(); - string flns = FileLevelNamespace(msg); - string repr = ClassName(scc_analyzer->GetSCC(msg)->GetRepresentative()); - inits.insert(std::make_pair(flns, "InitDefaults" + repr)); inits.insert(std::make_pair(flns, "AddDescriptors")); messages.insert(std::make_pair(Namespace(msg), ClassName(msg))); + weak_attr = " __attribute__((weak))"; } - } - - if (messages.empty()) { - return; + string dllexport = "PROTOBUF_INTERNAL_EXPORT_" + FileLevelNamespace(msg); + sccs.insert(std::make_pair(flns, "extern " + dllexport + weak_attr + + " ::google::protobuf::internal::SCCInfo<" + + SimpleItoa(scc->children.size()) + + "> scc_info_" + repr + ";\n")); } printer->Print("\n"); @@ -384,13 +387,33 @@ void GenerateWeakDeclarations( printer->Print("void $name$() __attribute__((weak));\n", "name", it->second); } + for (const auto& p : sccs) { + ns.ChangeTo(p.first); + printer->Print(p.second.c_str()); + } } } // namespace void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) { GenerateSourceIncludes(printer); - GenerateWeakDeclarations(file_, options_, &scc_analyzer_, printer); + + // Generate weak declarations. We do this for the whole strongly-connected + // component (SCC), because we have a single InitDefaults* function for the + // SCC. + std::vector<const FieldDescriptor*> fields; + for (const Descriptor* message : + scc_analyzer_.GetSCC(message_generators_[idx]->descriptor_) + ->descriptors) { + ListAllFields(message, &fields); + } + GenerateInternalForwardDeclarations(fields, options_, &scc_analyzer_, + printer); + + if (IsSCCRepresentative(message_generators_[idx]->descriptor_)) { + NamespaceOpener ns(FileLevelNamespace(file_), printer); + GenerateInitForSCC(GetSCC(message_generators_[idx]->descriptor_), printer); + } { // package namespace NamespaceOpener ns(Namespace(file_), printer); @@ -411,12 +434,6 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) { "// @@protoc_insertion_point(namespace_scope)\n"); } // end package namespace - if (IsSCCRepresentative(message_generators_[idx]->descriptor_)) { - NamespaceOpener ns(FileLevelNamespace(file_), printer); - GenerateInitForSCC(GetSCC(message_generators_[idx]->descriptor_), printer); - } - - printer->Print( "namespace google {\nnamespace protobuf {\n"); message_generators_[idx]->GenerateSourceInProto2Namespace(printer); @@ -430,15 +447,16 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) { void FileGenerator::GenerateGlobalSource(io::Printer* printer) { GenerateSourceIncludes(printer); - GenerateWeakDeclarations(file_, options_, &scc_analyzer_, printer); - // TODO(gerbens) Generate tables here - - // Define the code to initialize reflection. This code uses a global - // constructor to register reflection data with the runtime pre-main. - if (HasDescriptorMethods(file_, options_)) { + { NamespaceOpener ns(FileLevelNamespace(file_), printer); - GenerateReflectionInitializationCode(printer); + GenerateTables(printer); + + // Define the code to initialize reflection. This code uses a global + // constructor to register reflection data with the runtime pre-main. + if (HasDescriptorMethods(file_, options_)) { + GenerateReflectionInitializationCode(printer); + } } NamespaceOpener ns(Namespace(file_), printer); @@ -466,7 +484,10 @@ void FileGenerator::GenerateGlobalSource(io::Printer* printer) { void FileGenerator::GenerateSource(io::Printer* printer) { GenerateSourceIncludes(printer); - GenerateWeakDeclarations(file_, options_, &scc_analyzer_, printer); + std::vector<const FieldDescriptor*> fields; + ListAllFields(file_, &fields); + GenerateInternalForwardDeclarations(fields, options_, &scc_analyzer_, + printer); { NamespaceOpener ns(Namespace(file_), printer); @@ -483,9 +504,25 @@ void FileGenerator::GenerateSource(io::Printer* printer) { { NamespaceOpener ns(FileLevelNamespace(file_), printer); - // Define the initialization code to initialize the default instances. - // This code doesn't use a global constructor. - GenerateInitializationCode(printer); + GenerateTables(printer); + + // Now generate the InitDefaults for each SCC. + for (int i = 0; i < message_generators_.size(); i++) { + if (IsSCCRepresentative(message_generators_[i]->descriptor_)) { + GenerateInitForSCC(GetSCC(message_generators_[i]->descriptor_), + printer); + } + } + + printer->Print("void InitDefaults() {\n"); + for (int i = 0; i < message_generators_.size(); i++) { + if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue; + string scc_name = ClassName(message_generators_[i]->descriptor_); + printer->Print( + " ::google::protobuf::internal::InitSCC(&scc_info_$scc_name$.base);\n", + "scc_name", scc_name); + } + printer->Print("}\n\n"); // Define the code to initialize reflection. This code uses a global // constructor to register reflection data with the runtime pre-main. @@ -560,7 +597,7 @@ class FileGenerator::ForwardDeclarations { ForwardDeclarations* AddOrGetNamespace(const string& ns_name) { ForwardDeclarations*& ns = namespaces_[ns_name]; - if (ns == NULL) { + if (ns == nullptr) { ns = new ForwardDeclarations; } return ns; @@ -648,17 +685,12 @@ class FileGenerator::ForwardDeclarations { end = classes_.end(); it != end; ++it) { const Descriptor* d = it->second; - string extra_class_qualifier; - // "class" is to disambiguate in case there is also a function with this - // name. There is code out there that does this! printer->Print( "template<> " "$dllexport_decl$" - "$class$$classname$* Arena::$func$< $class$$classname$>(Arena*);\n", - "classname", QualifiedClassName(d), - "func", MessageCreateFunction(d), - "class", extra_class_qualifier, - "dllexport_decl", + "$classname$* Arena::CreateMaybeMessage<$classname$>" + "(Arena*);\n", + "classname", QualifiedClassName(d), "dllexport_decl", options.dllexport_decl.empty() ? "" : options.dllexport_decl + " "); } printer->Print( @@ -758,7 +790,6 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // protobuf_AssignDescriptorsOnce(): The first time it is called, calls // AssignDescriptors(). All later times, waits for the first call to // complete and then returns. - string message_factory = "NULL"; printer->Print( "void protobuf_AssignDescriptors() {\n" // Make sure the file has found its way into the pool. If a descriptor @@ -766,10 +797,9 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // been called yet, so we call it manually. Note that it's fine if // AddDescriptors() is called multiple times. " AddDescriptors();\n" - " ::google::protobuf::MessageFactory* factory = $factory$;\n" " AssignDescriptors(\n" " \"$filename$\", schemas, file_default_instances, " - "TableStruct::offsets, factory,\n" + "TableStruct::offsets,\n" " $metadata$, $enum_descriptors$, $service_descriptors$);\n", "filename", file_->name(), "metadata", !message_generators_.empty() ? "file_level_metadata" : "NULL", @@ -778,14 +808,13 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { "service_descriptors", HasGenericServices(file_, options_) && file_->service_count() > 0 ? "file_level_service_descriptors" - : "NULL", - "factory", message_factory); + : "NULL"); printer->Print( "}\n" "\n" "void protobuf_AssignDescriptorsOnce() {\n" - " static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n" - " ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors);\n" + " static ::google::protobuf::internal::once_flag once;\n" + " ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);\n" "}\n" "\n", "filename", file_->name(), "metadata", @@ -795,8 +824,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { "service_descriptors", HasGenericServices(file_, options_) && file_->service_count() > 0 ? "file_level_service_descriptors" - : "NULL", - "factory", message_factory); + : "NULL"); // Only here because of useless string reference that we don't want in // protobuf_AssignDescriptorsOnce, because that is called from all the @@ -891,8 +919,8 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { "}\n" "\n" "void AddDescriptors() {\n" - " static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n" - " ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);\n" + " static ::google::protobuf::internal::once_flag once;\n" + " ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);\n" "}\n"); printer->Print( @@ -907,47 +935,16 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { void FileGenerator::GenerateInitForSCC(const SCC* scc, io::Printer* printer) { const string scc_name = ClassName(scc->GetRepresentative()); + // We use static and not anonymous namespace because symbol names are + // substantially shorter. printer->Print( - "void InitDefaults$scc_name$Impl() {\n" + "static void InitDefaults$scc_name$() {\n" " GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n" - "#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n" - " ::google::protobuf::internal::InitProtobufDefaultsForceUnique();\n" - "#else\n" - " ::google::protobuf::internal::InitProtobufDefaults();\n" - "#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n", - // Force initialization of primitive values we depend on. + , // awkward comma due to macro "scc_name", scc_name); printer->Indent(); - // Call the InitDefaults() methods for all of our dependencies, to make - // sure they get added first. - for (int i = 0; i < scc->children.size(); i++) { - const SCC* child_scc = scc->children[i]; - const FileDescriptor* dependency = child_scc->GetRepresentative()->file(); - // Print the namespace prefix for the dependency. - string file_namespace = FileLevelNamespace(dependency); - std::map<string, string> variables; - variables["file_namespace"] = file_namespace; - variables["scc_name"] = ClassName(child_scc->GetRepresentative(), false); - bool using_weak_fields = UsingImplicitWeakFields(file_, options_); - if (using_weak_fields) { - // We're building for lite with implicit weak fields, so we need to handle - // the possibility that this InitDefaults function is not linked into the - // binary. Some of these might actually be guaranteed to be non-null since - // we might have a strong reference to the dependency (via a required - // field, for example), but it's simplest to just assume that any of them - // could be null. - printer->Print( - variables, - "if (&$file_namespace$::InitDefaults$scc_name$ != NULL) {\n" - " $file_namespace$::InitDefaults$scc_name$();\n" - "}\n"); - } else { - printer->Print(variables, - "$file_namespace$::InitDefaults$scc_name$();\n"); - } - } // First construct all the necessary default instances. for (int i = 0; i < message_generators_.size(); i++) { @@ -982,23 +979,24 @@ void FileGenerator::GenerateInitForSCC(const SCC* scc, io::Printer* printer) { } printer->Outdent(); printer->Print("}\n\n"); + printer->Print( - "void InitDefaults$scc_name$() {\n" - " static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n" - " ::google::protobuf::GoogleOnceInit(&once, " - "&InitDefaults$scc_name$Impl);\n" - "}\n\n", - "scc_name", scc_name); + "$dllexport_decl$::google::protobuf::internal::SCCInfo<$size$> " + "scc_info_$scc_name$ =\n" + " {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), " + "$size$, InitDefaults$scc_name$}, {", + "size", SimpleItoa(scc->children.size()), "scc_name", + ClassName(scc->GetRepresentative()), "dllexport_decl", + options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); + for (const SCC* child : scc->children) { + auto repr = child->GetRepresentative(); + printer->Print("\n &$ns$::scc_info_$child$.base,", "ns", + FileLevelNamespace(repr), "child", ClassName(repr)); + } + printer->Print("}};\n\n"); } -void FileGenerator::GenerateInitializationCode(io::Printer* printer) { - // Messages depend on the existence of a default instance, which has to - // initialized properly. The default instances are allocated in the data - // segment, but we can't quite allocate the type directly. The destructors - // cannot run at program exit as this could lead to segfaults in a threaded - // environment. Hence these instances must be inplace constructed at first - // use. - +void FileGenerator::GenerateTables(io::Printer* printer) { if (options_.table_driven_parsing) { // TODO(ckennelly): Gate this with the same options flag to enable // table-driven parsing. @@ -1105,16 +1103,6 @@ void FileGenerator::GenerateInitializationCode(io::Printer* printer) { "};\n" "\n"); } - - // ----------------------------------------------------------------- - // All functionality that need private access. - - // Now generate the InitDefaults for each SCC. - for (int i = 0; i < message_generators_.size(); i++) { - if (IsSCCRepresentative(message_generators_[i]->descriptor_)) { - GenerateInitForSCC(GetSCC(message_generators_[i]->descriptor_), printer); - } - } } void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) { @@ -1145,8 +1133,8 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer, "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" "// source: $filename$\n" "\n" - "#ifndef PROTOBUF_$filename_identifier$_INCLUDED\n" - "#define PROTOBUF_$filename_identifier$_INCLUDED\n" + "#ifndef PROTOBUF_INCLUDED_$filename_identifier$\n" + "#define PROTOBUF_INCLUDED_$filename_identifier$\n" "\n" "#include <string>\n", "filename", file_->name(), "filename_identifier", filename_identifier); @@ -1156,7 +1144,7 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer, void FileGenerator::GenerateBottomHeaderGuard( io::Printer* printer, const string& filename_identifier) { printer->Print( - "#endif // PROTOBUF_$filename_identifier$_INCLUDED\n", + "#endif // PROTOBUF_INCLUDED_$filename_identifier$\n", "filename_identifier", filename_identifier); } @@ -1193,7 +1181,9 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { "#include <google/protobuf/arena.h>\n" "#include <google/protobuf/arenastring.h>\n" "#include <google/protobuf/generated_message_table_driven.h>\n" - "#include <google/protobuf/generated_message_util.h>\n"); + "#include <google/protobuf/generated_message_util.h>\n" + "#include <google/protobuf/inlined_string_field.h>\n"); + if (HasDescriptorMethods(file_, options_)) { printer->Print( @@ -1280,11 +1270,12 @@ void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) { const bool use_system_include = IsWellKnownMessage(file_->dependency(i)); const string& name = file_->dependency(i)->name(); bool public_import = (public_import_names.count(name) != 0); + string basename = StripProto(name); printer->Print( "#include $left$$dependency$.pb.h$right$$iwyu$\n", - "dependency", StripProto(name), + "dependency", basename, "iwyu", (public_import) ? " // IWYU pragma: export" : "", "left", use_system_include ? "<" : "\"", "right", use_system_include ? ">" : "\""); @@ -1318,28 +1309,6 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations( "void $dllexport_decl$AddDescriptors();\n", "dllexport_decl", options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); } - for (int i = 0; i < message_generators_.size(); i++) { - if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue; - string scc_name = ClassName(message_generators_[i]->descriptor_); - // TODO(gerbens) Remove the Impl from header. This is solely because - // it currently still needs to be a friend of the protos. - printer->Print( - "void $dllexport_decl$InitDefaults$scc_name$Impl();\n" - "void $dllexport_decl$InitDefaults$scc_name$();\n", - "scc_name", scc_name, "dllexport_decl", - options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); - } - // TODO(gerbens) This is for proto1 interoperability. Remove when proto1 - // is gone. - printer->Print( - "inline void $dllexport_decl$InitDefaults() {\n", "dllexport_decl", - options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); - for (int i = 0; i < message_generators_.size(); i++) { - if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue; - string scc_name = ClassName(message_generators_[i]->descriptor_); - printer->Print(" InitDefaults$scc_name$();\n", "scc_name", scc_name); - } - printer->Print("}\n"); printer->Print( "} // namespace $file_namespace$\n", "file_namespace", FileLevelNamespace(file_)); @@ -1416,8 +1385,6 @@ void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) { printer->Print(kThinSeparator); printer->Print("\n"); } - // Methods of the dependent base class must always be inline in the header. - message_generators_[i]->GenerateDependentInlineMethods(printer); } } diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h index 7e61cbad..94da9a14 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.h +++ b/src/google/protobuf/compiler/cpp/cpp_file.h @@ -37,9 +37,6 @@ #include <algorithm> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <set> #include <string> #include <vector> @@ -97,7 +94,7 @@ class FileGenerator { void GenerateSourceDefaultInstance(int idx, io::Printer* printer); void GenerateInitForSCC(const SCC* scc, io::Printer* printer); - void GenerateInitializationCode(io::Printer* printer); + void GenerateTables(io::Printer* printer); void GenerateReflectionInitializationCode(io::Printer* printer); // For other imports, generates their forward-declarations. @@ -176,10 +173,10 @@ class FileGenerator { // These members are just for owning (and thus proper deleting). // Nested (enum/extension)_generators are owned by child messages. - google::protobuf::scoped_array<google::protobuf::scoped_ptr<EnumGenerator> > enum_generators_owner_; - google::protobuf::scoped_array<google::protobuf::scoped_ptr<ServiceGenerator> > + std::unique_ptr<std::unique_ptr<EnumGenerator> []> enum_generators_owner_; + std::unique_ptr<std::unique_ptr<ServiceGenerator> []> service_generators_owner_; - google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> > + std::unique_ptr<std::unique_ptr<ExtensionGenerator> []> extension_generators_owner_; // E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}. diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc index 5d8ea300..20bb8a1a 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -36,17 +36,15 @@ #include <vector> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <utility> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/cpp/cpp_file.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> + namespace google { namespace protobuf { @@ -66,12 +64,6 @@ bool CppGenerator::Generate(const FileDescriptor* file, // ----------------------------------------------------------------- // parse generator options - // TODO(kenton): If we ever have more options, we may want to create a - // class that encapsulates them which we can pass down to all the - // generator classes. Currently we pass dllexport_decl down to all of - // them via the constructors, but we don't want to have to add another - // constructor parameter for every option. - // If the dllexport_decl option is passed to the compiler, we need to write // it in front of every symbol that should be exported if this .proto is // compiled into a Windows DLL. E.g., if the user invokes the protocol @@ -127,11 +119,12 @@ bool CppGenerator::Generate(const FileDescriptor* file, string basename = StripProto(file->name()); + FileGenerator file_generator(file, file_options); // Generate header(s). if (file_options.proto_h) { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( generator_context->Open(basename + ".proto.h")); GeneratedCodeInfo annotations; io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( @@ -143,14 +136,14 @@ bool CppGenerator::Generate(const FileDescriptor* file, file_generator.GenerateProtoHeader( &printer, file_options.annotate_headers ? info_path : ""); if (file_options.annotate_headers) { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output( + std::unique_ptr<io::ZeroCopyOutputStream> info_output( generator_context->Open(info_path)); annotations.SerializeToZeroCopyStream(info_output.get()); } } { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( generator_context->Open(basename + ".pb.h")); GeneratedCodeInfo annotations; io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( @@ -162,7 +155,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, file_generator.GeneratePBHeader( &printer, file_options.annotate_headers ? info_path : ""); if (file_options.annotate_headers) { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output( + std::unique_ptr<io::ZeroCopyOutputStream> info_output( generator_context->Open(info_path)); annotations.SerializeToZeroCopyStream(info_output.get()); } @@ -172,7 +165,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, if (UsingImplicitWeakFields(file, file_options)) { { // This is the global .cc file, containing enum/services/tables/reflection - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( generator_context->Open(basename + ".pb.cc")); io::Printer printer(output.get(), '$'); file_generator.GenerateGlobalSource(&printer); @@ -191,7 +184,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, } for (int i = 0; i < num_cc_files; i++) { // TODO(gerbens) Agree on naming scheme. - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( generator_context->Open(basename + "." + SimpleItoa(i) + ".cc")); io::Printer printer(output.get(), '$'); if (i < file_generator.NumMessages()) { @@ -199,7 +192,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, } } } else { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( generator_context->Open(basename + ".pb.cc")); io::Printer printer(output.get(), '$'); file_generator.GenerateSource(&printer); diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 172acedd..163dac0a 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -42,6 +42,7 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> @@ -73,7 +74,7 @@ const char* const kKeywordList[] = { "constexpr", "const_cast", "continue", "decltype", "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline", "int", "long", - "mutable", "namespace", "new", "noexcept", "not", "not_eq", "NULL", + "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected", "public", "register", "reinterpret_cast", "return", "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", "template", "this", @@ -219,24 +220,12 @@ string ReferenceFunctionName(const Descriptor* descriptor) { return QualifiedClassName(descriptor) + "_ReferenceStrong"; } -string DependentBaseClassTemplateName(const Descriptor* descriptor) { - return ClassName(descriptor, false) + "_InternalBase"; -} - string SuperClassName(const Descriptor* descriptor, const Options& options) { return HasDescriptorMethods(descriptor->file(), options) ? "::google::protobuf::Message" : "::google::protobuf::MessageLite"; } -string DependentBaseDownCast() { - return "reinterpret_cast<T*>(this)->"; -} - -string DependentBaseConstDownCast() { - return "reinterpret_cast<const T*>(this)->"; -} - string FieldName(const FieldDescriptor* field) { string result = field->name(); LowerString(&result); @@ -294,60 +283,6 @@ string FieldConstantName(const FieldDescriptor *field) { return result; } -bool IsFieldDependent(const FieldDescriptor* field) { - if (field->containing_oneof() != NULL && - field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { - return true; - } - if (field->is_map()) { - const Descriptor* map_descriptor = field->message_type(); - for (int i = 0; i < map_descriptor->field_count(); i++) { - if (IsFieldDependent(map_descriptor->field(i))) { - return true; - } - } - return false; - } - if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - return false; - } - if (field->containing_oneof() != NULL) { - // Oneof fields will always be dependent. - // - // This is a unique case for field codegen. Field generators are - // responsible for generating all the field-specific accessor - // functions, except for the clear_*() function; instead, field - // generators produce inline clearing code. - // - // For non-oneof fields, the Message class uses the inline clearing - // code to define the field's clear_*() function, as well as in the - // destructor. For oneof fields, the Message class generates a much - // more complicated clear_*() function, which clears only the oneof - // member that is set, in addition to clearing methods for each of the - // oneof members individually. - // - // Since oneofs do not have their own generator class, the Message code - // generation logic would be significantly complicated in order to - // split dependent and non-dependent manipulation logic based on - // whether the oneof truly needs to be dependent; so, for oneof fields, - // we just assume it (and its constituents) should be manipulated by a - // dependent base class function. - // - // This is less precise than how dependent message-typed fields are - // handled, but the cost is limited to only the generated code for the - // oneof field, which seems like an acceptable tradeoff. - return true; - } - if (field->file() == field->message_type()->file()) { - return false; - } - return true; -} - -string DependentTypeName(const FieldDescriptor* field) { - return "InternalBase_" + field->name() + "_T"; -} - string FieldMessageTypeName(const FieldDescriptor* field) { // Note: The Google-internal version of Protocol Buffers uses this function // as a hook point for hacks to support legacy code. @@ -748,12 +683,17 @@ bool UsingImplicitWeakFields(const FileDescriptor* file, GetOptimizeFor(file, options) == FileOptions::LITE_RUNTIME; } - -bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options) { +bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options, + SCCAnalyzer* scc_analyzer) { return UsingImplicitWeakFields(field->file(), options) && field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_required() && !field->is_map() && - field->containing_oneof() == NULL; + field->containing_oneof() == NULL && + !IsWellKnownMessage(field->message_type()->file()) && + // We do not support implicit weak fields between messages in the same + // strongly-connected component. + scc_analyzer->GetSCC(field->containing_type()) != + scc_analyzer->GetSCC(field->message_type()); } struct CompareDescriptors { @@ -920,6 +860,7 @@ void ListAllTypesForServices(const FileDescriptor* fd, } } + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index 4026d0ed..eac65124 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -38,8 +38,9 @@ #include <map> #include <string> #include <google/protobuf/compiler/cpp/cpp_options.h> -#include <google/protobuf/io/printer.h> +#include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/stubs/strutil.h> @@ -53,6 +54,7 @@ namespace cpp { extern const char kThickSeparator[]; extern const char kThinSeparator[]; + // Name space of the proto file. This namespace is such that the string // "<namespace>::some_name" is the correct fully qualified namespace. // This means if the package is empty the namespace is "", and otherwise @@ -102,19 +104,9 @@ string DefaultInstanceName(const Descriptor* descriptor); // fields. string ReferenceFunctionName(const Descriptor* descriptor); -// Name of the CRTP class template (for use with proto_h). -// This is a class name, like "ProtoName_InternalBase". -string DependentBaseClassTemplateName(const Descriptor* descriptor); - -// Name of the base class: either the dependent base class (for use with -// proto_h) or google::protobuf::Message. +// Name of the base class: google::protobuf::Message or google::protobuf::MessageLite. string SuperClassName(const Descriptor* descriptor, const Options& options); -// Returns a string that down-casts from the dependent base class to the -// derived class. -string DependentBaseDownCast(); -string DependentBaseConstDownCast(); - // Get the (unqualified) name that should be used for this field in C++ code. // The name is coerced to lower-case to emulate proto1 behavior. People // should be using lowercase-with-underscores style for proto field names @@ -141,20 +133,6 @@ inline const Descriptor* FieldScope(const FieldDescriptor* field) { field->extension_scope() : field->containing_type(); } -// Returns true if the given 'field_descriptor' has a message type that is -// a dependency of the file where the field is defined (i.e., the field -// type is defined in a different file than the message holding the field). -// -// This only applies to Message-typed fields. Enum-typed fields may refer -// to an enum in a dependency; however, enums are specified and -// forward-declared with an enum-base, so the definition is not required to -// manipulate the field value. -bool IsFieldDependent(const FieldDescriptor* field_descriptor); - -// Returns the name that should be used for forcing dependent lookup from a -// dependent base class. -string DependentTypeName(const FieldDescriptor* field); - // Returns the fully-qualified type name field->message_type(). Usually this // is just ClassName(field->message_type(), true); string FieldMessageTypeName(const FieldDescriptor* field); @@ -314,6 +292,11 @@ inline string MessageCreateFunction(const Descriptor* d) { return SupportsArenas(d) ? "CreateMessage" : "Create"; } +inline string MakeDefaultName(const FieldDescriptor* field) { + return "_i_give_permission_to_break_this_code_default_" + FieldName(field) + + "_"; +} + bool IsAnyMessage(const FileDescriptor* descriptor); bool IsAnyMessage(const Descriptor* descriptor); @@ -350,13 +333,6 @@ inline std::vector<const Descriptor*> FlattenMessagesInFile( bool HasWeakFields(const Descriptor* desc); bool HasWeakFields(const FileDescriptor* desc); -// Indicates whether we should use implicit weak fields for this file. -bool UsingImplicitWeakFields(const FileDescriptor* file, - const Options& options); - -// Indicates whether to treat this field as implicitly weak. -bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options); - // Returns true if the "required" restriction check should be ignored for the // given field. inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field, @@ -462,11 +438,21 @@ class LIBPROTOC_EXPORT SCCAnalyzer { void AddChildren(SCC* scc); }; +void ListAllFields(const Descriptor* d, + std::vector<const FieldDescriptor*>* fields); void ListAllFields(const FileDescriptor* d, std::vector<const FieldDescriptor*>* fields); void ListAllTypesForServices(const FileDescriptor* fd, std::vector<const Descriptor*>* types); +// Indicates whether we should use implicit weak fields for this file. +bool UsingImplicitWeakFields(const FileDescriptor* file, + const Options& options); + +// Indicates whether to treat this field as implicitly weak. +bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options, + SCCAnalyzer* scc_analyzer); + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc index b22c0754..0e485cac 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -104,9 +104,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor, MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options) - : FieldGenerator(options), - descriptor_(descriptor), - dependent_field_(options.proto_h && IsFieldDependent(descriptor)) { + : FieldGenerator(options), descriptor_(descriptor) { SetMessageVariables(descriptor, &variables_, options); } @@ -202,7 +200,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { key = "entry->key()"; value = "entry->value()"; printer->Print(variables_, - "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry());\n"); + "::std::unique_ptr<$map_classname$> entry($name$_.NewEntry());\n"); printer->Print(variables_, "{\n" " ::std::string data;\n" @@ -258,7 +256,7 @@ static void GenerateSerializationLoop(io::Printer* printer, const string& ptr, bool loop_via_iterators) { printer->Print(variables, - StrCat("::google::protobuf::scoped_ptr<$map_classname$> entry;\n", + StrCat("::std::unique_ptr<$map_classname$> entry;\n", loop_header, " {\n").c_str()); printer->Indent(); @@ -365,7 +363,7 @@ void MapFieldGenerator::GenerateSerializeWithCachedSizes( "\n" "if ($deterministic$ &&\n" " this->$name$().size() > 1) {\n" - " ::google::protobuf::scoped_array<SortItem> items(\n" + " ::std::unique_ptr<SortItem[]> items(\n" " new SortItem[this->$name$().size()]);\n" " typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::size_type size_type;\n" " size_type n = 0;\n" @@ -402,7 +400,7 @@ GenerateByteSize(io::Printer* printer) const { "total_size += $tag_size$ *\n" " ::google::protobuf::internal::FromIntSize(this->$name$_size());\n" "{\n" - " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" + " ::std::unique_ptr<$map_classname$> entry;\n" " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" " it = this->$name$().begin();\n" " it != this->$name$().end(); ++it) {\n"); diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h index 88e3b464..0d54f0ea 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h @@ -66,7 +66,6 @@ class MapFieldGenerator : public FieldGenerator { io::Printer* printer, const std::map<string, string>& variables) const; const FieldDescriptor* descriptor_; - const bool dependent_field_; std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator); diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 9b2f090e..8c2336af 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -38,9 +38,6 @@ #include <google/protobuf/stubs/hash.h> #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <utility> #include <vector> @@ -49,9 +46,9 @@ #include <google/protobuf/compiler/cpp/cpp_field.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/compiler/cpp/cpp_padding_optimizer.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/generated_message_table_driven.h> #include <google/protobuf/generated_message_util.h> #include <google/protobuf/map_entry_lite.h> @@ -60,6 +57,7 @@ #include <google/protobuf/stubs/substitute.h> + namespace google { namespace protobuf { namespace compiler { @@ -440,13 +438,12 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, index_in_file_messages_(index_in_file_messages), classname_(ClassName(descriptor, false)), options_(options), - field_generators_(descriptor, options), + field_generators_(descriptor, options, scc_analyzer), max_has_bit_index_(0), enum_generators_( - new google::protobuf::scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]), - extension_generators_(new google::protobuf::scoped_ptr< + new std::unique_ptr<EnumGenerator>[descriptor->enum_type_count()]), + extension_generators_(new std::unique_ptr< ExtensionGenerator>[descriptor->extension_count()]), - use_dependent_base_(false), num_weak_fields_(0), message_layout_helper_(new PaddingOptimizer()), scc_analyzer_(scc_analyzer) { @@ -492,13 +489,6 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, if (descriptor->field(i)->is_required()) { ++num_required_fields_; } - if (options.proto_h && IsFieldDependent(descriptor->field(i))) { - use_dependent_base_ = true; - } - } - if (options.proto_h && descriptor->oneof_decl_count() > 0) { - // Always make oneofs dependent. - use_dependent_base_ = true; } table_driven_ = TableDrivenParsingEnabled(descriptor_, options_); @@ -539,22 +529,6 @@ void MessageGenerator::FillMessageForwardDeclarations( } void MessageGenerator:: -GenerateDependentFieldAccessorDeclarations(io::Printer* printer) { - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - PrintFieldComment(printer, field); - - std::map<string, string> vars; - SetCommonFieldVariables(field, &vars, options_); - - // Generate type-specific accessor declarations. - field_generators_.get(field).GenerateDependentAccessorDeclarations(printer); - printer->Print("\n"); - } -} - -void MessageGenerator:: GenerateFieldAccessorDeclarations(io::Printer* printer) { // optimized_fields_ does not contain fields where // field->containing_oneof() != NULL @@ -585,21 +559,6 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { SetCommonFieldVariables(field, &vars, options_); vars["constant_name"] = FieldConstantName(field); - bool dependent_field = use_dependent_base_ && IsFieldDependent(field); - if (dependent_field && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !field->is_map()) { - // If this field is dependent, the dependent base class determines - // the message type from the derived class (which is a template - // parameter). This typedef is for that: - printer->Print( - "private:\n" - "typedef $field_type$ $dependent_type$;\n" - "public:\n", - "field_type", FieldMessageTypeName(field), - "dependent_type", DependentTypeName(field)); - } - if (field->is_repeated()) { printer->Print(vars, "$deprecated_attr$int ${$$name$_size$}$() const;\n"); printer->Annotate("{", "}", field); @@ -637,6 +596,7 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { printer->Print( + "void clear_$oneof_name$();\n" "$camel_oneof_name$Case $oneof_name$_case() const;\n", "camel_oneof_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true), @@ -645,32 +605,6 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { } void MessageGenerator:: -GenerateDependentFieldAccessorDefinitions(io::Printer* printer) { - if (!use_dependent_base_) return; - - printer->Print("// $classname$\n\n", "classname", - DependentBaseClassTemplateName(descriptor_)); - - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - - if (field->options().weak()) continue; - - PrintFieldComment(printer, field); - // Generate type-specific accessors. - field_generators_.get(field) - .GenerateDependentInlineAccessorDefinitions(printer); - - printer->Print("\n"); - } - - // Generate has_$name$() and clear_has_$name$() functions for oneofs - // Similar to other has-bits, these must always be in the header if we - // are using a dependent base class. - GenerateOneofHasBits(printer); -} - -void MessageGenerator:: GenerateSingularFieldHasBits(const FieldDescriptor* field, std::map<string, string> vars, io::Printer* printer) { @@ -812,18 +746,6 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { std::map<string, string> vars; SetCommonFieldVariables(field, &vars, options_); - if (use_dependent_base_ && IsFieldDependent(field)) { - vars["tmpl"] = "template<class T>\n"; - vars["dependent_classname"] = - DependentBaseClassTemplateName(descriptor_) + "<T>"; - vars["this_message"] = "reinterpret_cast<T*>(this)->"; - vars["this_const_message"] = "reinterpret_cast<const T*>(this)->"; - } else { - vars["tmpl"] = ""; - vars["dependent_classname"] = vars["classname"]; - vars["this_message"] = ""; - vars["this_const_message"] = ""; - } // Generate has_$name$() or $name$_size(). if (field->is_repeated()) { @@ -851,42 +773,8 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { printer->Print("\n"); } - if (!use_dependent_base_) { - // Generate has_$name$() and clear_has_$name$() functions for oneofs - // If we aren't using a dependent base, they can be with the other functions - // that are #ifdef-guarded. - GenerateOneofHasBits(printer); - } -} - -void MessageGenerator:: -GenerateDependentBaseClassDefinition(io::Printer* printer) { - if (!use_dependent_base_) { - return; - } - - std::map<string, string> vars; - vars["classname"] = DependentBaseClassTemplateName(descriptor_); - vars["full_name"] = descriptor_->full_name(); - vars["superclass"] = SuperClassName(descriptor_, options_); - - printer->Print(vars, - "template <class T>\n" - "class $classname$ : public $superclass$ " - "/* @@protoc_insertion_point(dep_base_class_definition:$full_name$) */ {\n" - " public:\n"); - printer->Indent(); - - printer->Print(vars, - "$classname$() {}\n" - "virtual ~$classname$() {}\n" - "\n"); - - // Generate dependent accessor methods for all fields. - GenerateDependentFieldAccessorDeclarations(printer); - - printer->Outdent(); - printer->Print("};\n"); + // Generate has_$name$() and clear_has_$name$() functions for oneofs. + GenerateOneofHasBits(printer); } void MessageGenerator:: @@ -919,7 +807,7 @@ GenerateClassDefinition(io::Printer* printer) { "$classname$*>(&_$classname$_default_instance_); }\n"); if (HasDescriptorMethods(descriptor_->file(), options_)) { printer->Print( - " void MergeFrom(const ::google::protobuf::Message& other) PROTOBUF_FINAL;\n" + " void MergeFrom(const ::google::protobuf::Message& other) final;\n" " ::google::protobuf::Metadata GetMetadata() const;\n" "};\n"); } else { @@ -927,10 +815,6 @@ GenerateClassDefinition(io::Printer* printer) { } return; } - if (use_dependent_base_) { - GenerateDependentBaseClassDefinition(printer); - printer->Print("\n"); - } std::map<string, string> vars; vars["classname"] = classname_; @@ -942,20 +826,12 @@ GenerateClassDefinition(io::Printer* printer) { } else { vars["dllexport"] = options_.dllexport_decl + " "; } - if (use_dependent_base_) { - vars["superclass"] = - DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">"; - } else { - vars["superclass"] = SuperClassName(descriptor_, options_); - } + vars["superclass"] = SuperClassName(descriptor_, options_); printer->Print(vars, "class $dllexport$$classname$ : public $superclass$ " "/* @@protoc_insertion_point(class_definition:$full_name$) */ " "{\n"); printer->Annotate("classname", descriptor_); - if (use_dependent_base_) { - printer->Print(vars, " friend class $superclass$;\n"); - } printer->Print(" public:\n"); printer->Indent(); @@ -1016,10 +892,10 @@ GenerateClassDefinition(io::Printer* printer) { // virtual method version of GetArenaNoVirtual(), required for generic dispatch given a // MessageLite* (e.g., in RepeatedField::AddAllocated()). printer->Print( - "inline ::google::protobuf::Arena* GetArena() const PROTOBUF_FINAL {\n" + "inline ::google::protobuf::Arena* GetArena() const final {\n" " return GetArenaNoVirtual();\n" "}\n" - "inline void* GetMaybeArenaPointer() const PROTOBUF_FINAL {\n" + "inline void* GetMaybeArenaPointer() const final {\n" " return MaybeArenaPtr();\n" "}\n"); } @@ -1071,7 +947,7 @@ GenerateClassDefinition(io::Printer* printer) { " return reinterpret_cast<const $classname$*>(\n" " &_$classname$_default_instance_);\n" "}\n" - "static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =\n" + "static constexpr int kIndexInFileMessages =\n" " $message_index$;\n" "\n"); @@ -1091,12 +967,13 @@ GenerateClassDefinition(io::Printer* printer) { "template<typename T> bool Is() const {\n" " return _any_metadata_.Is<T>();\n" "}\n" + "static bool ParseAnyTypeUrl(const string& type_url,\n" + " string* full_type_name);\n" "\n"); } - vars["new_final"] = " PROTOBUF_FINAL"; + vars["new_final"] = " final"; - vars["create_func"] = MessageCreateFunction(descriptor_); printer->Print(vars, "void Swap($classname$* other);\n" "friend void swap($classname$& a, $classname$& b) {\n" @@ -1106,32 +983,32 @@ GenerateClassDefinition(io::Printer* printer) { "// implements Message ----------------------------------------------\n" "\n" "inline $classname$* New() const$new_final$ {\n" - " return ::google::protobuf::Arena::$create_func$<$classname$>(NULL);\n" + " return CreateMaybeMessage<$classname$>(NULL);\n" "}\n" "\n" "$classname$* New(::google::protobuf::Arena* arena) const$new_final$ {\n" - " return ::google::protobuf::Arena::$create_func$<$classname$>(arena);\n" + " return CreateMaybeMessage<$classname$>(arena);\n" "}\n"); // For instances that derive from Message (rather than MessageLite), some // methods are virtual and should be marked as final. string use_final = HasDescriptorMethods(descriptor_->file(), options_) ? - " PROTOBUF_FINAL" : ""; + " final" : ""; if (HasGeneratedMethods(descriptor_->file(), options_)) { if (HasDescriptorMethods(descriptor_->file(), options_)) { printer->Print(vars, - "void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;\n" - "void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;\n"); + "void CopyFrom(const ::google::protobuf::Message& from) final;\n" + "void MergeFrom(const ::google::protobuf::Message& from) final;\n"); } else { printer->Print(vars, "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from)\n" - " PROTOBUF_FINAL;\n"); + " final;\n"); } - vars["clear_final"] = " PROTOBUF_FINAL"; - vars["is_initialized_final"] = " PROTOBUF_FINAL"; - vars["merge_partial_final"] = " PROTOBUF_FINAL"; + vars["clear_final"] = " final"; + vars["is_initialized_final"] = " final"; + vars["merge_partial_final"] = " final"; printer->Print( vars, @@ -1140,7 +1017,7 @@ GenerateClassDefinition(io::Printer* printer) { "void Clear()$clear_final$;\n" "bool IsInitialized() const$is_initialized_final$;\n" "\n" - "size_t ByteSizeLong() const PROTOBUF_FINAL;\n" + "size_t ByteSizeLong() const final;\n" "bool MergePartialFromCodedStream(\n" " ::google::protobuf::io::CodedInputStream* input)$merge_partial_final$;\n"); if (!options_.table_driven_serialization || @@ -1148,7 +1025,7 @@ GenerateClassDefinition(io::Printer* printer) { printer->Print( "void SerializeWithCachedSizes(\n" " ::google::protobuf::io::CodedOutputStream* output) const " - "PROTOBUF_FINAL;\n"); + "final;\n"); } // DiscardUnknownFields() is implemented in message.cc using reflections. We // need to implement this function in generated code for messages. @@ -1160,19 +1037,18 @@ GenerateClassDefinition(io::Printer* printer) { if (HasFastArraySerialization(descriptor_->file(), options_)) { printer->Print( "::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(\n" - " bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;\n"); + " bool deterministic, ::google::protobuf::uint8* target) const final;\n"); } } printer->Print( - "int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }\n" - "private:\n" - "void SharedCtor();\n" - "void SharedDtor();\n" - "void SetCachedSize(int size) const$final$;\n" - "void InternalSwap($classname$* other);\n", - "classname", classname_, - "final", use_final); + "int GetCachedSize() const final { return _cached_size_.Get(); }" + "\n\nprivate:\n" + "void SharedCtor();\n" + "void SharedDtor();\n" + "void SetCachedSize(int size) const$final$;\n" + "void InternalSwap($classname$* other);\n", + "classname", classname_, "final", use_final); if (SupportsArenas(descriptor_)) { printer->Print( // TODO(gerbens) Make this private! Currently people are deriving from @@ -1212,11 +1088,11 @@ GenerateClassDefinition(io::Printer* printer) { if (HasDescriptorMethods(descriptor_->file(), options_)) { printer->Print( - "::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;\n" + "::google::protobuf::Metadata GetMetadata() const final;\n" "\n"); } else { printer->Print( - "::std::string GetTypeName() const PROTOBUF_FINAL;\n" + "::std::string GetTypeName() const final;\n" "\n"); } @@ -1295,7 +1171,6 @@ GenerateClassDefinition(io::Printer* printer) { for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { printer->Print( "inline bool has_$oneof_name$() const;\n" - "void clear_$oneof_name$();\n" "inline void clear_has_$oneof_name$();\n\n", "oneof_name", descriptor_->oneof_decl(i)->name()); } @@ -1313,7 +1188,8 @@ GenerateClassDefinition(io::Printer* printer) { bool need_to_emit_cached_size = true; // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it. - const string cached_size_decl = "mutable int _cached_size_;\n"; + const string cached_size_decl = + "mutable ::google::protobuf::internal::CachedSize _cached_size_;\n"; const size_t sizeof_has_bits = HasBitsSize(); const string has_bits_decl = sizeof_has_bits == 0 ? "" : @@ -1423,13 +1299,10 @@ GenerateClassDefinition(io::Printer* printer) { // The TableStruct struct needs access to the private parts, in order to // construct the offsets of all members. - // TODO(gerbens) Remove the friend for InitDefaults. - printer->Print( - "friend struct ::$file_namespace$::TableStruct;\n" - "friend void ::$file_namespace$::InitDefaults$scc_name$Impl();\n", - // Vars. - "scc_name", scc_name_, "file_namespace", - FileLevelNamespace(descriptor_)); + printer->Print("friend struct ::$file_namespace$::TableStruct;\n", + // Vars. + "scc_name", scc_name_, "file_namespace", + FileLevelNamespace(descriptor_)); printer->Outdent(); printer->Print("};"); @@ -1437,18 +1310,6 @@ GenerateClassDefinition(io::Printer* printer) { } void MessageGenerator:: -GenerateDependentInlineMethods(io::Printer* printer) { - if (IsMapEntryMessage(descriptor_)) return; - for (int i = 0; i < descriptor_->field_count(); i++) { - if (descriptor_->field(i)->options().weak()) { - field_generators_.get(descriptor_->field(i)) - .GenerateDependentInlineAccessorDefinitions(printer); - } - } - GenerateDependentFieldAccessorDefinitions(printer); -} - -void MessageGenerator:: GenerateInlineMethods(io::Printer* printer) { if (IsMapEntryMessage(descriptor_)) return; GenerateFieldAccessorDefinitions(printer); @@ -1603,7 +1464,8 @@ uint32 CalculateType(uint32 type, uint32 type_class) { return (type - 1) + type_class * 20; } -uint32 CalcFieldNum(const FieldDescriptor* field, const Options& options) { +uint32 CalcFieldNum(const FieldGenerator&, const FieldDescriptor* field, + const Options& options) { bool is_a_map = IsMapEntryMessage(field->containing_type()); int type = field->type(); if (field->containing_oneof()) { @@ -1624,9 +1486,16 @@ uint32 CalcFieldNum(const FieldDescriptor* field, const Options& options) { #else // We need to calculate for each field what function the table driven code // should use to serialize it. This returns the index in a lookup table. -uint32 CalcFieldNum(const FieldDescriptor* field, const Options& options) { +uint32 CalcFieldNum(const FieldGenerator& generator, + const FieldDescriptor* field, const Options& options) { bool is_a_map = IsMapEntryMessage(field->containing_type()); int type = field->type(); + if (type == FieldDescriptor::TYPE_STRING || + type == FieldDescriptor::TYPE_BYTES) { + if (generator.IsInlined()) { + type = internal::FieldMetadata::kInlinedType; + } + } if (field->containing_oneof()) { return internal::FieldMetadata::CalculateType( type, internal::FieldMetadata::kOneOf); @@ -1668,6 +1537,8 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { if (IsMapEntryMessage(descriptor_)) { for (int i = 0; i < 2; i++) { const FieldDescriptor* field = sorted[i]; + const FieldGenerator& generator = field_generators_.get(field); + uint32 tag = internal::WireFormatLite::MakeTag( field->number(), WireFormat::WireTypeForFieldType(field->type())); @@ -1676,7 +1547,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { vars["field_name"] = FieldName(field); vars["tag"] = SimpleItoa(tag); vars["hasbit"] = SimpleItoa(i); - vars["type"] = SimpleItoa(CalcFieldNum(field, options_)); + vars["type"] = SimpleItoa(CalcFieldNum(generator, field, options_)); vars["ptr"] = "NULL"; if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { GOOGLE_CHECK(!IsMapEntryMessage(field->message_type())); @@ -1765,7 +1636,9 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { SimpleItoa(FindMessageIndexInFile(field->message_type())); } } - vars["type"] = SimpleItoa(CalcFieldNum(field, options_)); + + const FieldGenerator& generator = field_generators_.get(field); + vars["type"] = SimpleItoa(CalcFieldNum(generator, field, options_)); if (field->options().weak()) { @@ -1912,6 +1785,11 @@ GenerateClassMethods(io::Printer* printer) { "bool $classname$::UnpackTo(::google::protobuf::Message* message) const {\n" " return _any_metadata_.UnpackTo(message);\n" "}\n" + "bool $classname$::ParseAnyTypeUrl(const string& type_url,\n" + " string* full_type_name) {\n" + " return ::google::protobuf::internal::ParseAnyTypeUrl(type_url,\n" + " full_type_name);\n" + "}\n" "\n", "classname", classname_); } @@ -2049,16 +1927,26 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { } processing_type = static_cast<unsigned>(field->type()); + const FieldGenerator& generator = field_generators_.get(field); if (field->type() == FieldDescriptor::TYPE_STRING) { switch (EffectiveStringCType(field)) { case FieldOptions::STRING: - default: + default: { + if (generator.IsInlined()) { + processing_type = internal::TYPE_STRING_INLINED; + break; + } break; + } } } else if (field->type() == FieldDescriptor::TYPE_BYTES) { switch (EffectiveStringCType(field)) { case FieldOptions::STRING: default: + if (generator.IsInlined()) { + processing_type = internal::TYPE_BYTES_INLINED; + break; + } break; } } @@ -2093,7 +1981,7 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { "{\n" " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" " $classname$, $name$_),\n" - " static_cast< ::google::protobuf::uint32>($presence$),\n" + " static_cast<::google::protobuf::uint32>($presence$),\n" " $nwtype$, $pwtype$, $ptype$, $tag_size$\n" "},\n"); } @@ -2150,20 +2038,7 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { printer->Print( vars, "{::google::protobuf::internal::AuxillaryParseTableField::message_aux{\n" - " &$ns$::_$classname$_default_instance_,\n"); - - bool dont_emit_table = - !TableDrivenParsingEnabled(field->message_type(), options_); - - if (dont_emit_table) { - printer->Print(" NULL,\n"); - } else { - printer->Print(vars, - " ::$file_namespace$::TableStruct::schema +\n" - " $ns$::$classname$::kIndexInFileMessages,\n"); - } - - printer->Print("}},\n"); + " &$ns$::_$classname$_default_instance_}},\n"); last_field_number++; break; } @@ -2174,7 +2049,7 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { field->default_value_string().empty() ? "&::google::protobuf::internal::fixed_address_empty_string" : "&" + Namespace(field) + " ::" + classname_ + - "::_default_" + FieldName(field) + "_"; + "::" + MakeDefaultName(field); break; case FieldOptions::CORD: case FieldOptions::STRING_PIECE: @@ -2245,14 +2120,20 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets( for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); if (field->containing_oneof() || field->options().weak()) { - printer->Print("offsetof($classname$DefaultTypeInternal, $name$_),\n", + printer->Print("offsetof($classname$DefaultTypeInternal, $name$_)", "classname", full_classname, "name", FieldName(field)); } else { printer->Print( - "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " - "$name$_),\n", + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_)", "classname", full_classname, "name", FieldName(field)); } + + uint32 tag = field_generators_.get(field).CalculateFieldTag(); + if (tag != 0) { + printer->Print(" | $tag$", "tag", SimpleItoa(tag)); + } + + printer->Print(",\n"); } for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { @@ -2286,15 +2167,6 @@ GenerateSharedConstructorCode(io::Printer* printer) { "classname", classname_); printer->Indent(); - bool need_to_clear_cached_size = true; - // We reproduce the logic used for laying out _cached_sized_ in the class - // definition, as to initialize it in-order. - if (HasFieldPresence(descriptor_->file()) && - (HasBitsSize() % 8) != 0) { - printer->Print("_cached_size_ = 0;\n"); - need_to_clear_cached_size = false; - } - std::vector<bool> processed(optimized_order_.size(), false); GenerateConstructorBody(printer, processed, false); @@ -2304,10 +2176,6 @@ GenerateSharedConstructorCode(io::Printer* printer) { "oneof_name", descriptor_->oneof_decl(i)->name()); } - if (need_to_clear_cached_size) { - printer->Print("_cached_size_ = 0;\n"); - } - printer->Outdent(); printer->Print("}\n\n"); } @@ -2491,12 +2359,7 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, void MessageGenerator:: GenerateStructors(io::Printer* printer) { string superclass; - if (use_dependent_base_) { - superclass = - DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">"; - } else { - superclass = SuperClassName(descriptor_, options_); - } + superclass = SuperClassName(descriptor_, options_); string initializer_with_arena = superclass + "()"; if (descriptor_->extension_range_count() > 0) { @@ -2528,15 +2391,14 @@ GenerateStructors(io::Printer* printer) { initializer_null += ", _any_metadata_(&type_url_, &value_)"; } if (num_weak_fields_ > 0) { - initializer_null += ", _weak_field_map_(NULL)"; + initializer_null += ", _weak_field_map_(nullptr)"; } printer->Print( "$classname$::$classname$()\n" " : $initializer$ {\n" - " if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {\n" - " ::$file_namespace$::InitDefaults$scc_name$();\n" - " }\n" + " ::google::protobuf::internal::InitSCC(\n" + " &$file_namespace$::scc_info_$scc_name$.base);\n" " SharedCtor();\n" " // @@protoc_insertion_point(constructor:$full_name$)\n" "}\n", @@ -2548,7 +2410,9 @@ GenerateStructors(io::Printer* printer) { printer->Print( "$classname$::$classname$(::google::protobuf::Arena* arena)\n" " : $initializer$ {\n" - " ::$file_namespace$::InitDefaults$scc_name$();\n" + " " + "::google::protobuf::internal::InitSCC(&$file_namespace$::scc_info_$scc_name$." + "base);\n" " SharedCtor();\n" " RegisterArenaDtor(arena);\n" " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" @@ -2589,16 +2453,6 @@ GenerateStructors(io::Printer* printer) { printer->Print(",\n_has_bits_(from._has_bits_)"); } - bool need_to_emit_cached_size = true; - const string cached_size_decl = ",\n_cached_size_(0)"; - // We reproduce the logic used for laying out _cached_sized_ in the class - // definition, as to initialize it in-order. - if (HasFieldPresence(descriptor_->file()) && - (HasBitsSize() % 8) != 0) { - printer->Print(cached_size_decl.c_str()); - need_to_emit_cached_size = false; - } - std::vector<bool> processed(optimized_order_.size(), false); for (int i = 0; i < optimized_order_.size(); ++i) { const FieldDescriptor* field = optimized_order_[i]; @@ -2613,11 +2467,6 @@ GenerateStructors(io::Printer* printer) { "name", FieldName(field)); } - if (need_to_emit_cached_size) { - printer->Print(cached_size_decl.c_str()); - need_to_emit_cached_size = false; - } - if (IsAnyMessage(descriptor_)) { printer->Print(",\n_any_metadata_(&type_url_, &value_)"); } @@ -2702,12 +2551,10 @@ GenerateStructors(io::Printer* printer) { // Generate SetCachedSize. printer->Print( - "void $classname$::SetCachedSize(int size) const {\n" - " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" - " _cached_size_ = size;\n" - " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" - "}\n", - "classname", classname_); + "void $classname$::SetCachedSize(int size) const {\n" + " _cached_size_.Set(size);\n" + "}\n", + "classname", classname_); // Only generate this member if it's not disabled. if (HasDescriptorMethods(descriptor_->file(), options_) && @@ -2726,7 +2573,9 @@ GenerateStructors(io::Printer* printer) { printer->Print( "const $classname$& $classname$::default_instance() {\n" - " ::$file_namespace$::InitDefaults$scc_name$();\n" + " " + "::google::protobuf::internal::InitSCC(&$file_namespace$::scc_info_$scc_name$.base)" + ";\n" " return *internal_default_instance();\n" "}\n\n", "classname", classname_, "scc_name", scc_name_, "file_namespace", @@ -2737,7 +2586,7 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) { printer->Print( "template<> " "GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE " - "$classname$* Arena::$create_func$< $classname$ >(Arena* arena) {\n" + "$classname$* Arena::CreateMaybeMessage< $classname$ >(Arena* arena) {\n" " return Arena::$create_func$Internal< $classname$ >(arena);\n" "}\n", "classname", QualifiedClassName(descriptor_), @@ -2823,10 +2672,10 @@ GenerateClear(io::Printer* printer) { chunks.push_back(chunks_frag[i]); const FieldDescriptor* field = chunks_frag[i].front(); const FieldDescriptor* next_field = - (i + 1) < chunks_frag.size() ? chunks_frag[i + 1].front() : NULL; + (i + 1) < chunks_frag.size() ? chunks_frag[i + 1].front() : nullptr; if (CanInitializeByZeroing(field) && (chunks_frag[i].size() == 1 || unconditional_budget < 0) && - next_field != NULL && + next_field != nullptr && has_bit_indices_[field->index()] / 8 == has_bit_indices_[next_field->index()] / 8) { GOOGLE_CHECK(!CanInitializeByZeroing(next_field)); @@ -3111,7 +2960,6 @@ GenerateSwap(io::Printer* printer) { printer->Print("_internal_metadata_.Swap(&other->_internal_metadata_);\n"); - printer->Print("swap(_cached_size_, other->_cached_size_);\n"); if (descriptor_->extension_range_count() > 0) { printer->Print("_extensions_.Swap(&other->_extensions_);\n"); } @@ -3492,8 +3340,12 @@ GenerateMergeFromCodedStream(io::Printer* printer) { printer->Print("for (;;) {\n"); printer->Indent(); - uint32 maxtag = descriptor_->field_count() == 0 ? 0 : - WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]); + // To calculate the maximum tag to expect, we look at the highest-numbered + // field. We need to be prepared to handle more than one wire type if that + // field is a packable repeated field, so to simplify things we assume the + // highest possible wire type of 5. + uint32 maxtag = + ordered_fields.empty() ? 0 : ordered_fields.back()->number() * 8 + 5; const int kCutoff0 = 127; // fits in 1-byte varint const int kCutoff1 = (127 << 7) + 127; // fits in 2-byte varint @@ -3511,6 +3363,15 @@ GenerateMergeFromCodedStream(io::Printer* printer) { break; } } + + for (int i = 0; i < parent->extension_count(); i++) { + const FieldDescriptor* field = parent->extension(i); + if (field->type() == FieldDescriptor::TYPE_GROUP && + field->message_type() == descriptor_) { + capture_last_tag = true; + break; + } + } } for (int i = 0; i < descriptor_->file()->extension_count(); i++) { @@ -3522,7 +3383,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) { } } - printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = " + printer->Print("::std::pair<::google::protobuf::uint32, bool> p = " "input->ReadTagWithCutoffNoLastTag($max$u);\n" "tag = p.first;\n" "if (!p.second) goto handle_unusual;\n", @@ -3621,7 +3482,6 @@ GenerateMergeFromCodedStream(io::Printer* printer) { printer->Outdent(); printer->Print("}\n\n"); } - printer->Print("default: {\n"); printer->Indent(); } @@ -4012,7 +3872,7 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { // Merge the fields and the extension ranges, both sorted by field number. { LazySerializerEmitter e(this, printer, to_array); - const FieldDescriptor* last_weak_field = NULL; + const FieldDescriptor* last_weak_field = nullptr; int i, j; for (i = 0, j = 0; i < ordered_fields.size() || j < sorted_extensions.size();) { @@ -4024,16 +3884,16 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { last_weak_field = field; PrintFieldComment(printer, field); } else { - if (last_weak_field != NULL) { + if (last_weak_field != nullptr) { e.Emit(last_weak_field); - last_weak_field = NULL; + last_weak_field = nullptr; } e.Emit(field); } } else { - if (last_weak_field != NULL) { + if (last_weak_field != nullptr) { e.Emit(last_weak_field); - last_weak_field = NULL; + last_weak_field = nullptr; } e.Flush(); GenerateSerializeOneExtensionRange(printer, @@ -4041,7 +3901,7 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { to_array); } } - if (last_weak_field != NULL) { + if (last_weak_field != nullptr) { e.Emit(last_weak_field); } } @@ -4103,8 +3963,9 @@ static string ConditionalToCheckBitmasks(const std::vector<uint32>& masks) { } GOOGLE_CHECK(!parts.empty()); // If we have multiple parts, each expected to be 0, then bitwise-or them. - string result = parts.size() == 1 ? parts[0] : - StrCat("(", Join(parts, "\n | "), ")"); + string result = parts.size() == 1 + ? parts[0] + : StrCat("(", Join(parts, "\n | "), ")"); return result + " == 0"; } @@ -4117,20 +3978,19 @@ GenerateByteSize(io::Printer* printer) { SetUnknkownFieldsVariable(descriptor_, options_, &vars); vars["classname"] = classname_; vars["full_name"] = descriptor_->full_name(); - printer->Print(vars, - "size_t $classname$::ByteSizeLong() const {\n" - "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" - " size_t total_size = _extensions_.MessageSetByteSize();\n" - " if ($have_unknown_fields$) {\n" - " total_size += ::google::protobuf::internal::WireFormat::\n" - " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n" - " }\n" - " int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);\n" - " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" - " _cached_size_ = cached_size;\n" - " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" - " return total_size;\n" - "}\n"); + printer->Print( + vars, + "size_t $classname$::ByteSizeLong() const {\n" + "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" + " size_t total_size = _extensions_.MessageSetByteSize();\n" + " if ($have_unknown_fields$) {\n" + " total_size += ::google::protobuf::internal::WireFormat::\n" + " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n" + " }\n" + " int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);\n" + " SetCachedSize(cached_size);\n" + " return total_size;\n" + "}\n"); return; } @@ -4362,17 +4222,18 @@ GenerateByteSize(io::Printer* printer) { printer->Print("total_size += _weak_field_map_.ByteSizeLong();\n"); } - // We update _cached_size_ even though this is a const method. In theory, - // this is not thread-compatible, because concurrent writes have undefined - // results. In practice, since any concurrent writes will be writing the - // exact same value, it works on all common processors. In a future version - // of C++, _cached_size_ should be made into an atomic<int>. + // We update _cached_size_ even though this is a const method. Because + // const methods might be called concurrently this needs to be atomic + // operations or the program is undefined. In practice, since any concurrent + // writes will be writing the exact same value, normal writes will work on + // all common processors. We use a dedicated wrapper class to abstract away + // the underlying atomic. This makes it easier on platforms where even relaxed + // memory order might have perf impact to replace it with ordinary loads and + // stores. printer->Print( - "int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);\n" - "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" - "_cached_size_ = cached_size;\n" - "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" - "return total_size;\n"); + "int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);\n" + "SetCachedSize(cached_size);\n" + "return total_size;\n"); printer->Outdent(); printer->Print("}\n"); @@ -4421,7 +4282,7 @@ GenerateIsInitialized(io::Printer* printer) { !ShouldIgnoreRequiredFieldCheck(field, options_) && scc_analyzer_->HasRequiredFields(field->message_type())) { if (field->is_repeated()) { - if (IsImplicitWeakField(field, options_)) { + if (IsImplicitWeakField(field, options_, scc_analyzer_)) { printer->Print( "if (!::google::protobuf::internal::AllAreInitializedWeak(this->$name$_))" " return false;\n", diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index 06e2030b..ca2ca2c9 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -36,9 +36,6 @@ #define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <set> #include <string> #include <google/protobuf/compiler/cpp/cpp_field.h> @@ -87,9 +84,6 @@ class MessageGenerator { // file). void GenerateInlineMethods(io::Printer* printer); - // Dependent methods are always inline. - void GenerateDependentInlineMethods(io::Printer* printer); - // Source file stuff. // Generate extra fields @@ -111,10 +105,7 @@ class MessageGenerator { private: // Generate declarations and definitions of accessors for fields. - void GenerateDependentBaseClassDefinition(io::Printer* printer); - void GenerateDependentFieldAccessorDeclarations(io::Printer* printer); void GenerateFieldAccessorDeclarations(io::Printer* printer); - void GenerateDependentFieldAccessorDefinitions(io::Printer* printer); void GenerateFieldAccessorDefinitions(io::Printer* printer); // Generate the table-driven parsing array. Returns the number of entries @@ -222,15 +213,14 @@ class MessageGenerator { std::vector<const FieldDescriptor *> optimized_order_; std::vector<int> has_bit_indices_; int max_has_bit_index_; - google::protobuf::scoped_array<google::protobuf::scoped_ptr<EnumGenerator> > enum_generators_; - google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> > extension_generators_; + std::unique_ptr<std::unique_ptr<EnumGenerator> []> enum_generators_; + std::unique_ptr<std::unique_ptr<ExtensionGenerator> []> extension_generators_; int num_required_fields_; - bool use_dependent_base_; int num_weak_fields_; // table_driven_ indicates the generated message uses table-driven parsing. bool table_driven_; - google::protobuf::scoped_ptr<MessageLayoutHelper> message_layout_helper_; + std::unique_ptr<MessageLayoutHelper> message_layout_helper_; SCCAnalyzer* scc_analyzer_; string scc_name_; diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index 530a6392..c1e15c52 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -70,17 +70,16 @@ string ReinterpretCast(const string& type, const string& expression, } void SetMessageVariables(const FieldDescriptor* descriptor, - std::map<string, string>* variables, - const Options& options) { + const Options& options, bool implicit_weak, + std::map<string, string>* variables) { SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = FieldMessageTypeName(descriptor); - (*variables)["casted_member"] = - ReinterpretCast((*variables)["type"] + "*", (*variables)["name"] + "_", - IsImplicitWeakField(descriptor, options)); + (*variables)["casted_member"] = ReinterpretCast( + (*variables)["type"] + "*", (*variables)["name"] + "_", implicit_weak); (*variables)["type_default_instance"] = DefaultInstanceName(descriptor->message_type()); (*variables)["type_reference_function"] = - IsImplicitWeakField(descriptor, options) + implicit_weak ? (" " + ReferenceFunctionName(descriptor->message_type()) + "();\n") : ""; (*variables)["stream_writer"] = @@ -94,8 +93,6 @@ void SetMessageVariables(const FieldDescriptor* descriptor, SafeFunctionName(descriptor->containing_type(), descriptor, "release_"); (*variables)["full_name"] = descriptor->full_name(); - (*variables)["create_func"] = - MessageCreateFunction(descriptor->message_type()); } } // namespace @@ -103,11 +100,13 @@ void SetMessageVariables(const FieldDescriptor* descriptor, // =================================================================== MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) + const Options& options, + SCCAnalyzer* scc_analyzer) : FieldGenerator(options), descriptor_(descriptor), - implicit_weak_field_(IsImplicitWeakField(descriptor, options)) { - SetMessageVariables(descriptor, &variables_, options); + implicit_weak_field_( + IsImplicitWeakField(descriptor, options, scc_analyzer)) { + SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_); } MessageFieldGenerator::~MessageFieldGenerator() {} @@ -115,7 +114,7 @@ MessageFieldGenerator::~MessageFieldGenerator() {} void MessageFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { if (implicit_weak_field_) { - printer->Print(variables_, "google::protobuf::MessageLite* $name$_;\n"); + printer->Print(variables_, "::google::protobuf::MessageLite* $name$_;\n"); } else { printer->Print(variables_, "$type$* $name$_;\n"); } @@ -129,8 +128,16 @@ GenerateAccessorDeclarations(io::Printer* printer) const { // the field without creating a strong dependency on the message type. printer->Print(variables_, "private:\n" - "const google::protobuf::MessageLite& _internal_$name$() const;\n" - "google::protobuf::MessageLite* _internal_mutable_$name$();\n" + "const ::google::protobuf::MessageLite& _internal_$name$() const;\n" + "::google::protobuf::MessageLite* _internal_mutable_$name$();\n" + "public:\n"); + } else { + // This inline accessor directly returns member field and is used in + // Serialize such that AFDO profile correctly captures access information to + // message fields under serialize. + printer->Print(variables_, + "private:\n" + "const $type$& _internal_$name$() const;\n" "public:\n"); } printer->Print(variables_, @@ -162,22 +169,22 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( io::Printer* printer) const { if (implicit_weak_field_) { printer->Print(variables_, - "const google::protobuf::MessageLite& $classname$::_internal_$name$() const {\n" + "const ::google::protobuf::MessageLite& $classname$::_internal_$name$() const {\n" " if ($name$_ != NULL) {\n" " return *$name$_;\n" " } else if (&$type_default_instance$ != NULL) {\n" - " return *reinterpret_cast<const google::protobuf::MessageLite*>(\n" + " return *reinterpret_cast<const ::google::protobuf::MessageLite*>(\n" " &$type_default_instance$);\n" " } else {\n" - " return *reinterpret_cast<const google::protobuf::MessageLite*>(\n" - " &::google::protobuf::internal::implicit_weak_message_default_instance);\n" + " return " + "*::google::protobuf::internal::ImplicitWeakMessage::default_instance();\n" " }\n" "}\n"); } if (SupportsArenas(descriptor_)) { if (implicit_weak_field_) { printer->Print(variables_, - "google::protobuf::MessageLite* $classname$::_internal_mutable_$name$() {\n" + "::google::protobuf::MessageLite* $classname$::_internal_mutable_$name$() {\n" " $set_hasbit$\n" " if ($name$_ == NULL) {\n" " if (&$type_default_instance$ == NULL) {\n" @@ -185,7 +192,7 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( " ::google::protobuf::internal::ImplicitWeakMessage>(\n" " GetArenaNoVirtual());\n" " } else {\n" - " $name$_ = reinterpret_cast<const google::protobuf::MessageLite*>(\n" + " $name$_ = reinterpret_cast<const ::google::protobuf::MessageLite*>(\n" " &$type_default_instance$)->New(GetArenaNoVirtual());\n" " }\n" " }\n" @@ -212,13 +219,13 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( "}\n"); } else if (implicit_weak_field_) { printer->Print(variables_, - "google::protobuf::MessageLite* $classname$::_internal_mutable_$name$() {\n" + "::google::protobuf::MessageLite* $classname$::_internal_mutable_$name$() {\n" " $set_hasbit$\n" " if ($name$_ == NULL) {\n" " if (&$type_default_instance$ == NULL) {\n" " $name$_ = new ::google::protobuf::internal::ImplicitWeakMessage;\n" " } else {\n" - " $name$_ = reinterpret_cast<const google::protobuf::MessageLite*>(\n" + " $name$_ = reinterpret_cast<const ::google::protobuf::MessageLite*>(\n" " &$type_default_instance$)->New();\n" " }\n" " }\n" @@ -229,9 +236,14 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( void MessageFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer) const { + if (!implicit_weak_field_) { + printer->Print(variables_, + "inline const $type$& $classname$::_internal_$name$() const {\n" + " return *$field_member$;\n" + "}\n"); + } printer->Print(variables_, "inline const $type$& $classname$::$name$() const {\n" - "$type_reference_function$" " const $type$* p = $casted_member$;\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return p != NULL ? *p : *reinterpret_cast<const $type$*>(\n" @@ -247,7 +259,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { if (SupportsArenas(descriptor_)) { printer->Print(variables_, " if (GetArenaNoVirtual() != NULL) {\n" - " temp = ::google::protobuf::internal::DuplicateIfNonNull(temp, NULL);\n" + " temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);\n" " }\n"); } printer->Print(variables_, @@ -269,16 +281,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { printer->Print(variables_, "inline $type$* $classname$::mutable_$name$() {\n" - "$type_reference_function$" " $set_hasbit$\n" - " if ($name$_ == NULL) {\n"); + " if ($name$_ == NULL) {\n" + " auto* p = CreateMaybeMessage<$type$>(GetArenaNoVirtual());\n"); if (implicit_weak_field_) { printer->Print(variables_, - " _internal_mutable_$name$();\n"); + " $name$_ = reinterpret_cast<::google::protobuf::MessageLite*>(p);\n"); } else { printer->Print(variables_, - " $name$_ = ::google::protobuf::Arena::$create_func$< $type$ >(\n" - " GetArenaNoVirtual());\n"); + " $name$_ = p;\n"); } printer->Print(variables_, " }\n" @@ -309,7 +320,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { // isn't defined in this file. printer->Print(variables_, " ::google::protobuf::Arena* submessage_arena =\n" - " reinterpret_cast< ::google::protobuf::MessageLite*>($name$)->GetArena();\n"); + " reinterpret_cast<::google::protobuf::MessageLite*>($name$)->GetArena();\n"); } else if (!SupportsArenas(descriptor_->message_type())) { printer->Print(variables_, " ::google::protobuf::Arena* submessage_arena = NULL;\n"); @@ -436,7 +447,7 @@ void MessageFieldGenerator:: GenerateSerializeWithCachedSizes(io::Printer* printer) const { printer->Print(variables_, "::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n" - " $number$, *$field_member$, output);\n"); + " $number$, this->_internal_$name$(), output);\n"); } void MessageFieldGenerator:: @@ -444,7 +455,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { printer->Print(variables_, "target = ::google::protobuf::internal::WireFormatLite::\n" " InternalWrite$declared_type$ToArray(\n" - " $number$, *$field_member$, deterministic, target);\n"); + " $number$, this->_internal_$name$(), deterministic, target);\n"); } void MessageFieldGenerator:: @@ -457,11 +468,10 @@ GenerateByteSize(io::Printer* printer) const { // =================================================================== -MessageOneofFieldGenerator:: -MessageOneofFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : MessageFieldGenerator(descriptor, options), - dependent_base_(options.proto_h) { +MessageOneofFieldGenerator::MessageOneofFieldGenerator( + const FieldDescriptor* descriptor, const Options& options, + SCCAnalyzer* scc_analyzer) + : MessageFieldGenerator(descriptor, options, scc_analyzer) { SetCommonOneofFieldVariables(descriptor, &variables_); } @@ -480,7 +490,7 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions( // isn't defined in this file. printer->Print(variables_, " ::google::protobuf::Arena* submessage_arena =\n" - " reinterpret_cast< ::google::protobuf::MessageLite*>($name$)->GetArena();\n"); + " reinterpret_cast<::google::protobuf::MessageLite*>($name$)->GetArena();\n"); } else if (!SupportsArenas(descriptor_->message_type())) { printer->Print(variables_, " ::google::protobuf::Arena* submessage_arena = NULL;\n"); @@ -503,6 +513,12 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions( void MessageOneofFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer) const { + if (!implicit_weak_field_) { + printer->Print(variables_, + "inline const $type$& $classname$::_internal_$name$() const {\n" + " return *$field_member$;\n" + "}\n"); + } printer->Print(variables_, "inline $type$* $classname$::$release_name$() {\n" " // @@protoc_insertion_point(field_release:$full_name$)\n" @@ -512,7 +528,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { if (SupportsArenas(descriptor_)) { printer->Print(variables_, " if (GetArenaNoVirtual() != NULL) {\n" - " temp = ::google::protobuf::internal::DuplicateIfNonNull(temp, NULL);\n" + " temp = ::google::protobuf::internal::DuplicateIfNonNull(temp);\n" " }\n"); } printer->Print(variables_, @@ -565,7 +581,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$ = ::google::protobuf::Arena::$create_func$< $type$ >(\n" + " $field_member$ = CreateMaybeMessage< $type$ >(\n" " GetArenaNoVirtual());\n" " }\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" @@ -611,12 +627,13 @@ GenerateConstructorCode(io::Printer* printer) const { // =================================================================== RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) + const FieldDescriptor* descriptor, const Options& options, + SCCAnalyzer* scc_analyzer) : FieldGenerator(options), descriptor_(descriptor), - dependent_field_(options.proto_h && IsFieldDependent(descriptor)), - implicit_weak_field_(IsImplicitWeakField(descriptor, options)) { - SetMessageVariables(descriptor, &variables_, options); + implicit_weak_field_( + IsImplicitWeakField(descriptor, options, scc_analyzer)) { + SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_); } RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} @@ -628,19 +645,6 @@ GeneratePrivateMembers(io::Printer* printer) const { } void RepeatedMessageFieldGenerator:: -InternalGenerateTypeDependentAccessorDeclarations(io::Printer* printer) const { - printer->Print(variables_, "$deprecated_attr$$type$* ${$add_$name$$}$();\n"); - printer->Annotate("{", "}", descriptor_); -} - -void RepeatedMessageFieldGenerator:: -GenerateDependentAccessorDeclarations(io::Printer* printer) const { - if (dependent_field_) { - InternalGenerateTypeDependentAccessorDeclarations(printer); - } -} - -void RepeatedMessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, "$deprecated_attr$$type$* ${$mutable_$name$$}$(int index);\n"); @@ -653,9 +657,8 @@ GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, "$deprecated_attr$const $type$& $name$(int index) const;\n"); printer->Annotate("name", descriptor_); - if (!dependent_field_) { - InternalGenerateTypeDependentAccessorDeclarations(printer); - } + printer->Print(variables_, "$deprecated_attr$$type$* ${$add_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); printer->Print(variables_, "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< $type$ >&\n" " $name$() const;\n"); @@ -663,29 +666,6 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } void RepeatedMessageFieldGenerator:: -GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { - if (!dependent_field_) { - return; - } - std::map<string, string> variables(variables_); - // For the CRTP base class, all mutation methods are dependent, and so - // they must be in the header. - variables["dependent_classname"] = - DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>"; - variables["this_message"] = DependentBaseDownCast(); - variables["this_const_message"] = DependentBaseConstDownCast(); - - // Generate per-element accessors: - printer->Print(variables, - "template <class T>\n" - "inline $type$* $dependent_classname$::add_$name$() {\n" - " // @@protoc_insertion_point(field_add:$full_name$)\n" - "$type_reference_function$" - " return $this_message$$name$_.Add();\n" - "}\n"); -} - -void RepeatedMessageFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer) const { printer->Print(variables_, "inline $type$* $classname$::mutable_$name$(int index) {\n" @@ -705,7 +685,6 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { printer->Print(variables_, "inline const $type$& $classname$::$name$(int index) const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" - "$type_reference_function$" " return $name$_.InternalCheckedGet(index,\n" " *reinterpret_cast<const $type$*>(&$type_default_instance$));\n" "}\n"); @@ -718,14 +697,11 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "}\n"); } - if (!dependent_field_) { - printer->Print(variables_, - "inline $type$* $classname$::add_$name$() {\n" - " // @@protoc_insertion_point(field_add:$full_name$)\n" - "$type_reference_function$" - " return $name$_.Add();\n" - "}\n"); - } + printer->Print(variables_, + "inline $type$* $classname$::add_$name$() {\n" + " // @@protoc_insertion_point(field_add:$full_name$)\n" + " return $name$_.Add();\n" + "}\n"); printer->Print(variables_, "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h index e165404f..6879539c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h @@ -38,18 +38,17 @@ #include <map> #include <string> #include <google/protobuf/compiler/cpp/cpp_field.h> +#include <google/protobuf/compiler/cpp/cpp_helpers.h> namespace google { namespace protobuf { namespace compiler { namespace cpp { -bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options); - class MessageFieldGenerator : public FieldGenerator { public: MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + const Options& options, SCCAnalyzer* scc_analyzer); ~MessageFieldGenerator(); // implements FieldGenerator --------------------------------------- @@ -81,7 +80,7 @@ class MessageFieldGenerator : public FieldGenerator { class MessageOneofFieldGenerator : public MessageFieldGenerator { public: MessageOneofFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + const Options& options, SCCAnalyzer* scc_analyzer); ~MessageOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- @@ -97,21 +96,19 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { void GenerateConstructorCode(io::Printer* printer) const; private: - const bool dependent_base_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator); }; class RepeatedMessageFieldGenerator : public FieldGenerator { public: RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + const Options& options, + SCCAnalyzer* scc_analyzer); ~RepeatedMessageFieldGenerator(); // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; - void GenerateDependentAccessorDeclarations(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const; void GenerateInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; @@ -124,11 +121,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { void GenerateByteSize(io::Printer* printer) const; private: - void InternalGenerateTypeDependentAccessorDeclarations( - io::Printer* printer) const; - const FieldDescriptor* descriptor_; - const bool dependent_field_; const bool implicit_weak_field_; std::map<string, string> variables_; diff --git a/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc index f72a7d60..eb7cd1c7 100644 --- a/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc @@ -34,7 +34,7 @@ #include <gtest/gtest.h> #if LANG_CXX11 -#include <google/protobuf/stubs/type_traits.h> +#include <type_traits> #endif namespace google { diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index b0dd8836..f09885be 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -54,6 +54,7 @@ struct Options { table_driven_parsing(false), table_driven_serialization(false), lite_implicit_weak_fields(false), + bootstrap(false), num_cc_files(0), access_info_map(NULL) {} @@ -66,6 +67,7 @@ struct Options { bool table_driven_parsing; bool table_driven_serialization; bool lite_implicit_weak_fields; + bool bootstrap; int num_cc_files; string annotation_pragma_name; string annotation_guard_name; diff --git a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h index 9641ba40..42a3b5cd 100644 --- a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h +++ b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h @@ -50,10 +50,10 @@ namespace cpp { class PaddingOptimizer : public MessageLayoutHelper { public: PaddingOptimizer() {} - ~PaddingOptimizer() {} + ~PaddingOptimizer() override {} void OptimizeLayout(std::vector<const FieldDescriptor*>* fields, - const Options& options); + const Options& options) override; }; } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc index ceb2270e..ff6ba0f8 100644 --- a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc @@ -35,9 +35,6 @@ // worth. #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/compiler/cpp/cpp_generator.h> #include <google/protobuf/compiler/command_line_interface.h> @@ -172,7 +169,7 @@ class TestGenerator : public CodeGenerator { void TryInsert(const string& filename, const string& insertion_point, GeneratorContext* context) const { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->OpenForInsert(filename, insertion_point)); io::Printer printer(output.get(), '$'); printer.Print("// inserted $name$\n", "name", insertion_point); diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index c9901e84..cf6c4b33 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -34,8 +34,8 @@ #include <google/protobuf/compiler/cpp/cpp_string_field.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/strutil.h> @@ -53,7 +53,7 @@ void SetStringVariables(const FieldDescriptor* descriptor, (*variables)["default"] = DefaultValue(descriptor); (*variables)["default_length"] = SimpleItoa(descriptor->default_value_string().length()); - string default_variable_string = "_default_" + FieldName(descriptor) + "_"; + string default_variable_string = MakeDefaultName(descriptor); (*variables)["default_variable_name"] = default_variable_string; (*variables)["default_variable"] = descriptor->default_value_string().empty() @@ -82,8 +82,24 @@ void SetStringVariables(const FieldDescriptor* descriptor, StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor, const Options& options) - : FieldGenerator(options), descriptor_(descriptor), - lite_(!HasDescriptorMethods(descriptor->file(), options)) { + : FieldGenerator(options), + descriptor_(descriptor), + lite_(!HasDescriptorMethods(descriptor->file(), options)), + inlined_(false) { + + // TODO(ckennelly): Handle inlining for any.proto. + if (IsAnyMessage(descriptor_->containing_type())) { + inlined_ = false; + } + if (descriptor_->containing_type()->options().map_entry()) { + inlined_ = false; + } + + // Limit to proto2, as we rely on has bits to distinguish field presence for + // release_$name$. On proto3, we cannot use the address of the string + // instance when the field has been inlined. + inlined_ = inlined_ && HasFieldPresence(descriptor_->file()); + SetStringVariables(descriptor, &variables_, options); } @@ -91,27 +107,36 @@ StringFieldGenerator::~StringFieldGenerator() {} void StringFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { - // N.B. that we continue to use |ArenaStringPtr| instead of |string*| for - // string fields, even when SupportArenas(descriptor_) == false. Why? - // The simple answer is to avoid unmaintainable complexity. The reflection - // code assumes ArenaStringPtrs. These are *almost* in-memory-compatible with - // string*, except for the pointer tags and related ownership semantics. We - // could modify the runtime code to use string* for the not-supporting-arenas - // case, but this would require a way to detect which type of class was - // generated (adding overhead and complexity to GeneratedMessageReflection) - // and littering the runtime code paths with conditionals. It's simpler to - // stick with this but use lightweight accessors that assume arena == NULL. - // There should be very little overhead anyway because it's just a tagged - // pointer in-memory. - printer->Print(variables_, "::google::protobuf::internal::ArenaStringPtr $name$_;\n"); + if (inlined_) { + printer->Print(variables_, + "::google::protobuf::internal::InlinedStringField $name$_;\n"); + } else { + // N.B. that we continue to use |ArenaStringPtr| instead of |string*| for + // string fields, even when SupportArenas(descriptor_) == false. Why? The + // simple answer is to avoid unmaintainable complexity. The reflection code + // assumes ArenaStringPtrs. These are *almost* in-memory-compatible with + // string*, except for the pointer tags and related ownership semantics. We + // could modify the runtime code to use string* for the + // not-supporting-arenas case, but this would require a way to detect which + // type of class was generated (adding overhead and complexity to + // GeneratedMessageReflection) and littering the runtime code paths with + // conditionals. It's simpler to stick with this but use lightweight + // accessors that assume arena == NULL. There should be very little + // overhead anyway because it's just a tagged pointer in-memory. + printer->Print(variables_, "::google::protobuf::internal::ArenaStringPtr $name$_;\n"); + } } void StringFieldGenerator:: GenerateStaticMembers(io::Printer* printer) const { if (!descriptor_->default_value_string().empty()) { + // We make the default instance public, so it can be initialized by + // non-friend code. printer->Print(variables_, + "public:\n" "static ::google::protobuf::internal::ExplicitlyConstructed< ::std::string>" - " $default_variable_name$;\n"); + " $default_variable_name$;\n" + "private:\n"); } } @@ -246,9 +271,23 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return $name$_.Mutable($default_variable$, GetArenaNoVirtual());\n" "}\n" "inline ::std::string* $classname$::$release_name$() {\n" - " // @@protoc_insertion_point(field_release:$full_name$)\n" + " // @@protoc_insertion_point(field_release:$full_name$)\n"); + + if (HasFieldPresence(descriptor_->file())) { + printer->Print(variables_, + " if (!has_$name$()) {\n" + " return NULL;\n" + " }\n" + " $clear_hasbit$\n" + " return $name$_.ReleaseNonDefault(" + "$default_variable$, GetArenaNoVirtual());\n"); + } else { + printer->Print(variables_, " $clear_hasbit$\n" - " return $name$_.Release($default_variable$, GetArenaNoVirtual());\n" + " return $name$_.Release($default_variable$, GetArenaNoVirtual());\n"); + } + + printer->Print(variables_, "}\n" "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" " if ($name$ != NULL) {\n" @@ -322,9 +361,22 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return $name$_.MutableNoArena($default_variable$);\n" "}\n" "inline ::std::string* $classname$::$release_name$() {\n" - " // @@protoc_insertion_point(field_release:$full_name$)\n" + " // @@protoc_insertion_point(field_release:$full_name$)\n"); + + if (HasFieldPresence(descriptor_->file())) { + printer->Print(variables_, + " if (!has_$name$()) {\n" + " return NULL;\n" + " }\n" " $clear_hasbit$\n" - " return $name$_.ReleaseNoArena($default_variable$);\n" + " return $name$_.ReleaseNonDefaultNoArena($default_variable$);\n"); + } else { + printer->Print(variables_, + " $clear_hasbit$\n" + " return $name$_.ReleaseNoArena($default_variable$);\n"); + } + + printer->Print(variables_, "}\n" "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" " if ($name$ != NULL) {\n" @@ -343,7 +395,7 @@ GenerateNonInlineAccessorDefinitions(io::Printer* printer) const { if (!descriptor_->default_value_string().empty()) { // Initialized in GenerateDefaultInstanceAllocator. printer->Print(variables_, - "::google::protobuf::internal::ExplicitlyConstructed< ::std::string> " + "::google::protobuf::internal::ExplicitlyConstructed<::std::string> " "$classname$::$default_variable_name$;\n"); } } @@ -383,18 +435,34 @@ GenerateMessageClearingCode(io::Printer* printer) const { // If we have field presence, then the Clear() method of the protocol buffer // will have checked that this field is set. If so, we can avoid redundant // checks against default_variable. - const bool must_be_present = HasFieldPresence(descriptor_->file()); - - if (must_be_present) { + const bool must_be_present = + HasFieldPresence(descriptor_->file()); + + if (inlined_ && must_be_present) { + // Calling mutable_$name$() gives us a string reference and sets the has bit + // for $name$ (in proto2). We may get here when the string field is inlined + // but the string's contents have not been changed by the user, so we cannot + // make an assertion about the contents of the string and could never make + // an assertion about the string instance. + // + // For non-inlined strings, we distinguish from non-default by comparing + // instances, rather than contents. printer->Print(variables_, "GOOGLE_DCHECK(!$name$_.IsDefault($default_variable$));\n"); } if (SupportsArenas(descriptor_)) { if (descriptor_->default_value_string().empty()) { - printer->Print(variables_, - "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n"); + if (must_be_present) { + printer->Print(variables_, + "$name$_.ClearNonDefaultToEmpty();\n"); + } else { + printer->Print(variables_, + "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n"); + } } else { + // Clear to a non-empty default is more involved, as we try to use the + // Arena if one is present and may need to reallocate the string. printer->Print(variables_, "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n"); } @@ -402,7 +470,7 @@ GenerateMessageClearingCode(io::Printer* printer) const { // When Arenas are disabled and field presence has been checked, we can // safely treat the ArenaStringPtr as a string*. if (descriptor_->default_value_string().empty()) { - printer->Print(variables_, "$name$_.UnsafeMutablePointer()->clear();\n"); + printer->Print(variables_, "$name$_.ClearNonDefaultToEmptyNoArena();\n"); } else { printer->Print( variables_, @@ -433,13 +501,29 @@ GenerateMergingCode(io::Printer* printer) const { void StringFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); + if (inlined_) { + printer->Print( + variables_, + "$name$_.Swap(&other->$name$_);\n"); + } else { + printer->Print( + variables_, + "$name$_.Swap(&other->$name$_, $default_variable$,\n" + " GetArenaNoVirtual());\n"); + } } void StringFieldGenerator:: GenerateConstructorCode(io::Printer* printer) const { + // TODO(ckennelly): Construct non-empty strings as part of the initializer + // list. + if (inlined_ && descriptor_->default_value_string().empty()) { + // Automatic initialization will construct the string. + return; + } + printer->Print(variables_, - "$name$_.UnsafeSetDefault($default_variable$);\n"); + "$name$_.UnsafeSetDefault($default_variable$);\n"); } void StringFieldGenerator:: @@ -472,8 +556,23 @@ GenerateCopyConstructorCode(io::Printer* printer) const { void StringFieldGenerator:: GenerateDestructorCode(io::Printer* printer) const { + if (inlined_) { + // The destructor is automatically invoked. + return; + } + + printer->Print(variables_, "$name$_.DestroyNoArena($default_variable$);\n"); +} + +bool StringFieldGenerator::GenerateArenaDestructorCode( + io::Printer* printer) const { + if (!inlined_) { + return false; + } + printer->Print(variables_, - "$name$_.DestroyNoArena($default_variable$);\n"); + "_this->$name$_.DestroyNoArena($default_variable$);\n"); + return true; } void StringFieldGenerator:: @@ -544,13 +643,17 @@ GenerateByteSize(io::Printer* printer) const { " this->$name$());\n"); } +uint32 StringFieldGenerator::CalculateFieldTag() const { + return inlined_ ? 1 : 0; +} + // =================================================================== -StringOneofFieldGenerator:: -StringOneofFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : StringFieldGenerator(descriptor, options), - dependent_field_(options.proto_h) { +StringOneofFieldGenerator::StringOneofFieldGenerator( + const FieldDescriptor* descriptor, const Options& options) + : StringFieldGenerator(descriptor, options) { + inlined_ = false; + SetCommonOneofFieldVariables(descriptor, &variables_); } diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h index 0c6e9ced..6cbf722f 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h @@ -63,11 +63,14 @@ class StringFieldGenerator : public FieldGenerator { void GenerateConstructorCode(io::Printer* printer) const; void GenerateCopyConstructorCode(io::Printer* printer) const; void GenerateDestructorCode(io::Printer* printer) const; + bool GenerateArenaDestructorCode(io::Printer* printer) const; void GenerateDefaultInstanceAllocator(io::Printer* printer) const; void GenerateMergeFromCodedStream(io::Printer* printer) const; void GenerateSerializeWithCachedSizes(io::Printer* printer) const; void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; void GenerateByteSize(io::Printer* printer) const; + uint32 CalculateFieldTag() const; + bool IsInlined() const { return inlined_; } bool MergeFromCodedStreamNeedsArena() const; @@ -75,6 +78,7 @@ class StringFieldGenerator : public FieldGenerator { const FieldDescriptor* descriptor_; std::map<string, string> variables_; const bool lite_; + bool inlined_; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); @@ -99,7 +103,6 @@ class StringOneofFieldGenerator : public StringFieldGenerator { void GenerateMergeFromCodedStream(io::Printer* printer) const; private: - const bool dependent_field_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOneofFieldGenerator); }; diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index 2ad7ea4e..22b759a9 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -46,40 +46,26 @@ #include <google/protobuf/compiler/cpp/cpp_unittest.h> -#include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif -#include <vector> - #include <google/protobuf/unittest.pb.h> -#include <google/protobuf/unittest_no_arena.pb.h> #include <google/protobuf/unittest_optimize_for.pb.h> #include <google/protobuf/unittest_embed_optimize_for.pb.h> -#if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER) -// We exclude this large proto from cmake build because it's too large for -// visual studio to compile (report internal errors). -#include <google/protobuf/unittest_enormous_descriptor.pb.h> -#endif -#include <google/protobuf/unittest_no_generic_services.pb.h> + #include <google/protobuf/test_util.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h> -#include <google/protobuf/compiler/importer.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/arena.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/dynamic_message.h> -#include <google/protobuf/stubs/callback.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/logging.h> -#include <google/protobuf/stubs/substitute.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> -#include <google/protobuf/stubs/stl_util.h> +#define MESSAGE_TEST_NAME MessageTest +#define GENERATED_DESCRIPTOR_TEST_NAME GeneratedDescriptorTest +#define GENERATED_MESSAGE_TEST_NAME GeneratedMessageTest +#define GENERATED_ENUM_TEST_NAME GeneratedEnumTest +#define GENERATED_SERVICE_TEST_NAME GeneratedServiceTest +#define HELPERS_TEST_NAME HelpersTest +#define DESCRIPTOR_INIT_TEST_NAME DescriptorInitializationTest + +#define UNITTEST_PROTO_PATH "google/protobuf/unittest.proto" +#define UNITTEST ::protobuf_unittest +#define UNITTEST_IMPORT ::protobuf_unittest_import + +// Must include after the above macros. +#include <google/protobuf/compiler/cpp/cpp_unittest.inc> namespace google { namespace protobuf { @@ -91,848 +77,14 @@ namespace cpp_unittest { namespace protobuf_unittest = ::protobuf_unittest; - -class MockErrorCollector : public MultiFileErrorCollector { - public: - MockErrorCollector() {} - ~MockErrorCollector() {} - - string text_; - - // implements ErrorCollector --------------------------------------- - void AddError(const string& filename, int line, int column, - const string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", - filename, line, column, message); - } -}; - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - -// Test that generated code has proper descriptors: -// Parse a descriptor directly (using google::protobuf::compiler::Importer) and -// compare it to the one that was produced by generated code. -TEST(GeneratedDescriptorTest, IdenticalDescriptors) { - const FileDescriptor* generated_descriptor = - unittest::TestAllTypes::descriptor()->file(); - - // Set up the Importer. - MockErrorCollector error_collector; - DiskSourceTree source_tree; - source_tree.MapPath("", TestSourceDir()); - Importer importer(&source_tree, &error_collector); - - // Import (parse) unittest.proto. - const FileDescriptor* parsed_descriptor = - importer.Import("google/protobuf/unittest.proto"); - EXPECT_EQ("", error_collector.text_); - ASSERT_TRUE(parsed_descriptor != NULL); - - // Test that descriptors are generated correctly by converting them to - // FileDescriptorProtos and comparing. - FileDescriptorProto generated_descriptor_proto, parsed_descriptor_proto; - generated_descriptor->CopyTo(&generated_descriptor_proto); - parsed_descriptor->CopyTo(&parsed_descriptor_proto); - - EXPECT_EQ(parsed_descriptor_proto.DebugString(), - generated_descriptor_proto.DebugString()); -} - -#if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER) -// Test that generated code has proper descriptors: -// Touch a descriptor generated from an enormous message to validate special -// handling for descriptors exceeding the C++ standard's recommended minimum -// limit for string literal size -TEST(GeneratedDescriptorTest, EnormousDescriptor) { - const Descriptor* generated_descriptor = - TestEnormousDescriptor::descriptor(); - - EXPECT_TRUE(generated_descriptor != NULL); -} -#endif - -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS - -// =================================================================== - -TEST(GeneratedMessageTest, Defaults) { - // Check that all default values are set correctly in the initial message. - unittest::TestAllTypes message; - - TestUtil::ExpectClear(message); - - // Messages should return pointers to default instances until first use. - // (This is not checked by ExpectClear() since it is not actually true after - // the fields have been set and then cleared.) - EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &message.optionalgroup()); - EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.optional_nested_message()); - EXPECT_EQ(&unittest::ForeignMessage::default_instance(), - &message.optional_foreign_message()); - EXPECT_EQ(&unittest_import::ImportMessage::default_instance(), - &message.optional_import_message()); -} - -#ifndef PROTOBUF_USE_DLLS -TEST(GeneratedMessageTest, Int32StringConversion) { - EXPECT_EQ("971", Int32ToString(971)); - EXPECT_EQ("(~0x7fffffff)", Int32ToString(kint32min)); - EXPECT_EQ("2147483647", Int32ToString(kint32max)); -} - -TEST(GeneratedMessageTest, Int64StringConversion) { - EXPECT_EQ("GOOGLE_LONGLONG(971)", Int64ToString(971)); - EXPECT_EQ("GOOGLE_LONGLONG(-2147483648)", Int64ToString(kint32min)); - EXPECT_EQ("GOOGLE_LONGLONG(~0x7fffffffffffffff)", Int64ToString(kint64min)); - EXPECT_EQ("GOOGLE_LONGLONG(9223372036854775807)", Int64ToString(kint64max)); -} -#endif // !PROTOBUF_USE_DLLS - -TEST(GeneratedMessageTest, FloatingPointDefaults) { - const unittest::TestExtremeDefaultValues& extreme_default = - unittest::TestExtremeDefaultValues::default_instance(); - - EXPECT_EQ(0.0f, extreme_default.zero_float()); - EXPECT_EQ(1.0f, extreme_default.one_float()); - EXPECT_EQ(1.5f, extreme_default.small_float()); - EXPECT_EQ(-1.0f, extreme_default.negative_one_float()); - EXPECT_EQ(-1.5f, extreme_default.negative_float()); - EXPECT_EQ(2.0e8f, extreme_default.large_float()); - EXPECT_EQ(-8e-28f, extreme_default.small_negative_float()); - EXPECT_EQ(std::numeric_limits<double>::infinity(), - extreme_default.inf_double()); - EXPECT_EQ(-std::numeric_limits<double>::infinity(), - extreme_default.neg_inf_double()); - EXPECT_TRUE(extreme_default.nan_double() != extreme_default.nan_double()); - EXPECT_EQ(std::numeric_limits<float>::infinity(), - extreme_default.inf_float()); - EXPECT_EQ(-std::numeric_limits<float>::infinity(), - extreme_default.neg_inf_float()); - EXPECT_TRUE(extreme_default.nan_float() != extreme_default.nan_float()); -} - -TEST(GeneratedMessageTest, Trigraph) { - const unittest::TestExtremeDefaultValues& extreme_default = - unittest::TestExtremeDefaultValues::default_instance(); - - EXPECT_EQ("? ? ?? ?? ??? ?\?/ ?\?-", extreme_default.cpp_trigraph()); -} - -TEST(GeneratedMessageTest, ExtremeSmallIntegerDefault) { - const unittest::TestExtremeDefaultValues& extreme_default = - unittest::TestExtremeDefaultValues::default_instance(); - EXPECT_EQ(~0x7fffffff, kint32min); - EXPECT_EQ(GOOGLE_LONGLONG(~0x7fffffffffffffff), kint64min); - EXPECT_EQ(kint32min, extreme_default.really_small_int32()); - EXPECT_EQ(kint64min, extreme_default.really_small_int64()); -} - -TEST(GeneratedMessageTest, Accessors) { - // Set every field to a unique value then go back and check all those - // values. - unittest::TestAllTypes message; - - TestUtil::SetAllFields(&message); - TestUtil::ExpectAllFieldsSet(message); - - TestUtil::ModifyRepeatedFields(&message); - TestUtil::ExpectRepeatedFieldsModified(message); -} - -TEST(GeneratedMessageTest, MutableStringDefault) { - // mutable_foo() for a string should return a string initialized to its - // default value. - unittest::TestAllTypes message; - - EXPECT_EQ("hello", *message.mutable_default_string()); - - // Note that the first time we call mutable_foo(), we get a newly-allocated - // string, but if we clear it and call it again, we get the same object again. - // We should verify that it has its default value in both cases. - message.set_default_string("blah"); - message.Clear(); - - EXPECT_EQ("hello", *message.mutable_default_string()); -} - -TEST(GeneratedMessageTest, StringDefaults) { - unittest::TestExtremeDefaultValues message; - // Check if '\000' can be used in default string value. - EXPECT_EQ(string("hel\000lo", 6), message.string_with_zero()); - EXPECT_EQ(string("wor\000ld", 6), message.bytes_with_zero()); -} - -TEST(GeneratedMessageTest, ReleaseString) { - // Check that release_foo() starts out NULL, and gives us a value - // that we can delete after it's been set. - unittest::TestAllTypes message; - - EXPECT_EQ(NULL, message.release_default_string()); - EXPECT_FALSE(message.has_default_string()); - EXPECT_EQ("hello", message.default_string()); - - message.set_default_string("blah"); - EXPECT_TRUE(message.has_default_string()); - google::protobuf::scoped_ptr<string> str(message.release_default_string()); - EXPECT_FALSE(message.has_default_string()); - ASSERT_TRUE(str != NULL); - EXPECT_EQ("blah", *str); - - EXPECT_EQ(NULL, message.release_default_string()); - EXPECT_FALSE(message.has_default_string()); - EXPECT_EQ("hello", message.default_string()); -} - -TEST(GeneratedMessageTest, ReleaseMessage) { - // Check that release_foo() starts out NULL, and gives us a value - // that we can delete after it's been set. - unittest::TestAllTypes message; - - EXPECT_EQ(NULL, message.release_optional_nested_message()); - EXPECT_FALSE(message.has_optional_nested_message()); - - message.mutable_optional_nested_message()->set_bb(1); - google::protobuf::scoped_ptr<unittest::TestAllTypes::NestedMessage> nest( - message.release_optional_nested_message()); - EXPECT_FALSE(message.has_optional_nested_message()); - ASSERT_TRUE(nest != NULL); - EXPECT_EQ(1, nest->bb()); - - EXPECT_EQ(NULL, message.release_optional_nested_message()); - EXPECT_FALSE(message.has_optional_nested_message()); -} - -TEST(GeneratedMessageTest, SetAllocatedString) { - // Check that set_allocated_foo() works for strings. - unittest::TestAllTypes message; - - EXPECT_FALSE(message.has_optional_string()); - const string kHello("hello"); - message.set_optional_string(kHello); - EXPECT_TRUE(message.has_optional_string()); - - message.set_allocated_optional_string(NULL); - EXPECT_FALSE(message.has_optional_string()); - EXPECT_EQ("", message.optional_string()); - - message.set_allocated_optional_string(new string(kHello)); - EXPECT_TRUE(message.has_optional_string()); - EXPECT_EQ(kHello, message.optional_string()); -} - -TEST(GeneratedMessageTest, SetAllocatedMessage) { - // Check that set_allocated_foo() can be called in all cases. - unittest::TestAllTypes message; - - EXPECT_FALSE(message.has_optional_nested_message()); - - message.mutable_optional_nested_message()->set_bb(1); - EXPECT_TRUE(message.has_optional_nested_message()); - - message.set_allocated_optional_nested_message(NULL); - EXPECT_FALSE(message.has_optional_nested_message()); - EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.optional_nested_message()); - - message.mutable_optional_nested_message()->set_bb(1); - unittest::TestAllTypes::NestedMessage* nest = - message.release_optional_nested_message(); - ASSERT_TRUE(nest != NULL); - EXPECT_FALSE(message.has_optional_nested_message()); - - message.set_allocated_optional_nested_message(nest); - EXPECT_TRUE(message.has_optional_nested_message()); - EXPECT_EQ(1, message.optional_nested_message().bb()); -} - -TEST(GeneratedMessageTest, Clear) { - // Set every field to a unique value, clear the message, then check that - // it is cleared. - unittest::TestAllTypes message; - - TestUtil::SetAllFields(&message); - message.Clear(); - TestUtil::ExpectClear(message); - - // Unlike with the defaults test, we do NOT expect that requesting embedded - // messages will return a pointer to the default instance. Instead, they - // should return the objects that were created when mutable_blah() was - // called. - EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &message.optionalgroup()); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.optional_nested_message()); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &message.optional_foreign_message()); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &message.optional_import_message()); -} - -TEST(GeneratedMessageTest, EmbeddedNullsInBytesCharStar) { - unittest::TestAllTypes message; - - const char* value = "\0lalala\0\0"; - message.set_optional_bytes(value, 9); - ASSERT_EQ(9, message.optional_bytes().size()); - EXPECT_EQ(0, memcmp(value, message.optional_bytes().data(), 9)); - - message.add_repeated_bytes(value, 9); - ASSERT_EQ(9, message.repeated_bytes(0).size()); - EXPECT_EQ(0, memcmp(value, message.repeated_bytes(0).data(), 9)); -} - -TEST(GeneratedMessageTest, ClearOneField) { - // Set every field to a unique value, then clear one value and insure that - // only that one value is cleared. - unittest::TestAllTypes message; - - TestUtil::SetAllFields(&message); - int64 original_value = message.optional_int64(); - - // Clear the field and make sure it shows up as cleared. - message.clear_optional_int64(); - EXPECT_FALSE(message.has_optional_int64()); - EXPECT_EQ(0, message.optional_int64()); - - // Other adjacent fields should not be cleared. - EXPECT_TRUE(message.has_optional_int32()); - EXPECT_TRUE(message.has_optional_uint32()); - - // Make sure if we set it again, then all fields are set. - message.set_optional_int64(original_value); - TestUtil::ExpectAllFieldsSet(message); -} - -TEST(GeneratedMessageTest, StringCharStarLength) { - // Verify that we can use a char*,length to set one of the string fields. - unittest::TestAllTypes message; - message.set_optional_string("abcdef", 3); - EXPECT_EQ("abc", message.optional_string()); - - // Verify that we can use a char*,length to add to a repeated string field. - message.add_repeated_string("abcdef", 3); - EXPECT_EQ(1, message.repeated_string_size()); - EXPECT_EQ("abc", message.repeated_string(0)); - - // Verify that we can use a char*,length to set a repeated string field. - message.set_repeated_string(0, "wxyz", 2); - EXPECT_EQ("wx", message.repeated_string(0)); -} - -#if LANG_CXX11 -TEST(GeneratedMessageTest, StringMove) { - // Verify that we trigger the move behavior on a scalar setter. - protobuf_unittest_no_arena::TestAllTypes message; - { - string tmp(32, 'a'); - - const char* old_data = tmp.data(); - message.set_optional_string(std::move(tmp)); - const char* new_data = message.optional_string().data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(string(32, 'a'), message.optional_string()); - - string tmp2(32, 'b'); - old_data = tmp2.data(); - message.set_optional_string(std::move(tmp2)); - new_data = message.optional_string().data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(string(32, 'b'), message.optional_string()); - } - - // Verify that we trigger the move behavior on a oneof setter. - { - string tmp(32, 'a'); - - const char* old_data = tmp.data(); - message.set_oneof_string(std::move(tmp)); - const char* new_data = message.oneof_string().data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(string(32, 'a'), message.oneof_string()); - - string tmp2(32, 'b'); - old_data = tmp2.data(); - message.set_oneof_string(std::move(tmp2)); - new_data = message.oneof_string().data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(string(32, 'b'), message.oneof_string()); - } - - // Verify that we trigger the move behavior on a repeated setter. - { - string tmp(32, 'a'); - - const char* old_data = tmp.data(); - message.add_repeated_string(std::move(tmp)); - const char* new_data = message.repeated_string(0).data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(string(32, 'a'), message.repeated_string(0)); - - string tmp2(32, 'b'); - old_data = tmp2.data(); - message.set_repeated_string(0, std::move(tmp2)); - new_data = message.repeated_string(0).data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(string(32, 'b'), message.repeated_string(0)); - } -} -#endif - - -TEST(GeneratedMessageTest, CopyFrom) { - unittest::TestAllTypes message1, message2; - - TestUtil::SetAllFields(&message1); - message2.CopyFrom(message1); - TestUtil::ExpectAllFieldsSet(message2); - - // Copying from self should be a no-op. - message2.CopyFrom(message2); - TestUtil::ExpectAllFieldsSet(message2); -} - - -TEST(GeneratedMessageTest, SwapWithEmpty) { - unittest::TestAllTypes message1, message2; - TestUtil::SetAllFields(&message1); - - TestUtil::ExpectAllFieldsSet(message1); - TestUtil::ExpectClear(message2); - message1.Swap(&message2); - TestUtil::ExpectAllFieldsSet(message2); - TestUtil::ExpectClear(message1); -} - -TEST(GeneratedMessageTest, SwapWithSelf) { - unittest::TestAllTypes message; - TestUtil::SetAllFields(&message); - TestUtil::ExpectAllFieldsSet(message); - message.Swap(&message); - TestUtil::ExpectAllFieldsSet(message); -} - -TEST(GeneratedMessageTest, SwapWithOther) { - unittest::TestAllTypes message1, message2; - - message1.set_optional_int32(123); - message1.set_optional_string("abc"); - message1.mutable_optional_nested_message()->set_bb(1); - message1.set_optional_nested_enum(unittest::TestAllTypes::FOO); - message1.add_repeated_int32(1); - message1.add_repeated_int32(2); - message1.add_repeated_string("a"); - message1.add_repeated_string("b"); - message1.add_repeated_nested_message()->set_bb(7); - message1.add_repeated_nested_message()->set_bb(8); - message1.add_repeated_nested_enum(unittest::TestAllTypes::FOO); - message1.add_repeated_nested_enum(unittest::TestAllTypes::BAR); - - message2.set_optional_int32(456); - message2.set_optional_string("def"); - message2.mutable_optional_nested_message()->set_bb(2); - message2.set_optional_nested_enum(unittest::TestAllTypes::BAR); - message2.add_repeated_int32(3); - message2.add_repeated_string("c"); - message2.add_repeated_nested_message()->set_bb(9); - message2.add_repeated_nested_enum(unittest::TestAllTypes::BAZ); - - message1.Swap(&message2); - - EXPECT_EQ(456, message1.optional_int32()); - EXPECT_EQ("def", message1.optional_string()); - EXPECT_EQ(2, message1.optional_nested_message().bb()); - EXPECT_EQ(unittest::TestAllTypes::BAR, message1.optional_nested_enum()); - ASSERT_EQ(1, message1.repeated_int32_size()); - EXPECT_EQ(3, message1.repeated_int32(0)); - ASSERT_EQ(1, message1.repeated_string_size()); - EXPECT_EQ("c", message1.repeated_string(0)); - ASSERT_EQ(1, message1.repeated_nested_message_size()); - EXPECT_EQ(9, message1.repeated_nested_message(0).bb()); - ASSERT_EQ(1, message1.repeated_nested_enum_size()); - EXPECT_EQ(unittest::TestAllTypes::BAZ, message1.repeated_nested_enum(0)); - - EXPECT_EQ(123, message2.optional_int32()); - EXPECT_EQ("abc", message2.optional_string()); - EXPECT_EQ(1, message2.optional_nested_message().bb()); - EXPECT_EQ(unittest::TestAllTypes::FOO, message2.optional_nested_enum()); - ASSERT_EQ(2, message2.repeated_int32_size()); - EXPECT_EQ(1, message2.repeated_int32(0)); - EXPECT_EQ(2, message2.repeated_int32(1)); - ASSERT_EQ(2, message2.repeated_string_size()); - EXPECT_EQ("a", message2.repeated_string(0)); - EXPECT_EQ("b", message2.repeated_string(1)); - ASSERT_EQ(2, message2.repeated_nested_message_size()); - EXPECT_EQ(7, message2.repeated_nested_message(0).bb()); - EXPECT_EQ(8, message2.repeated_nested_message(1).bb()); - ASSERT_EQ(2, message2.repeated_nested_enum_size()); - EXPECT_EQ(unittest::TestAllTypes::FOO, message2.repeated_nested_enum(0)); - EXPECT_EQ(unittest::TestAllTypes::BAR, message2.repeated_nested_enum(1)); -} - -TEST(GeneratedMessageTest, ADLSwap) { - unittest::TestAllTypes message1, message2; - TestUtil::SetAllFields(&message1); - - // Note the address of one of the repeated fields, to verify it was swapped - // rather than copied. - const int32* addr = &message1.repeated_int32().Get(0); - - using std::swap; - swap(message1, message2); - - TestUtil::ExpectAllFieldsSet(message2); - TestUtil::ExpectClear(message1); - - EXPECT_EQ(addr, &message2.repeated_int32().Get(0)); -} - -TEST(GeneratedMessageTest, CopyConstructor) { - // All set. - { - unittest::TestAllTypes message1; - TestUtil::SetAllFields(&message1); - - unittest::TestAllTypes message2(message1); - TestUtil::ExpectAllFieldsSet(message2); - } - - // None set. - { - unittest::TestAllTypes message1; - unittest::TestAllTypes message2(message1); - - EXPECT_FALSE(message1.has_optional_string()); - EXPECT_FALSE(message2.has_optional_string()); - EXPECT_EQ(&message1.optional_string(), - &message2.optional_string()); - - EXPECT_FALSE(message1.has_optional_bytes()); - EXPECT_FALSE(message2.has_optional_bytes()); - EXPECT_EQ(&message1.optional_bytes(), - &message2.optional_bytes()); - - EXPECT_FALSE(message1.has_optional_nested_message()); - EXPECT_FALSE(message2.has_optional_nested_message()); - EXPECT_EQ(&message1.optional_nested_message(), - &message2.optional_nested_message()); - - EXPECT_FALSE(message1.has_optional_foreign_message()); - EXPECT_FALSE(message2.has_optional_foreign_message()); - EXPECT_EQ(&message1.optional_foreign_message(), - &message2.optional_foreign_message()); - - EXPECT_FALSE(message1.has_optional_import_message()); - EXPECT_FALSE(message2.has_optional_import_message()); - EXPECT_EQ(&message1.optional_import_message(), - &message2.optional_import_message()); - - EXPECT_FALSE(message1.has_optional_public_import_message()); - EXPECT_FALSE(message2.has_optional_public_import_message()); - EXPECT_EQ(&message1.optional_public_import_message(), - &message2.optional_public_import_message()); - - EXPECT_FALSE(message1.has_optional_lazy_message()); - EXPECT_FALSE(message2.has_optional_lazy_message()); - EXPECT_EQ(&message1.optional_lazy_message(), - &message2.optional_lazy_message()); - } -} - -TEST(GeneratedMessageTest, CopyConstructorWithArenas) { - Arena arena; - unittest::TestAllTypes* message1 = - Arena::CreateMessage<unittest::TestAllTypes>(&arena); - TestUtil::SetAllFields(message1); - - unittest::TestAllTypes message2_stack(*message1); - TestUtil::ExpectAllFieldsSet(message2_stack); - - google::protobuf::scoped_ptr<unittest::TestAllTypes> message2_heap( - new unittest::TestAllTypes(*message1)); - TestUtil::ExpectAllFieldsSet(*message2_heap); - - arena.Reset(); - - // Verify that the copies are still intact. - TestUtil::ExpectAllFieldsSet(message2_stack); - TestUtil::ExpectAllFieldsSet(*message2_heap); -} - -TEST(GeneratedMessageTest, CopyAssignmentOperator) { - unittest::TestAllTypes message1; - TestUtil::SetAllFields(&message1); - - unittest::TestAllTypes message2; - message2 = message1; - TestUtil::ExpectAllFieldsSet(message2); - - // Make sure that self-assignment does something sane. - message2.operator=(message2); - TestUtil::ExpectAllFieldsSet(message2); -} - -#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \ - !defined(GOOGLE_PROTOBUF_NO_RTTI) -TEST(GeneratedMessageTest, UpcastCopyFrom) { - // Test the CopyFrom method that takes in the generic const Message& - // parameter. - unittest::TestAllTypes message1, message2; - - TestUtil::SetAllFields(&message1); - - const Message* source = implicit_cast<const Message*>(&message1); - message2.CopyFrom(*source); - - TestUtil::ExpectAllFieldsSet(message2); -} -#endif - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - -TEST(GeneratedMessageTest, DynamicMessageCopyFrom) { - // Test copying from a DynamicMessage, which must fall back to using - // reflection. - unittest::TestAllTypes message2; - - // Construct a new version of the dynamic message via the factory. - DynamicMessageFactory factory; - google::protobuf::scoped_ptr<Message> message1; - message1.reset(factory.GetPrototype( - unittest::TestAllTypes::descriptor())->New()); - - TestUtil::ReflectionTester reflection_tester( - unittest::TestAllTypes::descriptor()); - reflection_tester.SetAllFieldsViaReflection(message1.get()); - - message2.CopyFrom(*message1); - - TestUtil::ExpectAllFieldsSet(message2); -} - -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS - -TEST(GeneratedMessageTest, NonEmptyMergeFrom) { - // Test merging with a non-empty message. Code is a modified form - // of that found in google/protobuf/reflection_ops_unittest.cc. - unittest::TestAllTypes message1, message2; - - TestUtil::SetAllFields(&message1); - - // This field will test merging into an empty spot. - message2.set_optional_int32(message1.optional_int32()); - message1.clear_optional_int32(); - - // This tests overwriting. - message2.set_optional_string(message1.optional_string()); - message1.set_optional_string("something else"); - - // This tests concatenating. - message2.add_repeated_int32(message1.repeated_int32(1)); - int32 i = message1.repeated_int32(0); - message1.clear_repeated_int32(); - message1.add_repeated_int32(i); - - message1.MergeFrom(message2); - - TestUtil::ExpectAllFieldsSet(message1); -} - - -// Test the generated SerializeWithCachedSizesToArray(), -TEST(GeneratedMessageTest, SerializationToArray) { - unittest::TestAllTypes message1, message2; - string data; - TestUtil::SetAllFields(&message1); - int size = message1.ByteSize(); - data.resize(size); - uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); - uint8* end = message1.SerializeWithCachedSizesToArray(start); - EXPECT_EQ(size, end - start); - EXPECT_TRUE(message2.ParseFromString(data)); - TestUtil::ExpectAllFieldsSet(message2); - -} - -TEST(GeneratedMessageTest, PackedFieldsSerializationToArray) { - unittest::TestPackedTypes packed_message1, packed_message2; - string packed_data; - TestUtil::SetPackedFields(&packed_message1); - int packed_size = packed_message1.ByteSize(); - packed_data.resize(packed_size); - uint8* start = reinterpret_cast<uint8*>(string_as_array(&packed_data)); - uint8* end = packed_message1.SerializeWithCachedSizesToArray(start); - EXPECT_EQ(packed_size, end - start); - EXPECT_TRUE(packed_message2.ParseFromString(packed_data)); - TestUtil::ExpectPackedFieldsSet(packed_message2); -} - -// Test the generated SerializeWithCachedSizes() by forcing the buffer to write -// one byte at a time. -TEST(GeneratedMessageTest, SerializationToStream) { - unittest::TestAllTypes message1, message2; - TestUtil::SetAllFields(&message1); - int size = message1.ByteSize(); - string data; - data.resize(size); - { - // Allow the output stream to buffer only one byte at a time. - io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - message1.SerializeWithCachedSizes(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - } - EXPECT_TRUE(message2.ParseFromString(data)); - TestUtil::ExpectAllFieldsSet(message2); - -} - -TEST(GeneratedMessageTest, PackedFieldsSerializationToStream) { - unittest::TestPackedTypes message1, message2; - TestUtil::SetPackedFields(&message1); - int size = message1.ByteSize(); - string data; - data.resize(size); - { - // Allow the output stream to buffer only one byte at a time. - io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - message1.SerializeWithCachedSizes(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - } - EXPECT_TRUE(message2.ParseFromString(data)); - TestUtil::ExpectPackedFieldsSet(message2); -} - - -TEST(GeneratedMessageTest, Required) { - // Test that IsInitialized() returns false if required fields are missing. - unittest::TestRequired message; - - EXPECT_FALSE(message.IsInitialized()); - message.set_a(1); - EXPECT_FALSE(message.IsInitialized()); - message.set_b(2); - EXPECT_FALSE(message.IsInitialized()); - message.set_c(3); - EXPECT_TRUE(message.IsInitialized()); -} - -TEST(GeneratedMessageTest, RequiredForeign) { - // Test that IsInitialized() returns false if required fields in nested - // messages are missing. - unittest::TestRequiredForeign message; - - EXPECT_TRUE(message.IsInitialized()); - - message.mutable_optional_message(); - EXPECT_FALSE(message.IsInitialized()); - - message.mutable_optional_message()->set_a(1); - message.mutable_optional_message()->set_b(2); - message.mutable_optional_message()->set_c(3); - EXPECT_TRUE(message.IsInitialized()); - - message.add_repeated_message(); - EXPECT_FALSE(message.IsInitialized()); - - message.mutable_repeated_message(0)->set_a(1); - message.mutable_repeated_message(0)->set_b(2); - message.mutable_repeated_message(0)->set_c(3); - EXPECT_TRUE(message.IsInitialized()); -} - -TEST(GeneratedMessageTest, ForeignNested) { - // Test that TestAllTypes::NestedMessage can be embedded directly into - // another message. - unittest::TestForeignNested message; - - // If this compiles and runs without crashing, it must work. We have - // nothing more to test. - unittest::TestAllTypes::NestedMessage* nested = - message.mutable_foreign_nested(); - nested->set_bb(1); -} - -TEST(GeneratedMessageTest, ReallyLargeTagNumber) { - // Test that really large tag numbers don't break anything. - unittest::TestReallyLargeTagNumber message1, message2; - string data; - - // For the most part, if this compiles and runs then we're probably good. - // (The most likely cause for failure would be if something were attempting - // to allocate a lookup table of some sort using tag numbers as the index.) - // We'll try serializing just for fun. - message1.set_a(1234); - message1.set_bb(5678); - message1.SerializeToString(&data); - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(1234, message2.a()); - EXPECT_EQ(5678, message2.bb()); -} - -TEST(GeneratedMessageTest, MutualRecursion) { - // Test that mutually-recursive message types work. - unittest::TestMutualRecursionA message; - unittest::TestMutualRecursionA* nested = message.mutable_bb()->mutable_a(); - unittest::TestMutualRecursionA* nested2 = nested->mutable_bb()->mutable_a(); - - // Again, if the above compiles and runs, that's all we really have to - // test, but just for run we'll check that the system didn't somehow come - // up with a pointer loop... - EXPECT_NE(&message, nested); - EXPECT_NE(&message, nested2); - EXPECT_NE(nested, nested2); -} - -TEST(GeneratedMessageTest, CamelCaseFieldNames) { - // This test is mainly checking that the following compiles, which verifies - // that the field names were coerced to lower-case. - // - // Protocol buffers standard style is to use lowercase-with-underscores for - // field names. Some old proto1 .protos unfortunately used camel-case field - // names. In proto1, these names were forced to lower-case. So, we do the - // same thing in proto2. - - unittest::TestCamelCaseFieldNames message; - - message.set_primitivefield(2); - message.set_stringfield("foo"); - message.set_enumfield(unittest::FOREIGN_FOO); - message.mutable_messagefield()->set_c(6); - - message.add_repeatedprimitivefield(8); - message.add_repeatedstringfield("qux"); - message.add_repeatedenumfield(unittest::FOREIGN_BAR); - message.add_repeatedmessagefield()->set_c(15); - - EXPECT_EQ(2, message.primitivefield()); - EXPECT_EQ("foo", message.stringfield()); - EXPECT_EQ(unittest::FOREIGN_FOO, message.enumfield()); - EXPECT_EQ(6, message.messagefield().c()); - - EXPECT_EQ(8, message.repeatedprimitivefield(0)); - EXPECT_EQ("qux", message.repeatedstringfield(0)); - EXPECT_EQ(unittest::FOREIGN_BAR, message.repeatedenumfield(0)); - EXPECT_EQ(15, message.repeatedmessagefield(0).c()); -} - -TEST(GeneratedMessageTest, TestConflictingSymbolNames) { +TEST(GENERATED_MESSAGE_TEST_NAME, TestConflictingSymbolNames) { // test_bad_identifiers.proto successfully compiled, then it works. The // following is just a token usage to insure that the code is, in fact, // being compiled and linked. protobuf_unittest::TestConflictingSymbolNames message; message.set_uint32(1); - EXPECT_EQ(3, message.ByteSize()); + EXPECT_EQ(3, message.ByteSizeLong()); message.set_friend_(5); EXPECT_EQ(5, message.friend_()); @@ -948,7 +100,7 @@ TEST(GeneratedMessageTest, TestConflictingSymbolNames) { message.GetExtension(ExtensionMessage::repeated_int32_ext, 0)); } -TEST(GeneratedMessageTest, TestConflictingEnumNames) { +TEST(GENERATED_MESSAGE_TEST_NAME, TestConflictingEnumNames) { protobuf_unittest::TestConflictingEnumNames message; message.set_conflicting_enum(protobuf_unittest::TestConflictingEnumNames_NestedConflictingEnum_and_); EXPECT_EQ(1, message.conflicting_enum()); @@ -963,1366 +115,7 @@ TEST(GeneratedMessageTest, TestConflictingEnumNames) { EXPECT_EQ(3, conflicting_enum); } -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - -TEST(GeneratedMessageTest, TestOptimizedForSize) { - // We rely on the tests in reflection_ops_unittest and wire_format_unittest - // to really test that reflection-based methods work. Here we are mostly - // just making sure that TestOptimizedForSize actually builds and seems to - // function. - - protobuf_unittest::TestOptimizedForSize message, message2; - message.set_i(1); - message.mutable_msg()->set_c(2); - message2.CopyFrom(message); - EXPECT_EQ(1, message2.i()); - EXPECT_EQ(2, message2.msg().c()); -} - -TEST(GeneratedMessageTest, TestEmbedOptimizedForSize) { - // Verifies that something optimized for speed can contain something optimized - // for size. - - protobuf_unittest::TestEmbedOptimizedForSize message, message2; - message.mutable_optional_message()->set_i(1); - message.add_repeated_message()->mutable_msg()->set_c(2); - string data; - message.SerializeToString(&data); - ASSERT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(1, message2.optional_message().i()); - EXPECT_EQ(2, message2.repeated_message(0).msg().c()); -} - -TEST(GeneratedMessageTest, TestSpaceUsed) { - unittest::TestAllTypes message1; - // sizeof provides a lower bound on SpaceUsedLong(). - EXPECT_LE(sizeof(unittest::TestAllTypes), message1.SpaceUsedLong()); - const size_t empty_message_size = message1.SpaceUsedLong(); - - // Setting primitive types shouldn't affect the space used. - message1.set_optional_int32(123); - message1.set_optional_int64(12345); - message1.set_optional_uint32(123); - message1.set_optional_uint64(12345); - EXPECT_EQ(empty_message_size, message1.SpaceUsedLong()); - - // On some STL implementations, setting the string to a small value should - // only increase SpaceUsedLong() by the size of a string object, though this - // is not true everywhere. - message1.set_optional_string("abc"); - EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsedLong()); - - // Setting a string to a value larger than the string object itself should - // increase SpaceUsedLong(), because it cannot store the value internally. - message1.set_optional_string(string(sizeof(string) + 1, 'x')); - int min_expected_increase = message1.optional_string().capacity() + - sizeof(string); - EXPECT_LE(empty_message_size + min_expected_increase, - message1.SpaceUsedLong()); - - size_t previous_size = message1.SpaceUsedLong(); - // Adding an optional message should increase the size by the size of the - // nested message type. NestedMessage is simple enough (1 int field) that it - // is equal to sizeof(NestedMessage) - message1.mutable_optional_nested_message(); - ASSERT_EQ(sizeof(unittest::TestAllTypes::NestedMessage), - message1.optional_nested_message().SpaceUsedLong()); - EXPECT_EQ(previous_size + - sizeof(unittest::TestAllTypes::NestedMessage), - message1.SpaceUsedLong()); -} - -TEST(GeneratedMessageTest, TestOneofSpaceUsed) { - unittest::TestOneof2 message1; - EXPECT_LE(sizeof(unittest::TestOneof2), message1.SpaceUsedLong()); - - const size_t empty_message_size = message1.SpaceUsedLong(); - // Setting primitive types shouldn't affect the space used. - message1.set_foo_int(123); - message1.set_bar_int(12345); - EXPECT_EQ(empty_message_size, message1.SpaceUsedLong()); - - // Setting a string in oneof to a small value should only increase - // SpaceUsedLong() by the size of a string object. - message1.set_foo_string("abc"); - EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsedLong()); - - // Setting a string in oneof to a value larger than the string object itself - // should increase SpaceUsedLong(), because it cannot store the value - // internally. - message1.set_foo_string(string(sizeof(string) + 1, 'x')); - int min_expected_increase = message1.foo_string().capacity() + - sizeof(string); - EXPECT_LE(empty_message_size + min_expected_increase, - message1.SpaceUsedLong()); - - // Setting a message in oneof should delete the other fields and increase the - // size by the size of the nested message type. NestedMessage is simple enough - // that it is equal to sizeof(NestedMessage) - message1.mutable_foo_message(); - ASSERT_EQ(sizeof(unittest::TestOneof2::NestedMessage), - message1.foo_message().SpaceUsedLong()); - EXPECT_EQ(empty_message_size + - sizeof(unittest::TestOneof2::NestedMessage), - message1.SpaceUsedLong()); -} - -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS - - -TEST(GeneratedMessageTest, FieldConstantValues) { - unittest::TestRequired message; - EXPECT_EQ(unittest::TestAllTypes_NestedMessage::kBbFieldNumber, 1); - EXPECT_EQ(unittest::TestAllTypes::kOptionalInt32FieldNumber, 1); - EXPECT_EQ(unittest::TestAllTypes::kOptionalgroupFieldNumber, 16); - EXPECT_EQ(unittest::TestAllTypes::kOptionalNestedMessageFieldNumber, 18); - EXPECT_EQ(unittest::TestAllTypes::kOptionalNestedEnumFieldNumber, 21); - EXPECT_EQ(unittest::TestAllTypes::kRepeatedInt32FieldNumber, 31); - EXPECT_EQ(unittest::TestAllTypes::kRepeatedgroupFieldNumber, 46); - EXPECT_EQ(unittest::TestAllTypes::kRepeatedNestedMessageFieldNumber, 48); - EXPECT_EQ(unittest::TestAllTypes::kRepeatedNestedEnumFieldNumber, 51); -} - -TEST(GeneratedMessageTest, ExtensionConstantValues) { - EXPECT_EQ(unittest::TestRequired::kSingleFieldNumber, 1000); - EXPECT_EQ(unittest::TestRequired::kMultiFieldNumber, 1001); - EXPECT_EQ(unittest::kOptionalInt32ExtensionFieldNumber, 1); - EXPECT_EQ(unittest::kOptionalgroupExtensionFieldNumber, 16); - EXPECT_EQ(unittest::kOptionalNestedMessageExtensionFieldNumber, 18); - EXPECT_EQ(unittest::kOptionalNestedEnumExtensionFieldNumber, 21); - EXPECT_EQ(unittest::kRepeatedInt32ExtensionFieldNumber, 31); - EXPECT_EQ(unittest::kRepeatedgroupExtensionFieldNumber, 46); - EXPECT_EQ(unittest::kRepeatedNestedMessageExtensionFieldNumber, 48); - EXPECT_EQ(unittest::kRepeatedNestedEnumExtensionFieldNumber, 51); -} - -TEST(GeneratedMessageTest, ParseFromTruncated) { - const string long_string = string(128, 'q'); - FileDescriptorProto p; - p.add_extension()->set_name(long_string); - const string msg = p.SerializeAsString(); - int successful_count = 0; - for (int i = 0; i <= msg.size(); i++) { - if (p.ParseFromArray(msg.c_str(), i)) { - ++successful_count; - } - } - // We don't really care about how often we succeeded. - // As long as we didn't crash, we're happy. - EXPECT_GE(successful_count, 1); -} - -// =================================================================== - -TEST(GeneratedEnumTest, EnumValuesAsSwitchCases) { - // Test that our nested enum values can be used as switch cases. This test - // doesn't actually do anything, the proof that it works is that it - // compiles. - int i =0; - unittest::TestAllTypes::NestedEnum a = unittest::TestAllTypes::BAR; - switch (a) { - case unittest::TestAllTypes::FOO: - i = 1; - break; - case unittest::TestAllTypes::BAR: - i = 2; - break; - case unittest::TestAllTypes::BAZ: - i = 3; - break; - case unittest::TestAllTypes::NEG: - i = -1; - break; - // no default case: We want to make sure the compiler recognizes that - // all cases are covered. (GCC warns if you do not cover all cases of - // an enum in a switch.) - } - - // Token check just for fun. - EXPECT_EQ(2, i); -} - -TEST(GeneratedEnumTest, IsValidValue) { - // Test enum IsValidValue. - EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(1)); - EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(2)); - EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(3)); - - EXPECT_FALSE(unittest::TestAllTypes::NestedEnum_IsValid(0)); - EXPECT_FALSE(unittest::TestAllTypes::NestedEnum_IsValid(4)); - - // Make sure it also works when there are dups. - EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(1)); - EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(2)); - EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(3)); - - EXPECT_FALSE(unittest::TestEnumWithDupValue_IsValid(0)); - EXPECT_FALSE(unittest::TestEnumWithDupValue_IsValid(4)); -} - -TEST(GeneratedEnumTest, MinAndMax) { - EXPECT_EQ(unittest::TestAllTypes::NEG, - unittest::TestAllTypes::NestedEnum_MIN); - EXPECT_EQ(unittest::TestAllTypes::BAZ, - unittest::TestAllTypes::NestedEnum_MAX); - EXPECT_EQ(4, unittest::TestAllTypes::NestedEnum_ARRAYSIZE); - - EXPECT_EQ(unittest::FOREIGN_FOO, unittest::ForeignEnum_MIN); - EXPECT_EQ(unittest::FOREIGN_BAZ, unittest::ForeignEnum_MAX); - EXPECT_EQ(7, unittest::ForeignEnum_ARRAYSIZE); - - EXPECT_EQ(1, unittest::TestEnumWithDupValue_MIN); - EXPECT_EQ(3, unittest::TestEnumWithDupValue_MAX); - EXPECT_EQ(4, unittest::TestEnumWithDupValue_ARRAYSIZE); - - EXPECT_EQ(unittest::SPARSE_E, unittest::TestSparseEnum_MIN); - EXPECT_EQ(unittest::SPARSE_C, unittest::TestSparseEnum_MAX); - EXPECT_EQ(12589235, unittest::TestSparseEnum_ARRAYSIZE); - - // Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE. - void* null_pointer = 0; // NULL may be integer-type, not pointer-type. - EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MIN); - EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MAX); - EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_ARRAYSIZE); - - EXPECT_NE(null_pointer, &unittest::ForeignEnum_MIN); - EXPECT_NE(null_pointer, &unittest::ForeignEnum_MAX); - EXPECT_NE(null_pointer, &unittest::ForeignEnum_ARRAYSIZE); - - // Make sure we can use _MIN and _MAX as switch cases. - switch (unittest::SPARSE_A) { - case unittest::TestSparseEnum_MIN: - case unittest::TestSparseEnum_MAX: - break; - default: - break; - } -} - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - -TEST(GeneratedEnumTest, Name) { - // "Names" in the presence of dup values are a bit arbitrary. - EXPECT_EQ("FOO1", unittest::TestEnumWithDupValue_Name(unittest::FOO1)); - EXPECT_EQ("FOO1", unittest::TestEnumWithDupValue_Name(unittest::FOO2)); - - EXPECT_EQ("SPARSE_A", unittest::TestSparseEnum_Name(unittest::SPARSE_A)); - EXPECT_EQ("SPARSE_B", unittest::TestSparseEnum_Name(unittest::SPARSE_B)); - EXPECT_EQ("SPARSE_C", unittest::TestSparseEnum_Name(unittest::SPARSE_C)); - EXPECT_EQ("SPARSE_D", unittest::TestSparseEnum_Name(unittest::SPARSE_D)); - EXPECT_EQ("SPARSE_E", unittest::TestSparseEnum_Name(unittest::SPARSE_E)); - EXPECT_EQ("SPARSE_F", unittest::TestSparseEnum_Name(unittest::SPARSE_F)); - EXPECT_EQ("SPARSE_G", unittest::TestSparseEnum_Name(unittest::SPARSE_G)); -} - -TEST(GeneratedEnumTest, Parse) { - unittest::TestEnumWithDupValue dup_value = unittest::FOO1; - EXPECT_TRUE(unittest::TestEnumWithDupValue_Parse("FOO1", &dup_value)); - EXPECT_EQ(unittest::FOO1, dup_value); - EXPECT_TRUE(unittest::TestEnumWithDupValue_Parse("FOO2", &dup_value)); - EXPECT_EQ(unittest::FOO2, dup_value); - EXPECT_FALSE(unittest::TestEnumWithDupValue_Parse("FOO", &dup_value)); -} - -TEST(GeneratedEnumTest, GetEnumDescriptor) { - EXPECT_EQ(unittest::TestAllTypes::NestedEnum_descriptor(), - GetEnumDescriptor<unittest::TestAllTypes::NestedEnum>()); - EXPECT_EQ(unittest::ForeignEnum_descriptor(), - GetEnumDescriptor<unittest::ForeignEnum>()); - EXPECT_EQ(unittest::TestEnumWithDupValue_descriptor(), - GetEnumDescriptor<unittest::TestEnumWithDupValue>()); - EXPECT_EQ(unittest::TestSparseEnum_descriptor(), - GetEnumDescriptor<unittest::TestSparseEnum>()); -} - -enum NonProtoEnum { - kFoo = 1, -}; - -TEST(GeneratedEnumTest, IsProtoEnumTypeTrait) { - EXPECT_TRUE(is_proto_enum<unittest::TestAllTypes::NestedEnum>::value); - EXPECT_TRUE(is_proto_enum<unittest::ForeignEnum>::value); - EXPECT_TRUE(is_proto_enum<unittest::TestEnumWithDupValue>::value); - EXPECT_TRUE(is_proto_enum<unittest::TestSparseEnum>::value); - - EXPECT_FALSE(is_proto_enum<int>::value); - EXPECT_FALSE(is_proto_enum<NonProtoEnum>::value); -} - -#endif // PROTOBUF_TEST_NO_DESCRIPTORS - -// =================================================================== - -#ifndef PROTOBUF_TEST_NO_DESCRIPTORS - -// Support code for testing services. -class GeneratedServiceTest : public testing::Test { - protected: - class MockTestService : public unittest::TestService { - public: - MockTestService() - : called_(false), - method_(""), - controller_(NULL), - request_(NULL), - response_(NULL), - done_(NULL) {} - - ~MockTestService() {} - - void Reset() { called_ = false; } - - // implements TestService ---------------------------------------- - - void Foo(RpcController* controller, - const unittest::FooRequest* request, - unittest::FooResponse* response, - Closure* done) { - ASSERT_FALSE(called_); - called_ = true; - method_ = "Foo"; - controller_ = controller; - request_ = request; - response_ = response; - done_ = done; - } - - void Bar(RpcController* controller, - const unittest::BarRequest* request, - unittest::BarResponse* response, - Closure* done) { - ASSERT_FALSE(called_); - called_ = true; - method_ = "Bar"; - controller_ = controller; - request_ = request; - response_ = response; - done_ = done; - } - - // --------------------------------------------------------------- - - bool called_; - string method_; - RpcController* controller_; - const Message* request_; - Message* response_; - Closure* done_; - }; - - class MockRpcChannel : public RpcChannel { - public: - MockRpcChannel() - : called_(false), - method_(NULL), - controller_(NULL), - request_(NULL), - response_(NULL), - done_(NULL), - destroyed_(NULL) {} - - ~MockRpcChannel() { - if (destroyed_ != NULL) *destroyed_ = true; - } - - void Reset() { called_ = false; } - - // implements TestService ---------------------------------------- - - void CallMethod(const MethodDescriptor* method, - RpcController* controller, - const Message* request, - Message* response, - Closure* done) { - ASSERT_FALSE(called_); - called_ = true; - method_ = method; - controller_ = controller; - request_ = request; - response_ = response; - done_ = done; - } - - // --------------------------------------------------------------- - - bool called_; - const MethodDescriptor* method_; - RpcController* controller_; - const Message* request_; - Message* response_; - Closure* done_; - bool* destroyed_; - }; - - class MockController : public RpcController { - public: - void Reset() { - ADD_FAILURE() << "Reset() not expected during this test."; - } - bool Failed() const { - ADD_FAILURE() << "Failed() not expected during this test."; - return false; - } - string ErrorText() const { - ADD_FAILURE() << "ErrorText() not expected during this test."; - return ""; - } - void StartCancel() { - ADD_FAILURE() << "StartCancel() not expected during this test."; - } - void SetFailed(const string& reason) { - ADD_FAILURE() << "SetFailed() not expected during this test."; - } - bool IsCanceled() const { - ADD_FAILURE() << "IsCanceled() not expected during this test."; - return false; - } - void NotifyOnCancel(Closure* callback) { - ADD_FAILURE() << "NotifyOnCancel() not expected during this test."; - } - }; - - GeneratedServiceTest() - : descriptor_(unittest::TestService::descriptor()), - foo_(descriptor_->FindMethodByName("Foo")), - bar_(descriptor_->FindMethodByName("Bar")), - stub_(&mock_channel_), - done_(::google::protobuf::NewPermanentCallback(&DoNothing)) {} - - virtual void SetUp() { - ASSERT_TRUE(foo_ != NULL); - ASSERT_TRUE(bar_ != NULL); - } - - const ServiceDescriptor* descriptor_; - const MethodDescriptor* foo_; - const MethodDescriptor* bar_; - - MockTestService mock_service_; - MockController mock_controller_; - - MockRpcChannel mock_channel_; - unittest::TestService::Stub stub_; - - // Just so we don't have to re-define these with every test. - unittest::FooRequest foo_request_; - unittest::FooResponse foo_response_; - unittest::BarRequest bar_request_; - unittest::BarResponse bar_response_; - google::protobuf::scoped_ptr<Closure> done_; -}; - -TEST_F(GeneratedServiceTest, GetDescriptor) { - // Test that GetDescriptor() works. - - EXPECT_EQ(descriptor_, mock_service_.GetDescriptor()); -} - -TEST_F(GeneratedServiceTest, GetChannel) { - EXPECT_EQ(&mock_channel_, stub_.channel()); -} - -TEST_F(GeneratedServiceTest, OwnsChannel) { - MockRpcChannel* channel = new MockRpcChannel; - bool destroyed = false; - channel->destroyed_ = &destroyed; - - { - unittest::TestService::Stub owning_stub(channel, - Service::STUB_OWNS_CHANNEL); - EXPECT_FALSE(destroyed); - } - - EXPECT_TRUE(destroyed); -} - -TEST_F(GeneratedServiceTest, CallMethod) { - // Test that CallMethod() works. - - // Call Foo() via CallMethod(). - mock_service_.CallMethod(foo_, &mock_controller_, - &foo_request_, &foo_response_, done_.get()); - - ASSERT_TRUE(mock_service_.called_); - - EXPECT_EQ("Foo" , mock_service_.method_ ); - EXPECT_EQ(&mock_controller_, mock_service_.controller_); - EXPECT_EQ(&foo_request_ , mock_service_.request_ ); - EXPECT_EQ(&foo_response_ , mock_service_.response_ ); - EXPECT_EQ(done_.get() , mock_service_.done_ ); - - // Try again, but call Bar() instead. - mock_service_.Reset(); - mock_service_.CallMethod(bar_, &mock_controller_, - &bar_request_, &bar_response_, done_.get()); - - ASSERT_TRUE(mock_service_.called_); - EXPECT_EQ("Bar", mock_service_.method_); -} - -TEST_F(GeneratedServiceTest, CallMethodTypeFailure) { - // Verify death if we call Foo() with Bar's message types. - -#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet - EXPECT_DEBUG_DEATH( - mock_service_.CallMethod(foo_, &mock_controller_, - &foo_request_, &bar_response_, done_.get()), - "dynamic_cast"); - - mock_service_.Reset(); - EXPECT_DEBUG_DEATH( - mock_service_.CallMethod(foo_, &mock_controller_, - &bar_request_, &foo_response_, done_.get()), - "dynamic_cast"); -#endif // PROTOBUF_HAS_DEATH_TEST -} - -TEST_F(GeneratedServiceTest, GetPrototypes) { - // Test Get{Request,Response}Prototype() methods. - - EXPECT_EQ(&unittest::FooRequest::default_instance(), - &mock_service_.GetRequestPrototype(foo_)); - EXPECT_EQ(&unittest::BarRequest::default_instance(), - &mock_service_.GetRequestPrototype(bar_)); - - EXPECT_EQ(&unittest::FooResponse::default_instance(), - &mock_service_.GetResponsePrototype(foo_)); - EXPECT_EQ(&unittest::BarResponse::default_instance(), - &mock_service_.GetResponsePrototype(bar_)); -} - -TEST_F(GeneratedServiceTest, Stub) { - // Test that the stub class works. - - // Call Foo() via the stub. - stub_.Foo(&mock_controller_, &foo_request_, &foo_response_, done_.get()); - - ASSERT_TRUE(mock_channel_.called_); - - EXPECT_EQ(foo_ , mock_channel_.method_ ); - EXPECT_EQ(&mock_controller_, mock_channel_.controller_); - EXPECT_EQ(&foo_request_ , mock_channel_.request_ ); - EXPECT_EQ(&foo_response_ , mock_channel_.response_ ); - EXPECT_EQ(done_.get() , mock_channel_.done_ ); - - // Call Bar() via the stub. - mock_channel_.Reset(); - stub_.Bar(&mock_controller_, &bar_request_, &bar_response_, done_.get()); - - ASSERT_TRUE(mock_channel_.called_); - EXPECT_EQ(bar_, mock_channel_.method_); -} - -TEST_F(GeneratedServiceTest, NotImplemented) { - // Test that failing to implement a method of a service causes it to fail - // with a "not implemented" error message. - - // A service which doesn't implement any methods. - class UnimplementedService : public unittest::TestService { - public: - UnimplementedService() {} - }; - - UnimplementedService unimplemented_service; - - // And a controller which expects to get a "not implemented" error. - class ExpectUnimplementedController : public MockController { - public: - ExpectUnimplementedController() : called_(false) {} - - void SetFailed(const string& reason) { - EXPECT_FALSE(called_); - called_ = true; - EXPECT_EQ("Method Foo() not implemented.", reason); - } - - bool called_; - }; - - ExpectUnimplementedController controller; - - // Call Foo. - unimplemented_service.Foo(&controller, &foo_request_, &foo_response_, - done_.get()); - - EXPECT_TRUE(controller.called_); -} - -// =================================================================== - -class OneofTest : public testing::Test { - protected: - virtual void SetUp() { - } - - void ExpectEnumCasesWork(const unittest::TestOneof2 &message) { - switch (message.foo_case()) { - case unittest::TestOneof2::kFooInt: - EXPECT_TRUE(message.has_foo_int()); - break; - case unittest::TestOneof2::kFooString: - EXPECT_TRUE(message.has_foo_string()); - break; - case unittest::TestOneof2::kFooCord: - EXPECT_TRUE(message.has_foo_cord()); - break; - case unittest::TestOneof2::kFooStringPiece: - EXPECT_TRUE(message.has_foo_string_piece()); - break; - case unittest::TestOneof2::kFooBytes: - EXPECT_TRUE(message.has_foo_bytes()); - break; - case unittest::TestOneof2::kFooEnum: - EXPECT_TRUE(message.has_foo_enum()); - break; - case unittest::TestOneof2::kFooMessage: - EXPECT_TRUE(message.has_foo_message()); - break; - case unittest::TestOneof2::kFoogroup: - EXPECT_TRUE(message.has_foogroup()); - break; - case unittest::TestOneof2::kFooLazyMessage: - EXPECT_TRUE(message.has_foo_lazy_message()); - break; - case unittest::TestOneof2::FOO_NOT_SET: - break; - } - } -}; - -TEST_F(OneofTest, SettingOneFieldClearsOthers) { - unittest::TestOneof2 message; - - message.set_foo_int(123); - EXPECT_TRUE(message.has_foo_int()); - TestUtil::ExpectAtMostOneFieldSetInOneof(message); - - message.set_foo_string("foo"); - EXPECT_TRUE(message.has_foo_string()); - TestUtil::ExpectAtMostOneFieldSetInOneof(message); - - - message.set_foo_bytes("qux"); - EXPECT_TRUE(message.has_foo_bytes()); - TestUtil::ExpectAtMostOneFieldSetInOneof(message); - - message.set_foo_enum(unittest::TestOneof2::FOO); - EXPECT_TRUE(message.has_foo_enum()); - TestUtil::ExpectAtMostOneFieldSetInOneof(message); - - message.mutable_foo_message()->set_qux_int(234); - EXPECT_TRUE(message.has_foo_message()); - TestUtil::ExpectAtMostOneFieldSetInOneof(message); - - message.mutable_foogroup()->set_a(345); - EXPECT_TRUE(message.has_foogroup()); - TestUtil::ExpectAtMostOneFieldSetInOneof(message); - - - // we repeat this because we didn't test if this properly clears other fields - // at the beginning. - message.set_foo_int(123); - EXPECT_TRUE(message.has_foo_int()); - TestUtil::ExpectAtMostOneFieldSetInOneof(message); -} - -TEST_F(OneofTest, EnumCases) { - unittest::TestOneof2 message; - - message.set_foo_int(123); - ExpectEnumCasesWork(message); - message.set_foo_string("foo"); - ExpectEnumCasesWork(message); - message.set_foo_bytes("qux"); - ExpectEnumCasesWork(message); - message.set_foo_enum(unittest::TestOneof2::FOO); - ExpectEnumCasesWork(message); - message.mutable_foo_message()->set_qux_int(234); - ExpectEnumCasesWork(message); - message.mutable_foogroup()->set_a(345); - ExpectEnumCasesWork(message); -} - -TEST_F(OneofTest, PrimitiveType) { - unittest::TestOneof2 message; - // Unset field returns default value - EXPECT_EQ(message.foo_int(), 0); - - message.set_foo_int(123); - EXPECT_TRUE(message.has_foo_int()); - EXPECT_EQ(message.foo_int(), 123); - message.clear_foo_int(); - EXPECT_FALSE(message.has_foo_int()); -} - -TEST_F(OneofTest, EnumType) { - unittest::TestOneof2 message; - // Unset field returns default value - EXPECT_EQ(message.foo_enum(), 1); - - message.set_foo_enum(unittest::TestOneof2::FOO); - EXPECT_TRUE(message.has_foo_enum()); - EXPECT_EQ(message.foo_enum(), unittest::TestOneof2::FOO); - message.clear_foo_enum(); - EXPECT_FALSE(message.has_foo_enum()); -} - -TEST_F(OneofTest, SetString) { - // Check that setting a string field in various ways works - unittest::TestOneof2 message; - - // Unset field returns default value - EXPECT_EQ(message.foo_string(), ""); - - message.set_foo_string("foo"); - EXPECT_TRUE(message.has_foo_string()); - EXPECT_EQ(message.foo_string(), "foo"); - message.clear_foo_string(); - EXPECT_FALSE(message.has_foo_string()); - - message.set_foo_string(string("bar")); - EXPECT_TRUE(message.has_foo_string()); - EXPECT_EQ(message.foo_string(), "bar"); - message.clear_foo_string(); - EXPECT_FALSE(message.has_foo_string()); - - - message.set_foo_string("qux", 3); - EXPECT_TRUE(message.has_foo_string()); - EXPECT_EQ(message.foo_string(), "qux"); - message.clear_foo_string(); - EXPECT_FALSE(message.has_foo_string()); - - message.mutable_foo_string()->assign("quux"); - EXPECT_TRUE(message.has_foo_string()); - EXPECT_EQ(message.foo_string(), "quux"); - message.clear_foo_string(); - EXPECT_FALSE(message.has_foo_string()); - - message.set_foo_string("corge"); - EXPECT_TRUE(message.has_foo_string()); - EXPECT_EQ(message.foo_string(), "corge"); - message.clear_foo_string(); - EXPECT_FALSE(message.has_foo_string()); -} - -TEST_F(OneofTest, ReleaseString) { - // Check that release_foo() starts out NULL, and gives us a value - // that we can delete after it's been set. - unittest::TestOneof2 message; - - EXPECT_EQ(NULL, message.release_foo_string()); - EXPECT_FALSE(message.has_foo_string()); - - message.set_foo_string("blah"); - EXPECT_TRUE(message.has_foo_string()); - google::protobuf::scoped_ptr<string> str(message.release_foo_string()); - EXPECT_FALSE(message.has_foo_string()); - ASSERT_TRUE(str != NULL); - EXPECT_EQ("blah", *str); - - EXPECT_EQ(NULL, message.release_foo_string()); - EXPECT_FALSE(message.has_foo_string()); -} - -TEST_F(OneofTest, SetAllocatedString) { - // Check that set_allocated_foo() works for strings. - unittest::TestOneof2 message; - - EXPECT_FALSE(message.has_foo_string()); - const string kHello("hello"); - message.set_foo_string(kHello); - EXPECT_TRUE(message.has_foo_string()); - - message.set_allocated_foo_string(NULL); - EXPECT_FALSE(message.has_foo_string()); - EXPECT_EQ("", message.foo_string()); - - message.set_allocated_foo_string(new string(kHello)); - EXPECT_TRUE(message.has_foo_string()); - EXPECT_EQ(kHello, message.foo_string()); -} - - -TEST_F(OneofTest, SetMessage) { - // Check that setting a message field works - unittest::TestOneof2 message; - - // Unset field returns default instance - EXPECT_EQ(&message.foo_message(), - &unittest::TestOneof2_NestedMessage::default_instance()); - EXPECT_EQ(message.foo_message().qux_int(), 0); - - message.mutable_foo_message()->set_qux_int(234); - EXPECT_TRUE(message.has_foo_message()); - EXPECT_EQ(message.foo_message().qux_int(), 234); - message.clear_foo_message(); - EXPECT_FALSE(message.has_foo_message()); -} - -TEST_F(OneofTest, ReleaseMessage) { - // Check that release_foo() starts out NULL, and gives us a value - // that we can delete after it's been set. - unittest::TestOneof2 message; - - EXPECT_EQ(NULL, message.release_foo_message()); - EXPECT_FALSE(message.has_foo_message()); - - message.mutable_foo_message()->set_qux_int(1); - EXPECT_TRUE(message.has_foo_message()); - google::protobuf::scoped_ptr<unittest::TestOneof2_NestedMessage> mes( - message.release_foo_message()); - EXPECT_FALSE(message.has_foo_message()); - ASSERT_TRUE(mes != NULL); - EXPECT_EQ(1, mes->qux_int()); - - EXPECT_EQ(NULL, message.release_foo_message()); - EXPECT_FALSE(message.has_foo_message()); -} - -TEST_F(OneofTest, SetAllocatedMessage) { - // Check that set_allocated_foo() works for messages. - unittest::TestOneof2 message; - - EXPECT_FALSE(message.has_foo_message()); - - message.mutable_foo_message()->set_qux_int(1); - EXPECT_TRUE(message.has_foo_message()); - - message.set_allocated_foo_message(NULL); - EXPECT_FALSE(message.has_foo_message()); - EXPECT_EQ(&message.foo_message(), - &unittest::TestOneof2_NestedMessage::default_instance()); - - message.mutable_foo_message()->set_qux_int(1); - unittest::TestOneof2_NestedMessage* mes = message.release_foo_message(); - ASSERT_TRUE(mes != NULL); - EXPECT_FALSE(message.has_foo_message()); - - message.set_allocated_foo_message(mes); - EXPECT_TRUE(message.has_foo_message()); - EXPECT_EQ(1, message.foo_message().qux_int()); -} - - -TEST_F(OneofTest, Clear) { - unittest::TestOneof2 message; - - message.set_foo_int(1); - EXPECT_TRUE(message.has_foo_int()); - message.clear_foo_int(); - EXPECT_FALSE(message.has_foo_int()); -} - -TEST_F(OneofTest, Defaults) { - unittest::TestOneof2 message; - - EXPECT_FALSE(message.has_foo_int()); - EXPECT_EQ(message.foo_int(), 0); - - EXPECT_FALSE(message.has_foo_string()); - EXPECT_EQ(message.foo_string(), ""); - - - EXPECT_FALSE(message.has_foo_bytes()); - EXPECT_EQ(message.foo_bytes(), ""); - - EXPECT_FALSE(message.has_foo_enum()); - EXPECT_EQ(message.foo_enum(), 1); - - EXPECT_FALSE(message.has_foo_message()); - EXPECT_EQ(message.foo_message().qux_int(), 0); - - EXPECT_FALSE(message.has_foogroup()); - EXPECT_EQ(message.foogroup().a(), 0); - - - EXPECT_FALSE(message.has_bar_int()); - EXPECT_EQ(message.bar_int(), 5); - - EXPECT_FALSE(message.has_bar_string()); - EXPECT_EQ(message.bar_string(), "STRING"); - - - EXPECT_FALSE(message.has_bar_bytes()); - EXPECT_EQ(message.bar_bytes(), "BYTES"); - - EXPECT_FALSE(message.has_bar_enum()); - EXPECT_EQ(message.bar_enum(), 2); -} - -TEST_F(OneofTest, SwapWithEmpty) { - unittest::TestOneof2 message1, message2; - message1.set_foo_string("FOO"); - EXPECT_TRUE(message1.has_foo_string()); - message1.Swap(&message2); - EXPECT_FALSE(message1.has_foo_string()); - EXPECT_TRUE(message2.has_foo_string()); - EXPECT_EQ(message2.foo_string(), "FOO"); -} - -TEST_F(OneofTest, SwapWithSelf) { - unittest::TestOneof2 message; - message.set_foo_string("FOO"); - EXPECT_TRUE(message.has_foo_string()); - message.Swap(&message); - EXPECT_TRUE(message.has_foo_string()); - EXPECT_EQ(message.foo_string(), "FOO"); -} - -TEST_F(OneofTest, SwapBothHasFields) { - unittest::TestOneof2 message1, message2; - - message1.set_foo_string("FOO"); - EXPECT_TRUE(message1.has_foo_string()); - message2.mutable_foo_message()->set_qux_int(1); - EXPECT_TRUE(message2.has_foo_message()); - - message1.Swap(&message2); - EXPECT_FALSE(message1.has_foo_string()); - EXPECT_FALSE(message2.has_foo_message()); - EXPECT_TRUE(message1.has_foo_message()); - EXPECT_EQ(message1.foo_message().qux_int(), 1); - EXPECT_TRUE(message2.has_foo_string()); - EXPECT_EQ(message2.foo_string(), "FOO"); -} - -TEST_F(OneofTest, CopyConstructor) { - unittest::TestOneof2 message1; - message1.set_foo_bytes("FOO"); - - unittest::TestOneof2 message2(message1); - EXPECT_TRUE(message2.has_foo_bytes()); - EXPECT_EQ(message2.foo_bytes(), "FOO"); -} - -TEST_F(OneofTest, CopyFrom) { - unittest::TestOneof2 message1, message2; - message1.set_foo_enum(unittest::TestOneof2::BAR); - EXPECT_TRUE(message1.has_foo_enum()); - - message2.CopyFrom(message1); - EXPECT_TRUE(message2.has_foo_enum()); - EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::BAR); - - // Copying from self should be a no-op. - message2.CopyFrom(message2); - EXPECT_TRUE(message2.has_foo_enum()); - EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::BAR); -} - -TEST_F(OneofTest, CopyAssignmentOperator) { - unittest::TestOneof2 message1; - message1.mutable_foo_message()->set_qux_int(123); - EXPECT_TRUE(message1.has_foo_message()); - - unittest::TestOneof2 message2; - message2 = message1; - EXPECT_EQ(message2.foo_message().qux_int(), 123); - - // Make sure that self-assignment does something sane. - message2 = message2; - EXPECT_EQ(message2.foo_message().qux_int(), 123); -} - -TEST_F(OneofTest, UpcastCopyFrom) { - // Test the CopyFrom method that takes in the generic const Message& - // parameter. - unittest::TestOneof2 message1, message2; - message1.mutable_foogroup()->set_a(123); - EXPECT_TRUE(message1.has_foogroup()); - - const Message* source = implicit_cast<const Message*>(&message1); - message2.CopyFrom(*source); - - EXPECT_TRUE(message2.has_foogroup()); - EXPECT_EQ(message2.foogroup().a(), 123); -} - -// Test the generated SerializeWithCachedSizesToArray(), -// This indirectly tests MergePartialFromCodedStream() -// We have to test each field type separately because we cannot set them at the -// same time -TEST_F(OneofTest, SerializationToArray) { - // Primitive type - { - unittest::TestOneof2 message1, message2; - string data; - message1.set_foo_int(123); - int size = message1.ByteSize(); - data.resize(size); - uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); - uint8* end = message1.SerializeWithCachedSizesToArray(start); - EXPECT_EQ(size, end - start); - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_int(), 123); - } - - // String - { - unittest::TestOneof2 message1, message2; - string data; - message1.set_foo_string("foo"); - int size = message1.ByteSize(); - data.resize(size); - uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); - uint8* end = message1.SerializeWithCachedSizesToArray(start); - EXPECT_EQ(size, end - start); - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_string(), "foo"); - } - - - // Bytes - { - unittest::TestOneof2 message1, message2; - string data; - message1.set_foo_bytes("qux"); - int size = message1.ByteSize(); - data.resize(size); - uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); - uint8* end = message1.SerializeWithCachedSizesToArray(start); - EXPECT_EQ(size, end - start); - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_bytes(), "qux"); - } - - // Enum - { - unittest::TestOneof2 message1, message2; - string data; - message1.set_foo_enum(unittest::TestOneof2::FOO); - int size = message1.ByteSize(); - data.resize(size); - uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); - uint8* end = message1.SerializeWithCachedSizesToArray(start); - EXPECT_EQ(size, end - start); - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::FOO); - } - - // Message - { - unittest::TestOneof2 message1, message2; - string data; - message1.mutable_foo_message()->set_qux_int(234); - int size = message1.ByteSize(); - data.resize(size); - uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); - uint8* end = message1.SerializeWithCachedSizesToArray(start); - EXPECT_EQ(size, end - start); - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_message().qux_int(), 234); - } - - // Group - { - unittest::TestOneof2 message1, message2; - string data; - message1.mutable_foogroup()->set_a(345); - int size = message1.ByteSize(); - data.resize(size); - uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); - uint8* end = message1.SerializeWithCachedSizesToArray(start); - EXPECT_EQ(size, end - start); - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foogroup().a(), 345); - } - -} - -// Test the generated SerializeWithCachedSizes() by forcing the buffer to write -// one byte at a time. -// This indirectly tests MergePartialFromCodedStream() -// We have to test each field type separately because we cannot set them at the -// same time -TEST_F(OneofTest, SerializationToStream) { - // Primitive type - { - unittest::TestOneof2 message1, message2; - string data; - message1.set_foo_int(123); - int size = message1.ByteSize(); - data.resize(size); - - { - // Allow the output stream to buffer only one byte at a time. - io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - message1.SerializeWithCachedSizes(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - } - - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_int(), 123); - } - - // String - { - unittest::TestOneof2 message1, message2; - string data; - message1.set_foo_string("foo"); - int size = message1.ByteSize(); - data.resize(size); - - { - // Allow the output stream to buffer only one byte at a time. - io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - message1.SerializeWithCachedSizes(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - } - - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_string(), "foo"); - } - - - // Bytes - { - unittest::TestOneof2 message1, message2; - string data; - message1.set_foo_bytes("qux"); - int size = message1.ByteSize(); - data.resize(size); - - { - // Allow the output stream to buffer only one byte at a time. - io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - message1.SerializeWithCachedSizes(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - } - - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_bytes(), "qux"); - } - - // Enum - { - unittest::TestOneof2 message1, message2; - string data; - message1.set_foo_enum(unittest::TestOneof2::FOO); - int size = message1.ByteSize(); - data.resize(size); - - { - // Allow the output stream to buffer only one byte at a time. - io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - message1.SerializeWithCachedSizes(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - } - - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::FOO); - } - - // Message - { - unittest::TestOneof2 message1, message2; - string data; - message1.mutable_foo_message()->set_qux_int(234); - int size = message1.ByteSize(); - data.resize(size); - - { - // Allow the output stream to buffer only one byte at a time. - io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - message1.SerializeWithCachedSizes(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - } - - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foo_message().qux_int(), 234); - } - - // Group - { - unittest::TestOneof2 message1, message2; - string data; - message1.mutable_foogroup()->set_a(345); - int size = message1.ByteSize(); - data.resize(size); - - { - // Allow the output stream to buffer only one byte at a time. - io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); - io::CodedOutputStream output_stream(&array_stream); - message1.SerializeWithCachedSizes(&output_stream); - EXPECT_FALSE(output_stream.HadError()); - EXPECT_EQ(size, output_stream.ByteCount()); - } - - EXPECT_TRUE(message2.ParseFromString(data)); - EXPECT_EQ(message2.foogroup().a(), 345); - } - -} - -TEST_F(OneofTest, MergeFrom) { - unittest::TestOneof2 message1, message2; - - message1.set_foo_int(123); - message2.MergeFrom(message1); - TestUtil::ExpectAtMostOneFieldSetInOneof(message2); - EXPECT_TRUE(message2.has_foo_int()); - EXPECT_EQ(message2.foo_int(), 123); - - message1.set_foo_string("foo"); - message2.MergeFrom(message1); - TestUtil::ExpectAtMostOneFieldSetInOneof(message2); - EXPECT_TRUE(message2.has_foo_string()); - EXPECT_EQ(message2.foo_string(), "foo"); - - - message1.set_foo_bytes("qux"); - message2.MergeFrom(message1); - TestUtil::ExpectAtMostOneFieldSetInOneof(message2); - EXPECT_TRUE(message2.has_foo_bytes()); - EXPECT_EQ(message2.foo_bytes(), "qux"); - - message1.set_foo_enum(unittest::TestOneof2::FOO); - message2.MergeFrom(message1); - TestUtil::ExpectAtMostOneFieldSetInOneof(message2); - EXPECT_TRUE(message2.has_foo_enum()); - EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::FOO); - - message1.mutable_foo_message()->set_qux_int(234); - message2.MergeFrom(message1); - TestUtil::ExpectAtMostOneFieldSetInOneof(message2); - EXPECT_TRUE(message2.has_foo_message()); - EXPECT_EQ(message2.foo_message().qux_int(), 234); - - message1.mutable_foogroup()->set_a(345); - message2.MergeFrom(message1); - TestUtil::ExpectAtMostOneFieldSetInOneof(message2); - EXPECT_TRUE(message2.has_foogroup()); - EXPECT_EQ(message2.foogroup().a(), 345); - -} - -TEST(HelpersTest, TestSCC) { - protobuf_unittest::TestMutualRecursionA a; - SCCAnalyzer scc_analyzer((Options())); - const SCC* scc = scc_analyzer.GetSCC(a.GetDescriptor()); - std::vector<string> names; - for (int i = 0; i < scc->descriptors.size(); i++) { - names.push_back(scc->descriptors[i]->full_name()); - } - ASSERT_EQ(names.size(), 4); - std::sort(names.begin(), names.end()); - EXPECT_EQ(names[0], "protobuf_unittest.TestMutualRecursionA"); - EXPECT_EQ(names[1], "protobuf_unittest.TestMutualRecursionA.SubGroup"); - EXPECT_EQ(names[2], "protobuf_unittest.TestMutualRecursionA.SubMessage"); - EXPECT_EQ(names[3], "protobuf_unittest.TestMutualRecursionB"); - - MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); - EXPECT_EQ(result.is_recursive, true); - EXPECT_EQ(result.contains_required, false); - EXPECT_EQ(result.contains_cord, true); // TestAllTypes - EXPECT_EQ(result.contains_extension, false); // TestAllTypes -} - -TEST(HelpersTest, TestSCCAnalysis) { - { - protobuf_unittest::TestRecursiveMessage msg; - SCCAnalyzer scc_analyzer((Options())); - const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor()); - MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); - EXPECT_EQ(result.is_recursive, true); - EXPECT_EQ(result.contains_required, false); - EXPECT_EQ(result.contains_cord, false); - EXPECT_EQ(result.contains_extension, false); - } - { - protobuf_unittest::TestAllExtensions msg; - SCCAnalyzer scc_analyzer((Options())); - const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor()); - MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); - EXPECT_EQ(result.is_recursive, false); - EXPECT_EQ(result.contains_required, false); - EXPECT_EQ(result.contains_cord, false); - EXPECT_EQ(result.contains_extension, true); - } - { - protobuf_unittest::TestRequired msg; - SCCAnalyzer scc_analyzer((Options())); - const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor()); - MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); - EXPECT_EQ(result.is_recursive, false); - EXPECT_EQ(result.contains_required, true); - EXPECT_EQ(result.contains_cord, false); - EXPECT_EQ(result.contains_extension, false); - } -} - -} // namespace cpp_unittest -} // namespace cpp -} // namespace compiler - -namespace no_generic_services_test { - // Verify that no class called "TestService" was defined in - // unittest_no_generic_services.pb.h by defining a different type by the same - // name. If such a service was generated, this will not compile. - struct TestService { - int i; - }; -} - -namespace compiler { -namespace cpp { -namespace cpp_unittest { - -TEST_F(GeneratedServiceTest, NoGenericServices) { - // Verify that non-services in unittest_no_generic_services.proto were - // generated. - no_generic_services_test::TestMessage message; - message.set_a(1); - message.SetExtension(no_generic_services_test::test_extension, 123); - no_generic_services_test::TestEnum e = no_generic_services_test::FOO; - EXPECT_EQ(e, 1); - - // Verify that a ServiceDescriptor is generated for the service even if the - // class itself is not. - const FileDescriptor* file = - no_generic_services_test::TestMessage::descriptor()->file(); - - ASSERT_EQ(1, file->service_count()); - EXPECT_EQ("TestService", file->service(0)->name()); - ASSERT_EQ(1, file->service(0)->method_count()); - EXPECT_EQ("Foo", file->service(0)->method(0)->name()); -} - -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS - -// =================================================================== - -// This test must run last. It verifies that descriptors were or were not -// initialized depending on whether PROTOBUF_TEST_NO_DESCRIPTORS was defined. -// When this is defined, we skip all tests which are expected to trigger -// descriptor initialization. This verifies that everything else still works -// if descriptors are not initialized. -TEST(DescriptorInitializationTest, Initialized) { -#ifdef PROTOBUF_TEST_NO_DESCRIPTORS - bool should_have_descriptors = false; -#else - bool should_have_descriptors = true; -#endif - - EXPECT_EQ(should_have_descriptors, - DescriptorPool::generated_pool()->InternalIsFileLoaded( - "google/protobuf/unittest.proto")); -} - } // namespace cpp_unittest - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.inc b/src/google/protobuf/compiler/cpp/cpp_unittest.inc new file mode 100644 index 00000000..ff6354f8 --- /dev/null +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.inc @@ -0,0 +1,2281 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// To test the code generator, we actually use it to generate code for +// google/protobuf/unittest.proto, then test that. This means that we +// are actually testing the parser and other parts of the system at the same +// time, and that problems in the generator may show up as compile-time errors +// rather than unittest failures, which may be surprising. However, testing +// the output of the C++ generator directly would be very hard. We can't very +// well just check it against golden files since those files would have to be +// updated for any small change; such a test would be very brittle and probably +// not very helpful. What we really want to test is that the code compiles +// correctly and produces the interfaces we expect, which is why this test +// is written this way. + +#include <google/protobuf/compiler/cpp/cpp_unittest.h> + +#include <memory> +#include <vector> + +#include <google/protobuf/unittest_no_arena.pb.h> +#if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER) +// We exclude this large proto from cmake build because it's too large for +// visual studio to compile (report internal errors). +#include <google/protobuf/unittest_enormous_descriptor.pb.h> +#endif +#include <google/protobuf/compiler/cpp/cpp_helpers.h> +#include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h> +#include <google/protobuf/compiler/importer.h> +#include <google/protobuf/unittest_no_generic_services.pb.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/arena.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/dynamic_message.h> + +#include <google/protobuf/stubs/callback.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> +#include <google/protobuf/stubs/stl_util.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. +namespace cpp_unittest { + + +class MockErrorCollector : public MultiFileErrorCollector { + public: + MockErrorCollector() {} + ~MockErrorCollector() {} + + string text_; + + // implements ErrorCollector --------------------------------------- + void AddError(const string& filename, int line, int column, + const string& message) { + strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", + filename, line, column, message); + } +}; + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +// Test that generated code has proper descriptors: +// Parse a descriptor directly (using google::protobuf::compiler::Importer) and +// compare it to the one that was produced by generated code. +TEST(GENERATED_DESCRIPTOR_TEST_NAME, IdenticalDescriptors) { + const FileDescriptor* generated_descriptor = + UNITTEST::TestAllTypes::descriptor()->file(); + + // Set up the Importer. + MockErrorCollector error_collector; + DiskSourceTree source_tree; + source_tree.MapPath("", TestSourceDir()); + Importer importer(&source_tree, &error_collector); + + // Import (parse) unittest.proto. + const FileDescriptor* parsed_descriptor = + importer.Import(UNITTEST_PROTO_PATH); + EXPECT_EQ("", error_collector.text_); + ASSERT_TRUE(parsed_descriptor != NULL); + + // Test that descriptors are generated correctly by converting them to + // FileDescriptorProtos and comparing. + FileDescriptorProto generated_descriptor_proto, parsed_descriptor_proto; + generated_descriptor->CopyTo(&generated_descriptor_proto); + parsed_descriptor->CopyTo(&parsed_descriptor_proto); + + EXPECT_EQ(parsed_descriptor_proto.DebugString(), + generated_descriptor_proto.DebugString()); +} + +#if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER) +// Test that generated code has proper descriptors: +// Touch a descriptor generated from an enormous message to validate special +// handling for descriptors exceeding the C++ standard's recommended minimum +// limit for string literal size +TEST(GENERATED_DESCRIPTOR_TEST_NAME, EnormousDescriptor) { + const Descriptor* generated_descriptor = + TestEnormousDescriptor::descriptor(); + + EXPECT_TRUE(generated_descriptor != NULL); +} +#endif + +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS + +// =================================================================== + +TEST(GENERATED_MESSAGE_TEST_NAME, Defaults) { + // Check that all default values are set correctly in the initial message. + UNITTEST::TestAllTypes message; + + TestUtil::ExpectClear(message); + + // Messages should return pointers to default instances until first use. + // (This is not checked by ExpectClear() since it is not actually true after + // the fields have been set and then cleared.) + EXPECT_EQ(&UNITTEST::TestAllTypes::OptionalGroup::default_instance(), + &message.optionalgroup()); + EXPECT_EQ(&UNITTEST::TestAllTypes::NestedMessage::default_instance(), + &message.optional_nested_message()); + EXPECT_EQ(&UNITTEST::ForeignMessage::default_instance(), + &message.optional_foreign_message()); + EXPECT_EQ(&UNITTEST_IMPORT::ImportMessage::default_instance(), + &message.optional_import_message()); +} + +#ifndef PROTOBUF_USE_DLLS +TEST(GENERATED_MESSAGE_TEST_NAME, Int32StringConversion) { + EXPECT_EQ("971", Int32ToString(971)); + EXPECT_EQ("(~0x7fffffff)", Int32ToString(kint32min)); + EXPECT_EQ("2147483647", Int32ToString(kint32max)); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, Int64StringConversion) { + EXPECT_EQ("GOOGLE_LONGLONG(971)", Int64ToString(971)); + EXPECT_EQ("GOOGLE_LONGLONG(-2147483648)", Int64ToString(kint32min)); + EXPECT_EQ("GOOGLE_LONGLONG(~0x7fffffffffffffff)", Int64ToString(kint64min)); + EXPECT_EQ("GOOGLE_LONGLONG(9223372036854775807)", Int64ToString(kint64max)); +} +#endif // !PROTOBUF_USE_DLLS + +TEST(GENERATED_MESSAGE_TEST_NAME, FloatingPointDefaults) { + const UNITTEST::TestExtremeDefaultValues& extreme_default = + UNITTEST::TestExtremeDefaultValues::default_instance(); + + EXPECT_EQ(0.0f, extreme_default.zero_float()); + EXPECT_EQ(1.0f, extreme_default.one_float()); + EXPECT_EQ(1.5f, extreme_default.small_float()); + EXPECT_EQ(-1.0f, extreme_default.negative_one_float()); + EXPECT_EQ(-1.5f, extreme_default.negative_float()); + EXPECT_EQ(2.0e8f, extreme_default.large_float()); + EXPECT_EQ(-8e-28f, extreme_default.small_negative_float()); + EXPECT_EQ(std::numeric_limits<double>::infinity(), + extreme_default.inf_double()); + EXPECT_EQ(-std::numeric_limits<double>::infinity(), + extreme_default.neg_inf_double()); + EXPECT_TRUE(extreme_default.nan_double() != extreme_default.nan_double()); + EXPECT_EQ(std::numeric_limits<float>::infinity(), + extreme_default.inf_float()); + EXPECT_EQ(-std::numeric_limits<float>::infinity(), + extreme_default.neg_inf_float()); + EXPECT_TRUE(extreme_default.nan_float() != extreme_default.nan_float()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, Trigraph) { + const UNITTEST::TestExtremeDefaultValues& extreme_default = + UNITTEST::TestExtremeDefaultValues::default_instance(); + + EXPECT_EQ("? ? ?? ?? ??? ?\?/ ?\?-", extreme_default.cpp_trigraph()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, ExtremeSmallIntegerDefault) { + const UNITTEST::TestExtremeDefaultValues& extreme_default = + UNITTEST::TestExtremeDefaultValues::default_instance(); + EXPECT_EQ(~0x7fffffff, kint32min); + EXPECT_EQ(GOOGLE_LONGLONG(~0x7fffffffffffffff), kint64min); + EXPECT_EQ(kint32min, extreme_default.really_small_int32()); + EXPECT_EQ(kint64min, extreme_default.really_small_int64()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, Accessors) { + // Set every field to a unique value then go back and check all those + // values. + UNITTEST::TestAllTypes message; + + TestUtil::SetAllFields(&message); + TestUtil::ExpectAllFieldsSet(message); + + TestUtil::ModifyRepeatedFields(&message); + TestUtil::ExpectRepeatedFieldsModified(message); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, MutableStringDefault) { + // mutable_foo() for a string should return a string initialized to its + // default value. + UNITTEST::TestAllTypes message; + + EXPECT_EQ("hello", *message.mutable_default_string()); + + // Note that the first time we call mutable_foo(), we get a newly-allocated + // string, but if we clear it and call it again, we get the same object again. + // We should verify that it has its default value in both cases. + message.set_default_string("blah"); + message.Clear(); + + EXPECT_EQ("hello", *message.mutable_default_string()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, StringDefaults) { + UNITTEST::TestExtremeDefaultValues message; + // Check if '\000' can be used in default string value. + EXPECT_EQ(string("hel\000lo", 6), message.string_with_zero()); + EXPECT_EQ(string("wor\000ld", 6), message.bytes_with_zero()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, ReleaseString) { + // Check that release_foo() starts out NULL, and gives us a value + // that we can delete after it's been set. + UNITTEST::TestAllTypes message; + + EXPECT_EQ(NULL, message.release_default_string()); + EXPECT_FALSE(message.has_default_string()); + EXPECT_EQ("hello", message.default_string()); + + message.set_default_string("blah"); + EXPECT_TRUE(message.has_default_string()); + std::unique_ptr<string> str(message.release_default_string()); + EXPECT_FALSE(message.has_default_string()); + ASSERT_TRUE(str != NULL); + EXPECT_EQ("blah", *str); + + EXPECT_EQ(NULL, message.release_default_string()); + EXPECT_FALSE(message.has_default_string()); + EXPECT_EQ("hello", message.default_string()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, ReleaseMessage) { + // Check that release_foo() starts out NULL, and gives us a value + // that we can delete after it's been set. + UNITTEST::TestAllTypes message; + + EXPECT_EQ(NULL, message.release_optional_nested_message()); + EXPECT_FALSE(message.has_optional_nested_message()); + + message.mutable_optional_nested_message()->set_bb(1); + std::unique_ptr<UNITTEST::TestAllTypes::NestedMessage> nest( + message.release_optional_nested_message()); + EXPECT_FALSE(message.has_optional_nested_message()); + ASSERT_TRUE(nest != NULL); + EXPECT_EQ(1, nest->bb()); + + EXPECT_EQ(NULL, message.release_optional_nested_message()); + EXPECT_FALSE(message.has_optional_nested_message()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, SetAllocatedString) { + // Check that set_allocated_foo() works for strings. + UNITTEST::TestAllTypes message; + + EXPECT_FALSE(message.has_optional_string()); + const string kHello("hello"); + message.set_optional_string(kHello); + EXPECT_TRUE(message.has_optional_string()); + + message.set_allocated_optional_string(NULL); + EXPECT_FALSE(message.has_optional_string()); + EXPECT_EQ("", message.optional_string()); + + message.set_allocated_optional_string(new string(kHello)); + EXPECT_TRUE(message.has_optional_string()); + EXPECT_EQ(kHello, message.optional_string()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, SetAllocatedMessage) { + // Check that set_allocated_foo() can be called in all cases. + UNITTEST::TestAllTypes message; + + EXPECT_FALSE(message.has_optional_nested_message()); + + message.mutable_optional_nested_message()->set_bb(1); + EXPECT_TRUE(message.has_optional_nested_message()); + + message.set_allocated_optional_nested_message(NULL); + EXPECT_FALSE(message.has_optional_nested_message()); + EXPECT_EQ(&UNITTEST::TestAllTypes::NestedMessage::default_instance(), + &message.optional_nested_message()); + + message.mutable_optional_nested_message()->set_bb(1); + UNITTEST::TestAllTypes::NestedMessage* nest = + message.release_optional_nested_message(); + ASSERT_TRUE(nest != NULL); + EXPECT_FALSE(message.has_optional_nested_message()); + + message.set_allocated_optional_nested_message(nest); + EXPECT_TRUE(message.has_optional_nested_message()); + EXPECT_EQ(1, message.optional_nested_message().bb()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, Clear) { + // Set every field to a unique value, clear the message, then check that + // it is cleared. + UNITTEST::TestAllTypes message; + + TestUtil::SetAllFields(&message); + message.Clear(); + TestUtil::ExpectClear(message); + + // Unlike with the defaults test, we do NOT expect that requesting embedded + // messages will return a pointer to the default instance. Instead, they + // should return the objects that were created when mutable_blah() was + // called. + EXPECT_NE(&UNITTEST::TestAllTypes::OptionalGroup::default_instance(), + &message.optionalgroup()); + EXPECT_NE(&UNITTEST::TestAllTypes::NestedMessage::default_instance(), + &message.optional_nested_message()); + EXPECT_NE(&UNITTEST::ForeignMessage::default_instance(), + &message.optional_foreign_message()); + EXPECT_NE(&UNITTEST_IMPORT::ImportMessage::default_instance(), + &message.optional_import_message()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, EmbeddedNullsInBytesCharStar) { + UNITTEST::TestAllTypes message; + + const char* value = "\0lalala\0\0"; + message.set_optional_bytes(value, 9); + ASSERT_EQ(9, message.optional_bytes().size()); + EXPECT_EQ(0, memcmp(value, message.optional_bytes().data(), 9)); + + message.add_repeated_bytes(value, 9); + ASSERT_EQ(9, message.repeated_bytes(0).size()); + EXPECT_EQ(0, memcmp(value, message.repeated_bytes(0).data(), 9)); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, ClearOneField) { + // Set every field to a unique value, then clear one value and insure that + // only that one value is cleared. + UNITTEST::TestAllTypes message; + + TestUtil::SetAllFields(&message); + int64 original_value = message.optional_int64(); + + // Clear the field and make sure it shows up as cleared. + message.clear_optional_int64(); + EXPECT_FALSE(message.has_optional_int64()); + EXPECT_EQ(0, message.optional_int64()); + + // Other adjacent fields should not be cleared. + EXPECT_TRUE(message.has_optional_int32()); + EXPECT_TRUE(message.has_optional_uint32()); + + // Make sure if we set it again, then all fields are set. + message.set_optional_int64(original_value); + TestUtil::ExpectAllFieldsSet(message); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, StringCharStarLength) { + // Verify that we can use a char*,length to set one of the string fields. + UNITTEST::TestAllTypes message; + message.set_optional_string("abcdef", 3); + EXPECT_EQ("abc", message.optional_string()); + + // Verify that we can use a char*,length to add to a repeated string field. + message.add_repeated_string("abcdef", 3); + EXPECT_EQ(1, message.repeated_string_size()); + EXPECT_EQ("abc", message.repeated_string(0)); + + // Verify that we can use a char*,length to set a repeated string field. + message.set_repeated_string(0, "wxyz", 2); + EXPECT_EQ("wx", message.repeated_string(0)); +} + +#if LANG_CXX11 +TEST(GENERATED_MESSAGE_TEST_NAME, StringMove) { + // Verify that we trigger the move behavior on a scalar setter. + protobuf_unittest_no_arena::TestAllTypes message; + { + string tmp(32, 'a'); + + const char* old_data = tmp.data(); + message.set_optional_string(std::move(tmp)); + const char* new_data = message.optional_string().data(); + + EXPECT_EQ(old_data, new_data); + EXPECT_EQ(string(32, 'a'), message.optional_string()); + + string tmp2(32, 'b'); + old_data = tmp2.data(); + message.set_optional_string(std::move(tmp2)); + new_data = message.optional_string().data(); + + EXPECT_EQ(old_data, new_data); + EXPECT_EQ(string(32, 'b'), message.optional_string()); + } + + // Verify that we trigger the move behavior on a oneof setter. + { + string tmp(32, 'a'); + + const char* old_data = tmp.data(); + message.set_oneof_string(std::move(tmp)); + const char* new_data = message.oneof_string().data(); + + EXPECT_EQ(old_data, new_data); + EXPECT_EQ(string(32, 'a'), message.oneof_string()); + + string tmp2(32, 'b'); + old_data = tmp2.data(); + message.set_oneof_string(std::move(tmp2)); + new_data = message.oneof_string().data(); + + EXPECT_EQ(old_data, new_data); + EXPECT_EQ(string(32, 'b'), message.oneof_string()); + } + + // Verify that we trigger the move behavior on a repeated setter. + { + string tmp(32, 'a'); + + const char* old_data = tmp.data(); + message.add_repeated_string(std::move(tmp)); + const char* new_data = message.repeated_string(0).data(); + + EXPECT_EQ(old_data, new_data); + EXPECT_EQ(string(32, 'a'), message.repeated_string(0)); + + string tmp2(32, 'b'); + old_data = tmp2.data(); + message.set_repeated_string(0, std::move(tmp2)); + new_data = message.repeated_string(0).data(); + + EXPECT_EQ(old_data, new_data); + EXPECT_EQ(string(32, 'b'), message.repeated_string(0)); + } +} +#endif + + +TEST(GENERATED_MESSAGE_TEST_NAME, CopyFrom) { + UNITTEST::TestAllTypes message1, message2; + + TestUtil::SetAllFields(&message1); + message2.CopyFrom(message1); + TestUtil::ExpectAllFieldsSet(message2); + + // Copying from self should be a no-op. + message2.CopyFrom(message2); + TestUtil::ExpectAllFieldsSet(message2); +} + + +TEST(GENERATED_MESSAGE_TEST_NAME, SwapWithEmpty) { + UNITTEST::TestAllTypes message1, message2; + TestUtil::SetAllFields(&message1); + + TestUtil::ExpectAllFieldsSet(message1); + TestUtil::ExpectClear(message2); + message1.Swap(&message2); + TestUtil::ExpectAllFieldsSet(message2); + TestUtil::ExpectClear(message1); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, SwapWithSelf) { + UNITTEST::TestAllTypes message; + TestUtil::SetAllFields(&message); + TestUtil::ExpectAllFieldsSet(message); + message.Swap(&message); + TestUtil::ExpectAllFieldsSet(message); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, SwapWithOther) { + UNITTEST::TestAllTypes message1, message2; + + message1.set_optional_int32(123); + message1.set_optional_string("abc"); + message1.mutable_optional_nested_message()->set_bb(1); + message1.set_optional_nested_enum(UNITTEST::TestAllTypes::FOO); + message1.add_repeated_int32(1); + message1.add_repeated_int32(2); + message1.add_repeated_string("a"); + message1.add_repeated_string("b"); + message1.add_repeated_nested_message()->set_bb(7); + message1.add_repeated_nested_message()->set_bb(8); + message1.add_repeated_nested_enum(UNITTEST::TestAllTypes::FOO); + message1.add_repeated_nested_enum(UNITTEST::TestAllTypes::BAR); + + message2.set_optional_int32(456); + message2.set_optional_string("def"); + message2.mutable_optional_nested_message()->set_bb(2); + message2.set_optional_nested_enum(UNITTEST::TestAllTypes::BAR); + message2.add_repeated_int32(3); + message2.add_repeated_string("c"); + message2.add_repeated_nested_message()->set_bb(9); + message2.add_repeated_nested_enum(UNITTEST::TestAllTypes::BAZ); + + message1.Swap(&message2); + + EXPECT_EQ(456, message1.optional_int32()); + EXPECT_EQ("def", message1.optional_string()); + EXPECT_EQ(2, message1.optional_nested_message().bb()); + EXPECT_EQ(UNITTEST::TestAllTypes::BAR, message1.optional_nested_enum()); + ASSERT_EQ(1, message1.repeated_int32_size()); + EXPECT_EQ(3, message1.repeated_int32(0)); + ASSERT_EQ(1, message1.repeated_string_size()); + EXPECT_EQ("c", message1.repeated_string(0)); + ASSERT_EQ(1, message1.repeated_nested_message_size()); + EXPECT_EQ(9, message1.repeated_nested_message(0).bb()); + ASSERT_EQ(1, message1.repeated_nested_enum_size()); + EXPECT_EQ(UNITTEST::TestAllTypes::BAZ, message1.repeated_nested_enum(0)); + + EXPECT_EQ(123, message2.optional_int32()); + EXPECT_EQ("abc", message2.optional_string()); + EXPECT_EQ(1, message2.optional_nested_message().bb()); + EXPECT_EQ(UNITTEST::TestAllTypes::FOO, message2.optional_nested_enum()); + ASSERT_EQ(2, message2.repeated_int32_size()); + EXPECT_EQ(1, message2.repeated_int32(0)); + EXPECT_EQ(2, message2.repeated_int32(1)); + ASSERT_EQ(2, message2.repeated_string_size()); + EXPECT_EQ("a", message2.repeated_string(0)); + EXPECT_EQ("b", message2.repeated_string(1)); + ASSERT_EQ(2, message2.repeated_nested_message_size()); + EXPECT_EQ(7, message2.repeated_nested_message(0).bb()); + EXPECT_EQ(8, message2.repeated_nested_message(1).bb()); + ASSERT_EQ(2, message2.repeated_nested_enum_size()); + EXPECT_EQ(UNITTEST::TestAllTypes::FOO, message2.repeated_nested_enum(0)); + EXPECT_EQ(UNITTEST::TestAllTypes::BAR, message2.repeated_nested_enum(1)); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, ADLSwap) { + UNITTEST::TestAllTypes message1, message2; + TestUtil::SetAllFields(&message1); + + // Note the address of one of the repeated fields, to verify it was swapped + // rather than copied. + const int32* addr = &message1.repeated_int32().Get(0); + + using std::swap; + swap(message1, message2); + + TestUtil::ExpectAllFieldsSet(message2); + TestUtil::ExpectClear(message1); + + EXPECT_EQ(addr, &message2.repeated_int32().Get(0)); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, CopyConstructor) { + // All set. + { + UNITTEST::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + + UNITTEST::TestAllTypes message2(message1); + TestUtil::ExpectAllFieldsSet(message2); + } + + // None set. + { + UNITTEST::TestAllTypes message1; + UNITTEST::TestAllTypes message2(message1); + + EXPECT_FALSE(message1.has_optional_string()); + EXPECT_FALSE(message2.has_optional_string()); + EXPECT_EQ(message1.optional_string(), message2.optional_string()); + + EXPECT_FALSE(message1.has_optional_bytes()); + EXPECT_FALSE(message2.has_optional_bytes()); + EXPECT_EQ(message1.optional_bytes(), message2.optional_bytes()); + + EXPECT_FALSE(message1.has_optional_nested_message()); + EXPECT_FALSE(message2.has_optional_nested_message()); + EXPECT_EQ(&message1.optional_nested_message(), + &message2.optional_nested_message()); + + EXPECT_FALSE(message1.has_optional_foreign_message()); + EXPECT_FALSE(message2.has_optional_foreign_message()); + EXPECT_EQ(&message1.optional_foreign_message(), + &message2.optional_foreign_message()); + + EXPECT_FALSE(message1.has_optional_import_message()); + EXPECT_FALSE(message2.has_optional_import_message()); + EXPECT_EQ(&message1.optional_import_message(), + &message2.optional_import_message()); + + EXPECT_FALSE(message1.has_optional_public_import_message()); + EXPECT_FALSE(message2.has_optional_public_import_message()); + EXPECT_EQ(&message1.optional_public_import_message(), + &message2.optional_public_import_message()); + + EXPECT_FALSE(message1.has_optional_lazy_message()); + EXPECT_FALSE(message2.has_optional_lazy_message()); + EXPECT_EQ(&message1.optional_lazy_message(), + &message2.optional_lazy_message()); + } +} + +TEST(GENERATED_MESSAGE_TEST_NAME, CopyConstructorWithArenas) { + Arena arena; + UNITTEST::TestAllTypes* message1 = + Arena::CreateMessage<UNITTEST::TestAllTypes>(&arena); + TestUtil::SetAllFields(message1); + + UNITTEST::TestAllTypes message2_stack(*message1); + TestUtil::ExpectAllFieldsSet(message2_stack); + + std::unique_ptr<UNITTEST::TestAllTypes> message2_heap( + new UNITTEST::TestAllTypes(*message1)); + TestUtil::ExpectAllFieldsSet(*message2_heap); + + arena.Reset(); + + // Verify that the copies are still intact. + TestUtil::ExpectAllFieldsSet(message2_stack); + TestUtil::ExpectAllFieldsSet(*message2_heap); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, CopyAssignmentOperator) { + UNITTEST::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + + UNITTEST::TestAllTypes message2; + message2 = message1; + TestUtil::ExpectAllFieldsSet(message2); + + // Make sure that self-assignment does something sane. + message2.operator=(message2); + TestUtil::ExpectAllFieldsSet(message2); +} + +#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \ + !defined(GOOGLE_PROTOBUF_NO_RTTI) +TEST(GENERATED_MESSAGE_TEST_NAME, UpcastCopyFrom) { + // Test the CopyFrom method that takes in the generic const Message& + // parameter. + UNITTEST::TestAllTypes message1, message2; + + TestUtil::SetAllFields(&message1); + + const Message* source = implicit_cast<const Message*>(&message1); + message2.CopyFrom(*source); + + TestUtil::ExpectAllFieldsSet(message2); +} +#endif + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +TEST(GENERATED_MESSAGE_TEST_NAME, DynamicMessageCopyFrom) { + // Test copying from a DynamicMessage, which must fall back to using + // reflection. + UNITTEST::TestAllTypes message2; + + // Construct a new version of the dynamic message via the factory. + DynamicMessageFactory factory; + std::unique_ptr<Message> message1; + message1.reset(factory.GetPrototype( + UNITTEST::TestAllTypes::descriptor())->New()); + + TestUtil::ReflectionTester reflection_tester( + UNITTEST::TestAllTypes::descriptor()); + reflection_tester.SetAllFieldsViaReflection(message1.get()); + + message2.CopyFrom(*message1); + + TestUtil::ExpectAllFieldsSet(message2); +} + +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS + +TEST(GENERATED_MESSAGE_TEST_NAME, NonEmptyMergeFrom) { + // Test merging with a non-empty message. Code is a modified form + // of that found in google/protobuf/reflection_ops_unittest.cc. + UNITTEST::TestAllTypes message1, message2; + + TestUtil::SetAllFields(&message1); + + // This field will test merging into an empty spot. + message2.set_optional_int32(message1.optional_int32()); + message1.clear_optional_int32(); + + // This tests overwriting. + message2.set_optional_string(message1.optional_string()); + message1.set_optional_string("something else"); + + // This tests concatenating. + message2.add_repeated_int32(message1.repeated_int32(1)); + int32 i = message1.repeated_int32(0); + message1.clear_repeated_int32(); + message1.add_repeated_int32(i); + + message1.MergeFrom(message2); + + TestUtil::ExpectAllFieldsSet(message1); +} + + +// Test the generated SerializeWithCachedSizesToArray(), +TEST(GENERATED_MESSAGE_TEST_NAME, SerializationToArray) { + UNITTEST::TestAllTypes message1, message2; + string data; + TestUtil::SetAllFields(&message1); + int size = message1.ByteSizeLong(); + data.resize(size); + uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); + uint8* end = message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(size, end - start); + EXPECT_TRUE(message2.ParseFromString(data)); + TestUtil::ExpectAllFieldsSet(message2); + +} + +TEST(GENERATED_MESSAGE_TEST_NAME, PackedFieldsSerializationToArray) { + UNITTEST::TestPackedTypes packed_message1, packed_message2; + string packed_data; + TestUtil::SetPackedFields(&packed_message1); + int packed_size = packed_message1.ByteSizeLong(); + packed_data.resize(packed_size); + uint8* start = reinterpret_cast<uint8*>(string_as_array(&packed_data)); + uint8* end = packed_message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(packed_size, end - start); + EXPECT_TRUE(packed_message2.ParseFromString(packed_data)); + TestUtil::ExpectPackedFieldsSet(packed_message2); +} + +// Test the generated SerializeWithCachedSizes() by forcing the buffer to write +// one byte at a time. +TEST(GENERATED_MESSAGE_TEST_NAME, SerializationToStream) { + UNITTEST::TestAllTypes message1, message2; + TestUtil::SetAllFields(&message1); + int size = message1.ByteSizeLong(); + string data; + data.resize(size); + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + EXPECT_TRUE(message2.ParseFromString(data)); + TestUtil::ExpectAllFieldsSet(message2); + +} + +TEST(GENERATED_MESSAGE_TEST_NAME, PackedFieldsSerializationToStream) { + UNITTEST::TestPackedTypes message1, message2; + TestUtil::SetPackedFields(&message1); + int size = message1.ByteSizeLong(); + string data; + data.resize(size); + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + EXPECT_TRUE(message2.ParseFromString(data)); + TestUtil::ExpectPackedFieldsSet(message2); +} + + +TEST(GENERATED_MESSAGE_TEST_NAME, Required) { + // Test that IsInitialized() returns false if required fields are missing. + UNITTEST::TestRequired message; + + EXPECT_FALSE(message.IsInitialized()); + message.set_a(1); + EXPECT_FALSE(message.IsInitialized()); + message.set_b(2); + EXPECT_FALSE(message.IsInitialized()); + message.set_c(3); + EXPECT_TRUE(message.IsInitialized()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, RequiredForeign) { + // Test that IsInitialized() returns false if required fields in nested + // messages are missing. + UNITTEST::TestRequiredForeign message; + + EXPECT_TRUE(message.IsInitialized()); + + message.mutable_optional_message(); + EXPECT_FALSE(message.IsInitialized()); + + message.mutable_optional_message()->set_a(1); + message.mutable_optional_message()->set_b(2); + message.mutable_optional_message()->set_c(3); + EXPECT_TRUE(message.IsInitialized()); + + message.add_repeated_message(); + EXPECT_FALSE(message.IsInitialized()); + + message.mutable_repeated_message(0)->set_a(1); + message.mutable_repeated_message(0)->set_b(2); + message.mutable_repeated_message(0)->set_c(3); + EXPECT_TRUE(message.IsInitialized()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, ForeignNested) { + // Test that TestAllTypes::NestedMessage can be embedded directly into + // another message. + UNITTEST::TestForeignNested message; + + // If this compiles and runs without crashing, it must work. We have + // nothing more to test. + UNITTEST::TestAllTypes::NestedMessage* nested = + message.mutable_foreign_nested(); + nested->set_bb(1); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, ReallyLargeTagNumber) { + // Test that really large tag numbers don't break anything. + UNITTEST::TestReallyLargeTagNumber message1, message2; + string data; + + // For the most part, if this compiles and runs then we're probably good. + // (The most likely cause for failure would be if something were attempting + // to allocate a lookup table of some sort using tag numbers as the index.) + // We'll try serializing just for fun. + message1.set_a(1234); + message1.set_bb(5678); + message1.SerializeToString(&data); + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(1234, message2.a()); + EXPECT_EQ(5678, message2.bb()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, MutualRecursion) { + // Test that mutually-recursive message types work. + UNITTEST::TestMutualRecursionA message; + UNITTEST::TestMutualRecursionA* nested = message.mutable_bb()->mutable_a(); + UNITTEST::TestMutualRecursionA* nested2 = nested->mutable_bb()->mutable_a(); + + // Again, if the above compiles and runs, that's all we really have to + // test, but just for run we'll check that the system didn't somehow come + // up with a pointer loop... + EXPECT_NE(&message, nested); + EXPECT_NE(&message, nested2); + EXPECT_NE(nested, nested2); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, CamelCaseFieldNames) { + // This test is mainly checking that the following compiles, which verifies + // that the field names were coerced to lower-case. + // + // Protocol buffers standard style is to use lowercase-with-underscores for + // field names. Some old proto1 .protos unfortunately used camel-case field + // names. In proto1, these names were forced to lower-case. So, we do the + // same thing in proto2. + + UNITTEST::TestCamelCaseFieldNames message; + + message.set_primitivefield(2); + message.set_stringfield("foo"); + message.set_enumfield(UNITTEST::FOREIGN_FOO); + message.mutable_messagefield()->set_c(6); + + message.add_repeatedprimitivefield(8); + message.add_repeatedstringfield("qux"); + message.add_repeatedenumfield(UNITTEST::FOREIGN_BAR); + message.add_repeatedmessagefield()->set_c(15); + + EXPECT_EQ(2, message.primitivefield()); + EXPECT_EQ("foo", message.stringfield()); + EXPECT_EQ(UNITTEST::FOREIGN_FOO, message.enumfield()); + EXPECT_EQ(6, message.messagefield().c()); + + EXPECT_EQ(8, message.repeatedprimitivefield(0)); + EXPECT_EQ("qux", message.repeatedstringfield(0)); + EXPECT_EQ(UNITTEST::FOREIGN_BAR, message.repeatedenumfield(0)); + EXPECT_EQ(15, message.repeatedmessagefield(0).c()); +} + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +TEST(GENERATED_MESSAGE_TEST_NAME, TestOptimizedForSize) { + // We rely on the tests in reflection_ops_unittest and wire_format_unittest + // to really test that reflection-based methods work. Here we are mostly + // just making sure that TestOptimizedForSize actually builds and seems to + // function. + + UNITTEST::TestOptimizedForSize message, message2; + message.set_i(1); + message.mutable_msg()->set_c(2); + message2.CopyFrom(message); + EXPECT_EQ(1, message2.i()); + EXPECT_EQ(2, message2.msg().c()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, TestEmbedOptimizedForSize) { + // Verifies that something optimized for speed can contain something optimized + // for size. + + UNITTEST::TestEmbedOptimizedForSize message, message2; + message.mutable_optional_message()->set_i(1); + message.add_repeated_message()->mutable_msg()->set_c(2); + string data; + message.SerializeToString(&data); + ASSERT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(1, message2.optional_message().i()); + EXPECT_EQ(2, message2.repeated_message(0).msg().c()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, TestSpaceUsed) { + UNITTEST::TestAllTypes message1; + // sizeof provides a lower bound on SpaceUsedLong(). + EXPECT_LE(sizeof(UNITTEST::TestAllTypes), message1.SpaceUsedLong()); + const size_t empty_message_size = message1.SpaceUsedLong(); + + // Setting primitive types shouldn't affect the space used. + message1.set_optional_int32(123); + message1.set_optional_int64(12345); + message1.set_optional_uint32(123); + message1.set_optional_uint64(12345); + EXPECT_EQ(empty_message_size, message1.SpaceUsedLong()); + + // On some STL implementations, setting the string to a small value should + // only increase SpaceUsedLong() by the size of a string object, though this + // is not true everywhere. + message1.set_optional_string("abc"); + EXPECT_LE(empty_message_size + message1.optional_string().size(), + message1.SpaceUsedLong()); + + // Setting a string to a value larger than the string object itself should + // increase SpaceUsedLong(), because it cannot store the value internally. + message1.set_optional_string(string(sizeof(string) + 1, 'x')); + int min_expected_increase = message1.optional_string().capacity(); + EXPECT_LE(empty_message_size + min_expected_increase, + message1.SpaceUsedLong()); + + size_t previous_size = message1.SpaceUsedLong(); + // Adding an optional message should increase the size by the size of the + // nested message type. NestedMessage is simple enough (1 int field) that it + // is equal to sizeof(NestedMessage) + message1.mutable_optional_nested_message(); + ASSERT_EQ(sizeof(UNITTEST::TestAllTypes::NestedMessage), + message1.optional_nested_message().SpaceUsedLong()); + EXPECT_EQ(previous_size + + sizeof(UNITTEST::TestAllTypes::NestedMessage), + message1.SpaceUsedLong()); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, TestOneofSpaceUsed) { + UNITTEST::TestOneof2 message1; + EXPECT_LE(sizeof(UNITTEST::TestOneof2), message1.SpaceUsedLong()); + + const size_t empty_message_size = message1.SpaceUsedLong(); + // Setting primitive types shouldn't affect the space used. + message1.set_foo_int(123); + message1.set_bar_int(12345); + EXPECT_EQ(empty_message_size, message1.SpaceUsedLong()); + + // Setting a string in oneof to a small value should only increase + // SpaceUsedLong() by the size of a string object. + message1.set_foo_string("abc"); + EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsedLong()); + + // Setting a string in oneof to a value larger than the string object itself + // should increase SpaceUsedLong(), because it cannot store the value + // internally. + message1.set_foo_string(string(sizeof(string) + 1, 'x')); + int min_expected_increase = message1.foo_string().capacity() + + sizeof(string); + EXPECT_LE(empty_message_size + min_expected_increase, + message1.SpaceUsedLong()); + + // Setting a message in oneof should delete the other fields and increase the + // size by the size of the nested message type. NestedMessage is simple enough + // that it is equal to sizeof(NestedMessage) + message1.mutable_foo_message(); + ASSERT_EQ(sizeof(UNITTEST::TestOneof2::NestedMessage), + message1.foo_message().SpaceUsedLong()); + EXPECT_EQ(empty_message_size + + sizeof(UNITTEST::TestOneof2::NestedMessage), + message1.SpaceUsedLong()); +} + +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS + + +TEST(GENERATED_MESSAGE_TEST_NAME, FieldConstantValues) { + UNITTEST::TestRequired message; + EXPECT_EQ(UNITTEST::TestAllTypes_NestedMessage::kBbFieldNumber, 1); + EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalInt32FieldNumber, 1); + EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalgroupFieldNumber, 16); + EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalNestedMessageFieldNumber, 18); + EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalNestedEnumFieldNumber, 21); + EXPECT_EQ(UNITTEST::TestAllTypes::kRepeatedInt32FieldNumber, 31); + EXPECT_EQ(UNITTEST::TestAllTypes::kRepeatedgroupFieldNumber, 46); + EXPECT_EQ(UNITTEST::TestAllTypes::kRepeatedNestedMessageFieldNumber, 48); + EXPECT_EQ(UNITTEST::TestAllTypes::kRepeatedNestedEnumFieldNumber, 51); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, ExtensionConstantValues) { + EXPECT_EQ(UNITTEST::TestRequired::kSingleFieldNumber, 1000); + EXPECT_EQ(UNITTEST::TestRequired::kMultiFieldNumber, 1001); + EXPECT_EQ(UNITTEST::kOptionalInt32ExtensionFieldNumber, 1); + EXPECT_EQ(UNITTEST::kOptionalgroupExtensionFieldNumber, 16); + EXPECT_EQ(UNITTEST::kOptionalNestedMessageExtensionFieldNumber, 18); + EXPECT_EQ(UNITTEST::kOptionalNestedEnumExtensionFieldNumber, 21); + EXPECT_EQ(UNITTEST::kRepeatedInt32ExtensionFieldNumber, 31); + EXPECT_EQ(UNITTEST::kRepeatedgroupExtensionFieldNumber, 46); + EXPECT_EQ(UNITTEST::kRepeatedNestedMessageExtensionFieldNumber, 48); + EXPECT_EQ(UNITTEST::kRepeatedNestedEnumExtensionFieldNumber, 51); +} + +TEST(GENERATED_MESSAGE_TEST_NAME, ParseFromTruncated) { + const string long_string = string(128, 'q'); + FileDescriptorProto p; + p.add_extension()->set_name(long_string); + const string msg = p.SerializeAsString(); + int successful_count = 0; + for (int i = 0; i <= msg.size(); i++) { + if (p.ParseFromArray(msg.c_str(), i)) { + ++successful_count; + } + } + // We don't really care about how often we succeeded. + // As long as we didn't crash, we're happy. + EXPECT_GE(successful_count, 1); +} + +// =================================================================== + +TEST(GENERATED_ENUM_TEST_NAME, EnumValuesAsSwitchCases) { + // Test that our nested enum values can be used as switch cases. This test + // doesn't actually do anything, the proof that it works is that it + // compiles. + int i =0; + UNITTEST::TestAllTypes::NestedEnum a = UNITTEST::TestAllTypes::BAR; + switch (a) { + case UNITTEST::TestAllTypes::FOO: + i = 1; + break; + case UNITTEST::TestAllTypes::BAR: + i = 2; + break; + case UNITTEST::TestAllTypes::BAZ: + i = 3; + break; + case UNITTEST::TestAllTypes::NEG: + i = -1; + break; + // no default case: We want to make sure the compiler recognizes that + // all cases are covered. (GCC warns if you do not cover all cases of + // an enum in a switch.) + } + + // Token check just for fun. + EXPECT_EQ(2, i); +} + +TEST(GENERATED_ENUM_TEST_NAME, IsValidValue) { + // Test enum IsValidValue. + EXPECT_TRUE(UNITTEST::TestAllTypes::NestedEnum_IsValid(1)); + EXPECT_TRUE(UNITTEST::TestAllTypes::NestedEnum_IsValid(2)); + EXPECT_TRUE(UNITTEST::TestAllTypes::NestedEnum_IsValid(3)); + + EXPECT_FALSE(UNITTEST::TestAllTypes::NestedEnum_IsValid(0)); + EXPECT_FALSE(UNITTEST::TestAllTypes::NestedEnum_IsValid(4)); + + // Make sure it also works when there are dups. + EXPECT_TRUE(UNITTEST::TestEnumWithDupValue_IsValid(1)); + EXPECT_TRUE(UNITTEST::TestEnumWithDupValue_IsValid(2)); + EXPECT_TRUE(UNITTEST::TestEnumWithDupValue_IsValid(3)); + + EXPECT_FALSE(UNITTEST::TestEnumWithDupValue_IsValid(0)); + EXPECT_FALSE(UNITTEST::TestEnumWithDupValue_IsValid(4)); +} + +TEST(GENERATED_ENUM_TEST_NAME, MinAndMax) { + EXPECT_EQ(UNITTEST::TestAllTypes::NEG, + UNITTEST::TestAllTypes::NestedEnum_MIN); + EXPECT_EQ(UNITTEST::TestAllTypes::BAZ, + UNITTEST::TestAllTypes::NestedEnum_MAX); + EXPECT_EQ(4, UNITTEST::TestAllTypes::NestedEnum_ARRAYSIZE); + + EXPECT_EQ(UNITTEST::FOREIGN_FOO, UNITTEST::ForeignEnum_MIN); + EXPECT_EQ(UNITTEST::FOREIGN_BAZ, UNITTEST::ForeignEnum_MAX); + EXPECT_EQ(7, UNITTEST::ForeignEnum_ARRAYSIZE); + + EXPECT_EQ(1, UNITTEST::TestEnumWithDupValue_MIN); + EXPECT_EQ(3, UNITTEST::TestEnumWithDupValue_MAX); + EXPECT_EQ(4, UNITTEST::TestEnumWithDupValue_ARRAYSIZE); + + EXPECT_EQ(UNITTEST::SPARSE_E, UNITTEST::TestSparseEnum_MIN); + EXPECT_EQ(UNITTEST::SPARSE_C, UNITTEST::TestSparseEnum_MAX); + EXPECT_EQ(12589235, UNITTEST::TestSparseEnum_ARRAYSIZE); + + // Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE. + void* null_pointer = 0; // NULL may be integer-type, not pointer-type. + EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_MIN); + EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_MAX); + EXPECT_NE(null_pointer, &UNITTEST::TestAllTypes::NestedEnum_ARRAYSIZE); + + EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_MIN); + EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_MAX); + EXPECT_NE(null_pointer, &UNITTEST::ForeignEnum_ARRAYSIZE); + + // Make sure we can use _MIN and _MAX as switch cases. + switch (UNITTEST::SPARSE_A) { + case UNITTEST::TestSparseEnum_MIN: + case UNITTEST::TestSparseEnum_MAX: + break; + default: + break; + } +} + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +TEST(GENERATED_ENUM_TEST_NAME, Name) { + // "Names" in the presence of dup values are a bit arbitrary. + EXPECT_EQ("FOO1", UNITTEST::TestEnumWithDupValue_Name(UNITTEST::FOO1)); + EXPECT_EQ("FOO1", UNITTEST::TestEnumWithDupValue_Name(UNITTEST::FOO2)); + + EXPECT_EQ("SPARSE_A", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_A)); + EXPECT_EQ("SPARSE_B", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_B)); + EXPECT_EQ("SPARSE_C", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_C)); + EXPECT_EQ("SPARSE_D", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_D)); + EXPECT_EQ("SPARSE_E", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_E)); + EXPECT_EQ("SPARSE_F", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_F)); + EXPECT_EQ("SPARSE_G", UNITTEST::TestSparseEnum_Name(UNITTEST::SPARSE_G)); +} + +TEST(GENERATED_ENUM_TEST_NAME, Parse) { + UNITTEST::TestEnumWithDupValue dup_value = UNITTEST::FOO1; + EXPECT_TRUE(UNITTEST::TestEnumWithDupValue_Parse("FOO1", &dup_value)); + EXPECT_EQ(UNITTEST::FOO1, dup_value); + EXPECT_TRUE(UNITTEST::TestEnumWithDupValue_Parse("FOO2", &dup_value)); + EXPECT_EQ(UNITTEST::FOO2, dup_value); + EXPECT_FALSE(UNITTEST::TestEnumWithDupValue_Parse("FOO", &dup_value)); +} + +TEST(GENERATED_ENUM_TEST_NAME, GetEnumDescriptor) { + EXPECT_EQ(UNITTEST::TestAllTypes::NestedEnum_descriptor(), + GetEnumDescriptor<UNITTEST::TestAllTypes::NestedEnum>()); + EXPECT_EQ(UNITTEST::ForeignEnum_descriptor(), + GetEnumDescriptor<UNITTEST::ForeignEnum>()); + EXPECT_EQ(UNITTEST::TestEnumWithDupValue_descriptor(), + GetEnumDescriptor<UNITTEST::TestEnumWithDupValue>()); + EXPECT_EQ(UNITTEST::TestSparseEnum_descriptor(), + GetEnumDescriptor<UNITTEST::TestSparseEnum>()); +} + +enum NonProtoEnum { + kFoo = 1, +}; + +TEST(GENERATED_ENUM_TEST_NAME, IsProtoEnumTypeTrait) { + EXPECT_TRUE(is_proto_enum<UNITTEST::TestAllTypes::NestedEnum>::value); + EXPECT_TRUE(is_proto_enum<UNITTEST::ForeignEnum>::value); + EXPECT_TRUE(is_proto_enum<UNITTEST::TestEnumWithDupValue>::value); + EXPECT_TRUE(is_proto_enum<UNITTEST::TestSparseEnum>::value); + + EXPECT_FALSE(is_proto_enum<int>::value); + EXPECT_FALSE(is_proto_enum<NonProtoEnum>::value); +} + +#endif // PROTOBUF_TEST_NO_DESCRIPTORS + +// =================================================================== + +#ifndef PROTOBUF_TEST_NO_DESCRIPTORS + +// Support code for testing services. +class GENERATED_SERVICE_TEST_NAME : public testing::Test { + protected: + class MockTestService : public UNITTEST::TestService { + public: + MockTestService() + : called_(false), + method_(""), + controller_(NULL), + request_(NULL), + response_(NULL), + done_(NULL) {} + + ~MockTestService() {} + + void Reset() { called_ = false; } + + // implements TestService ---------------------------------------- + + void Foo(RpcController* controller, + const UNITTEST::FooRequest* request, + UNITTEST::FooResponse* response, + Closure* done) { + ASSERT_FALSE(called_); + called_ = true; + method_ = "Foo"; + controller_ = controller; + request_ = request; + response_ = response; + done_ = done; + } + + void Bar(RpcController* controller, + const UNITTEST::BarRequest* request, + UNITTEST::BarResponse* response, + Closure* done) { + ASSERT_FALSE(called_); + called_ = true; + method_ = "Bar"; + controller_ = controller; + request_ = request; + response_ = response; + done_ = done; + } + + // --------------------------------------------------------------- + + bool called_; + string method_; + RpcController* controller_; + const Message* request_; + Message* response_; + Closure* done_; + }; + + class MockRpcChannel : public RpcChannel { + public: + MockRpcChannel() + : called_(false), + method_(NULL), + controller_(NULL), + request_(NULL), + response_(NULL), + done_(NULL), + destroyed_(NULL) {} + + ~MockRpcChannel() { + if (destroyed_ != NULL) *destroyed_ = true; + } + + void Reset() { called_ = false; } + + // implements TestService ---------------------------------------- + + void CallMethod(const MethodDescriptor* method, + RpcController* controller, + const Message* request, + Message* response, + Closure* done) { + ASSERT_FALSE(called_); + called_ = true; + method_ = method; + controller_ = controller; + request_ = request; + response_ = response; + done_ = done; + } + + // --------------------------------------------------------------- + + bool called_; + const MethodDescriptor* method_; + RpcController* controller_; + const Message* request_; + Message* response_; + Closure* done_; + bool* destroyed_; + }; + + class MockController : public RpcController { + public: + void Reset() { + ADD_FAILURE() << "Reset() not expected during this test."; + } + bool Failed() const { + ADD_FAILURE() << "Failed() not expected during this test."; + return false; + } + string ErrorText() const { + ADD_FAILURE() << "ErrorText() not expected during this test."; + return ""; + } + void StartCancel() { + ADD_FAILURE() << "StartCancel() not expected during this test."; + } + void SetFailed(const string& reason) { + ADD_FAILURE() << "SetFailed() not expected during this test."; + } + bool IsCanceled() const { + ADD_FAILURE() << "IsCanceled() not expected during this test."; + return false; + } + void NotifyOnCancel(Closure* callback) { + ADD_FAILURE() << "NotifyOnCancel() not expected during this test."; + } + }; + + GENERATED_SERVICE_TEST_NAME() + : descriptor_(UNITTEST::TestService::descriptor()), + foo_(descriptor_->FindMethodByName("Foo")), + bar_(descriptor_->FindMethodByName("Bar")), + stub_(&mock_channel_), + done_(::google::protobuf::NewPermanentCallback(&DoNothing)) {} + + virtual void SetUp() { + ASSERT_TRUE(foo_ != NULL); + ASSERT_TRUE(bar_ != NULL); + } + + const ServiceDescriptor* descriptor_; + const MethodDescriptor* foo_; + const MethodDescriptor* bar_; + + MockTestService mock_service_; + MockController mock_controller_; + + MockRpcChannel mock_channel_; + UNITTEST::TestService::Stub stub_; + + // Just so we don't have to re-define these with every test. + UNITTEST::FooRequest foo_request_; + UNITTEST::FooResponse foo_response_; + UNITTEST::BarRequest bar_request_; + UNITTEST::BarResponse bar_response_; + std::unique_ptr<Closure> done_; +}; + +TEST_F(GENERATED_SERVICE_TEST_NAME, GetDescriptor) { + // Test that GetDescriptor() works. + + EXPECT_EQ(descriptor_, mock_service_.GetDescriptor()); +} + +TEST_F(GENERATED_SERVICE_TEST_NAME, GetChannel) { + EXPECT_EQ(&mock_channel_, stub_.channel()); +} + +TEST_F(GENERATED_SERVICE_TEST_NAME, OwnsChannel) { + MockRpcChannel* channel = new MockRpcChannel; + bool destroyed = false; + channel->destroyed_ = &destroyed; + + { + UNITTEST::TestService::Stub owning_stub(channel, + Service::STUB_OWNS_CHANNEL); + EXPECT_FALSE(destroyed); + } + + EXPECT_TRUE(destroyed); +} + +TEST_F(GENERATED_SERVICE_TEST_NAME, CallMethod) { + // Test that CallMethod() works. + + // Call Foo() via CallMethod(). + mock_service_.CallMethod(foo_, &mock_controller_, + &foo_request_, &foo_response_, done_.get()); + + ASSERT_TRUE(mock_service_.called_); + + EXPECT_EQ("Foo" , mock_service_.method_ ); + EXPECT_EQ(&mock_controller_, mock_service_.controller_); + EXPECT_EQ(&foo_request_ , mock_service_.request_ ); + EXPECT_EQ(&foo_response_ , mock_service_.response_ ); + EXPECT_EQ(done_.get() , mock_service_.done_ ); + + // Try again, but call Bar() instead. + mock_service_.Reset(); + mock_service_.CallMethod(bar_, &mock_controller_, + &bar_request_, &bar_response_, done_.get()); + + ASSERT_TRUE(mock_service_.called_); + EXPECT_EQ("Bar", mock_service_.method_); +} + +TEST_F(GENERATED_SERVICE_TEST_NAME, CallMethodTypeFailure) { + // Verify death if we call Foo() with Bar's message types. + +#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet + EXPECT_DEBUG_DEATH( + mock_service_.CallMethod(foo_, &mock_controller_, + &foo_request_, &bar_response_, done_.get()), + "dynamic_cast"); + + mock_service_.Reset(); + EXPECT_DEBUG_DEATH( + mock_service_.CallMethod(foo_, &mock_controller_, + &bar_request_, &foo_response_, done_.get()), + "dynamic_cast"); +#endif // PROTOBUF_HAS_DEATH_TEST +} + +TEST_F(GENERATED_SERVICE_TEST_NAME, GetPrototypes) { + // Test Get{Request,Response}Prototype() methods. + + EXPECT_EQ(&UNITTEST::FooRequest::default_instance(), + &mock_service_.GetRequestPrototype(foo_)); + EXPECT_EQ(&UNITTEST::BarRequest::default_instance(), + &mock_service_.GetRequestPrototype(bar_)); + + EXPECT_EQ(&UNITTEST::FooResponse::default_instance(), + &mock_service_.GetResponsePrototype(foo_)); + EXPECT_EQ(&UNITTEST::BarResponse::default_instance(), + &mock_service_.GetResponsePrototype(bar_)); +} + +TEST_F(GENERATED_SERVICE_TEST_NAME, Stub) { + // Test that the stub class works. + + // Call Foo() via the stub. + stub_.Foo(&mock_controller_, &foo_request_, &foo_response_, done_.get()); + + ASSERT_TRUE(mock_channel_.called_); + + EXPECT_EQ(foo_ , mock_channel_.method_ ); + EXPECT_EQ(&mock_controller_, mock_channel_.controller_); + EXPECT_EQ(&foo_request_ , mock_channel_.request_ ); + EXPECT_EQ(&foo_response_ , mock_channel_.response_ ); + EXPECT_EQ(done_.get() , mock_channel_.done_ ); + + // Call Bar() via the stub. + mock_channel_.Reset(); + stub_.Bar(&mock_controller_, &bar_request_, &bar_response_, done_.get()); + + ASSERT_TRUE(mock_channel_.called_); + EXPECT_EQ(bar_, mock_channel_.method_); +} + +TEST_F(GENERATED_SERVICE_TEST_NAME, NotImplemented) { + // Test that failing to implement a method of a service causes it to fail + // with a "not implemented" error message. + + // A service which doesn't implement any methods. + class UnimplementedService : public UNITTEST::TestService { + public: + UnimplementedService() {} + }; + + UnimplementedService unimplemented_service; + + // And a controller which expects to get a "not implemented" error. + class ExpectUnimplementedController : public MockController { + public: + ExpectUnimplementedController() : called_(false) {} + + void SetFailed(const string& reason) { + EXPECT_FALSE(called_); + called_ = true; + EXPECT_EQ("Method Foo() not implemented.", reason); + } + + bool called_; + }; + + ExpectUnimplementedController controller; + + // Call Foo. + unimplemented_service.Foo(&controller, &foo_request_, &foo_response_, + done_.get()); + + EXPECT_TRUE(controller.called_); +} + +// =================================================================== + +class OneofTest : public testing::Test { + protected: + virtual void SetUp() { + } + + void ExpectEnumCasesWork(const UNITTEST::TestOneof2 &message) { + switch (message.foo_case()) { + case UNITTEST::TestOneof2::kFooInt: + EXPECT_TRUE(message.has_foo_int()); + break; + case UNITTEST::TestOneof2::kFooString: + EXPECT_TRUE(message.has_foo_string()); + break; + case UNITTEST::TestOneof2::kFooCord: + EXPECT_TRUE(message.has_foo_cord()); + break; + case UNITTEST::TestOneof2::kFooStringPiece: + EXPECT_TRUE(message.has_foo_string_piece()); + break; + case UNITTEST::TestOneof2::kFooBytes: + EXPECT_TRUE(message.has_foo_bytes()); + break; + case UNITTEST::TestOneof2::kFooEnum: + EXPECT_TRUE(message.has_foo_enum()); + break; + case UNITTEST::TestOneof2::kFooMessage: + EXPECT_TRUE(message.has_foo_message()); + break; + case UNITTEST::TestOneof2::kFoogroup: + EXPECT_TRUE(message.has_foogroup()); + break; + case UNITTEST::TestOneof2::kFooLazyMessage: + EXPECT_TRUE(message.has_foo_lazy_message()); + break; + case UNITTEST::TestOneof2::FOO_NOT_SET: + break; + } + } +}; + +TEST_F(OneofTest, SettingOneFieldClearsOthers) { + UNITTEST::TestOneof2 message; + + message.set_foo_int(123); + EXPECT_TRUE(message.has_foo_int()); + TestUtil::ExpectAtMostOneFieldSetInOneof(message); + + message.set_foo_string("foo"); + EXPECT_TRUE(message.has_foo_string()); + TestUtil::ExpectAtMostOneFieldSetInOneof(message); + + + message.set_foo_bytes("qux"); + EXPECT_TRUE(message.has_foo_bytes()); + TestUtil::ExpectAtMostOneFieldSetInOneof(message); + + message.set_foo_enum(UNITTEST::TestOneof2::FOO); + EXPECT_TRUE(message.has_foo_enum()); + TestUtil::ExpectAtMostOneFieldSetInOneof(message); + + message.mutable_foo_message()->set_qux_int(234); + EXPECT_TRUE(message.has_foo_message()); + TestUtil::ExpectAtMostOneFieldSetInOneof(message); + + message.mutable_foogroup()->set_a(345); + EXPECT_TRUE(message.has_foogroup()); + TestUtil::ExpectAtMostOneFieldSetInOneof(message); + + + // we repeat this because we didn't test if this properly clears other fields + // at the beginning. + message.set_foo_int(123); + EXPECT_TRUE(message.has_foo_int()); + TestUtil::ExpectAtMostOneFieldSetInOneof(message); +} + +TEST_F(OneofTest, EnumCases) { + UNITTEST::TestOneof2 message; + + message.set_foo_int(123); + ExpectEnumCasesWork(message); + message.set_foo_string("foo"); + ExpectEnumCasesWork(message); + message.set_foo_bytes("qux"); + ExpectEnumCasesWork(message); + message.set_foo_enum(UNITTEST::TestOneof2::FOO); + ExpectEnumCasesWork(message); + message.mutable_foo_message()->set_qux_int(234); + ExpectEnumCasesWork(message); + message.mutable_foogroup()->set_a(345); + ExpectEnumCasesWork(message); +} + +TEST_F(OneofTest, PrimitiveType) { + UNITTEST::TestOneof2 message; + // Unset field returns default value + EXPECT_EQ(message.foo_int(), 0); + + message.set_foo_int(123); + EXPECT_TRUE(message.has_foo_int()); + EXPECT_EQ(message.foo_int(), 123); + message.clear_foo_int(); + EXPECT_FALSE(message.has_foo_int()); +} + +TEST_F(OneofTest, EnumType) { + UNITTEST::TestOneof2 message; + // Unset field returns default value + EXPECT_EQ(message.foo_enum(), 1); + + message.set_foo_enum(UNITTEST::TestOneof2::FOO); + EXPECT_TRUE(message.has_foo_enum()); + EXPECT_EQ(message.foo_enum(), UNITTEST::TestOneof2::FOO); + message.clear_foo_enum(); + EXPECT_FALSE(message.has_foo_enum()); +} + +TEST_F(OneofTest, SetString) { + // Check that setting a string field in various ways works + UNITTEST::TestOneof2 message; + + // Unset field returns default value + EXPECT_EQ(message.foo_string(), ""); + + message.set_foo_string("foo"); + EXPECT_TRUE(message.has_foo_string()); + EXPECT_EQ(message.foo_string(), "foo"); + message.clear_foo_string(); + EXPECT_FALSE(message.has_foo_string()); + + message.set_foo_string(string("bar")); + EXPECT_TRUE(message.has_foo_string()); + EXPECT_EQ(message.foo_string(), "bar"); + message.clear_foo_string(); + EXPECT_FALSE(message.has_foo_string()); + + + message.set_foo_string("qux", 3); + EXPECT_TRUE(message.has_foo_string()); + EXPECT_EQ(message.foo_string(), "qux"); + message.clear_foo_string(); + EXPECT_FALSE(message.has_foo_string()); + + message.mutable_foo_string()->assign("quux"); + EXPECT_TRUE(message.has_foo_string()); + EXPECT_EQ(message.foo_string(), "quux"); + message.clear_foo_string(); + EXPECT_FALSE(message.has_foo_string()); + + message.set_foo_string("corge"); + EXPECT_TRUE(message.has_foo_string()); + EXPECT_EQ(message.foo_string(), "corge"); + message.clear_foo_string(); + EXPECT_FALSE(message.has_foo_string()); +} + +TEST_F(OneofTest, ReleaseString) { + // Check that release_foo() starts out NULL, and gives us a value + // that we can delete after it's been set. + UNITTEST::TestOneof2 message; + + EXPECT_EQ(NULL, message.release_foo_string()); + EXPECT_FALSE(message.has_foo_string()); + + message.set_foo_string("blah"); + EXPECT_TRUE(message.has_foo_string()); + std::unique_ptr<string> str(message.release_foo_string()); + EXPECT_FALSE(message.has_foo_string()); + ASSERT_TRUE(str != NULL); + EXPECT_EQ("blah", *str); + + EXPECT_EQ(NULL, message.release_foo_string()); + EXPECT_FALSE(message.has_foo_string()); +} + +TEST_F(OneofTest, SetAllocatedString) { + // Check that set_allocated_foo() works for strings. + UNITTEST::TestOneof2 message; + + EXPECT_FALSE(message.has_foo_string()); + const string kHello("hello"); + message.set_foo_string(kHello); + EXPECT_TRUE(message.has_foo_string()); + + message.set_allocated_foo_string(NULL); + EXPECT_FALSE(message.has_foo_string()); + EXPECT_EQ("", message.foo_string()); + + message.set_allocated_foo_string(new string(kHello)); + EXPECT_TRUE(message.has_foo_string()); + EXPECT_EQ(kHello, message.foo_string()); +} + + +TEST_F(OneofTest, SetMessage) { + // Check that setting a message field works + UNITTEST::TestOneof2 message; + + // Unset field returns default instance + EXPECT_EQ(&message.foo_message(), + &UNITTEST::TestOneof2_NestedMessage::default_instance()); + EXPECT_EQ(message.foo_message().qux_int(), 0); + + message.mutable_foo_message()->set_qux_int(234); + EXPECT_TRUE(message.has_foo_message()); + EXPECT_EQ(message.foo_message().qux_int(), 234); + message.clear_foo_message(); + EXPECT_FALSE(message.has_foo_message()); +} + +TEST_F(OneofTest, ReleaseMessage) { + // Check that release_foo() starts out NULL, and gives us a value + // that we can delete after it's been set. + UNITTEST::TestOneof2 message; + + EXPECT_EQ(NULL, message.release_foo_message()); + EXPECT_FALSE(message.has_foo_message()); + + message.mutable_foo_message()->set_qux_int(1); + EXPECT_TRUE(message.has_foo_message()); + std::unique_ptr<UNITTEST::TestOneof2_NestedMessage> mes( + message.release_foo_message()); + EXPECT_FALSE(message.has_foo_message()); + ASSERT_TRUE(mes != NULL); + EXPECT_EQ(1, mes->qux_int()); + + EXPECT_EQ(NULL, message.release_foo_message()); + EXPECT_FALSE(message.has_foo_message()); +} + +TEST_F(OneofTest, SetAllocatedMessage) { + // Check that set_allocated_foo() works for messages. + UNITTEST::TestOneof2 message; + + EXPECT_FALSE(message.has_foo_message()); + + message.mutable_foo_message()->set_qux_int(1); + EXPECT_TRUE(message.has_foo_message()); + + message.set_allocated_foo_message(NULL); + EXPECT_FALSE(message.has_foo_message()); + EXPECT_EQ(&message.foo_message(), + &UNITTEST::TestOneof2_NestedMessage::default_instance()); + + message.mutable_foo_message()->set_qux_int(1); + UNITTEST::TestOneof2_NestedMessage* mes = message.release_foo_message(); + ASSERT_TRUE(mes != NULL); + EXPECT_FALSE(message.has_foo_message()); + + message.set_allocated_foo_message(mes); + EXPECT_TRUE(message.has_foo_message()); + EXPECT_EQ(1, message.foo_message().qux_int()); +} + + +TEST_F(OneofTest, Clear) { + UNITTEST::TestOneof2 message; + + message.set_foo_int(1); + EXPECT_TRUE(message.has_foo_int()); + message.clear_foo_int(); + EXPECT_FALSE(message.has_foo_int()); +} + +TEST_F(OneofTest, Defaults) { + UNITTEST::TestOneof2 message; + + EXPECT_FALSE(message.has_foo_int()); + EXPECT_EQ(message.foo_int(), 0); + + EXPECT_FALSE(message.has_foo_string()); + EXPECT_EQ(message.foo_string(), ""); + + + EXPECT_FALSE(message.has_foo_bytes()); + EXPECT_EQ(message.foo_bytes(), ""); + + EXPECT_FALSE(message.has_foo_enum()); + EXPECT_EQ(message.foo_enum(), 1); + + EXPECT_FALSE(message.has_foo_message()); + EXPECT_EQ(message.foo_message().qux_int(), 0); + + EXPECT_FALSE(message.has_foogroup()); + EXPECT_EQ(message.foogroup().a(), 0); + + + EXPECT_FALSE(message.has_bar_int()); + EXPECT_EQ(message.bar_int(), 5); + + EXPECT_FALSE(message.has_bar_string()); + EXPECT_EQ(message.bar_string(), "STRING"); + + + EXPECT_FALSE(message.has_bar_bytes()); + EXPECT_EQ(message.bar_bytes(), "BYTES"); + + EXPECT_FALSE(message.has_bar_enum()); + EXPECT_EQ(message.bar_enum(), 2); +} + +TEST_F(OneofTest, SwapWithEmpty) { + UNITTEST::TestOneof2 message1, message2; + message1.set_foo_string("FOO"); + EXPECT_TRUE(message1.has_foo_string()); + message1.Swap(&message2); + EXPECT_FALSE(message1.has_foo_string()); + EXPECT_TRUE(message2.has_foo_string()); + EXPECT_EQ(message2.foo_string(), "FOO"); +} + +TEST_F(OneofTest, SwapWithSelf) { + UNITTEST::TestOneof2 message; + message.set_foo_string("FOO"); + EXPECT_TRUE(message.has_foo_string()); + message.Swap(&message); + EXPECT_TRUE(message.has_foo_string()); + EXPECT_EQ(message.foo_string(), "FOO"); +} + +TEST_F(OneofTest, SwapBothHasFields) { + UNITTEST::TestOneof2 message1, message2; + + message1.set_foo_string("FOO"); + EXPECT_TRUE(message1.has_foo_string()); + message2.mutable_foo_message()->set_qux_int(1); + EXPECT_TRUE(message2.has_foo_message()); + + message1.Swap(&message2); + EXPECT_FALSE(message1.has_foo_string()); + EXPECT_FALSE(message2.has_foo_message()); + EXPECT_TRUE(message1.has_foo_message()); + EXPECT_EQ(message1.foo_message().qux_int(), 1); + EXPECT_TRUE(message2.has_foo_string()); + EXPECT_EQ(message2.foo_string(), "FOO"); +} + +TEST_F(OneofTest, CopyConstructor) { + UNITTEST::TestOneof2 message1; + message1.set_foo_bytes("FOO"); + + UNITTEST::TestOneof2 message2(message1); + EXPECT_TRUE(message2.has_foo_bytes()); + EXPECT_EQ(message2.foo_bytes(), "FOO"); +} + +TEST_F(OneofTest, CopyFrom) { + UNITTEST::TestOneof2 message1, message2; + message1.set_foo_enum(UNITTEST::TestOneof2::BAR); + EXPECT_TRUE(message1.has_foo_enum()); + + message2.CopyFrom(message1); + EXPECT_TRUE(message2.has_foo_enum()); + EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::BAR); + + // Copying from self should be a no-op. + message2.CopyFrom(message2); + EXPECT_TRUE(message2.has_foo_enum()); + EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::BAR); +} + +TEST_F(OneofTest, CopyAssignmentOperator) { + UNITTEST::TestOneof2 message1; + message1.mutable_foo_message()->set_qux_int(123); + EXPECT_TRUE(message1.has_foo_message()); + + UNITTEST::TestOneof2 message2; + message2 = message1; + EXPECT_EQ(message2.foo_message().qux_int(), 123); + + // Make sure that self-assignment does something sane. + message2 = message2; + EXPECT_EQ(message2.foo_message().qux_int(), 123); +} + +TEST_F(OneofTest, UpcastCopyFrom) { + // Test the CopyFrom method that takes in the generic const Message& + // parameter. + UNITTEST::TestOneof2 message1, message2; + message1.mutable_foogroup()->set_a(123); + EXPECT_TRUE(message1.has_foogroup()); + + const Message* source = implicit_cast<const Message*>(&message1); + message2.CopyFrom(*source); + + EXPECT_TRUE(message2.has_foogroup()); + EXPECT_EQ(message2.foogroup().a(), 123); +} + +// Test the generated SerializeWithCachedSizesToArray(), +// This indirectly tests MergePartialFromCodedStream() +// We have to test each field type separately because we cannot set them at the +// same time +TEST_F(OneofTest, SerializationToArray) { + // Primitive type + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.set_foo_int(123); + int size = message1.ByteSizeLong(); + data.resize(size); + uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); + uint8* end = message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(size, end - start); + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foo_int(), 123); + } + + // String + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.set_foo_string("foo"); + int size = message1.ByteSizeLong(); + data.resize(size); + uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); + uint8* end = message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(size, end - start); + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foo_string(), "foo"); + } + + + // Bytes + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.set_foo_bytes("qux"); + int size = message1.ByteSizeLong(); + data.resize(size); + uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); + uint8* end = message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(size, end - start); + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foo_bytes(), "qux"); + } + + // Enum + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.set_foo_enum(UNITTEST::TestOneof2::FOO); + int size = message1.ByteSizeLong(); + data.resize(size); + uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); + uint8* end = message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(size, end - start); + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::FOO); + } + + // Message + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.mutable_foo_message()->set_qux_int(234); + int size = message1.ByteSizeLong(); + data.resize(size); + uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); + uint8* end = message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(size, end - start); + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foo_message().qux_int(), 234); + } + + // Group + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.mutable_foogroup()->set_a(345); + int size = message1.ByteSizeLong(); + data.resize(size); + uint8* start = reinterpret_cast<uint8*>(string_as_array(&data)); + uint8* end = message1.SerializeWithCachedSizesToArray(start); + EXPECT_EQ(size, end - start); + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foogroup().a(), 345); + } + +} + +// Test the generated SerializeWithCachedSizes() by forcing the buffer to write +// one byte at a time. +// This indirectly tests MergePartialFromCodedStream() +// We have to test each field type separately because we cannot set them at the +// same time +TEST_F(OneofTest, SerializationToStream) { + // Primitive type + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.set_foo_int(123); + int size = message1.ByteSizeLong(); + data.resize(size); + + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foo_int(), 123); + } + + // String + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.set_foo_string("foo"); + int size = message1.ByteSizeLong(); + data.resize(size); + + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foo_string(), "foo"); + } + + + // Bytes + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.set_foo_bytes("qux"); + int size = message1.ByteSizeLong(); + data.resize(size); + + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foo_bytes(), "qux"); + } + + // Enum + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.set_foo_enum(UNITTEST::TestOneof2::FOO); + int size = message1.ByteSizeLong(); + data.resize(size); + + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::FOO); + } + + // Message + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.mutable_foo_message()->set_qux_int(234); + int size = message1.ByteSizeLong(); + data.resize(size); + + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foo_message().qux_int(), 234); + } + + // Group + { + UNITTEST::TestOneof2 message1, message2; + string data; + message1.mutable_foogroup()->set_a(345); + int size = message1.ByteSizeLong(); + data.resize(size); + + { + // Allow the output stream to buffer only one byte at a time. + io::ArrayOutputStream array_stream(string_as_array(&data), size, 1); + io::CodedOutputStream output_stream(&array_stream); + message1.SerializeWithCachedSizes(&output_stream); + EXPECT_FALSE(output_stream.HadError()); + EXPECT_EQ(size, output_stream.ByteCount()); + } + + EXPECT_TRUE(message2.ParseFromString(data)); + EXPECT_EQ(message2.foogroup().a(), 345); + } + +} + +TEST_F(OneofTest, MergeFrom) { + UNITTEST::TestOneof2 message1, message2; + + message1.set_foo_int(123); + message2.MergeFrom(message1); + TestUtil::ExpectAtMostOneFieldSetInOneof(message2); + EXPECT_TRUE(message2.has_foo_int()); + EXPECT_EQ(message2.foo_int(), 123); + + message1.set_foo_string("foo"); + message2.MergeFrom(message1); + TestUtil::ExpectAtMostOneFieldSetInOneof(message2); + EXPECT_TRUE(message2.has_foo_string()); + EXPECT_EQ(message2.foo_string(), "foo"); + + + message1.set_foo_bytes("qux"); + message2.MergeFrom(message1); + TestUtil::ExpectAtMostOneFieldSetInOneof(message2); + EXPECT_TRUE(message2.has_foo_bytes()); + EXPECT_EQ(message2.foo_bytes(), "qux"); + + message1.set_foo_enum(UNITTEST::TestOneof2::FOO); + message2.MergeFrom(message1); + TestUtil::ExpectAtMostOneFieldSetInOneof(message2); + EXPECT_TRUE(message2.has_foo_enum()); + EXPECT_EQ(message2.foo_enum(), UNITTEST::TestOneof2::FOO); + + message1.mutable_foo_message()->set_qux_int(234); + message2.MergeFrom(message1); + TestUtil::ExpectAtMostOneFieldSetInOneof(message2); + EXPECT_TRUE(message2.has_foo_message()); + EXPECT_EQ(message2.foo_message().qux_int(), 234); + + message1.mutable_foogroup()->set_a(345); + message2.MergeFrom(message1); + TestUtil::ExpectAtMostOneFieldSetInOneof(message2); + EXPECT_TRUE(message2.has_foogroup()); + EXPECT_EQ(message2.foogroup().a(), 345); + +} + +TEST(HELPERS_TEST_NAME, TestSCC) { + UNITTEST::TestMutualRecursionA a; + SCCAnalyzer scc_analyzer((Options())); + const SCC* scc = scc_analyzer.GetSCC(a.GetDescriptor()); + std::vector<string> names; + for (int i = 0; i < scc->descriptors.size(); i++) { + names.push_back(scc->descriptors[i]->full_name()); + } + string package = a.GetDescriptor()->file()->package(); + ASSERT_EQ(names.size(), 4); + std::sort(names.begin(), names.end()); + EXPECT_EQ(names[0], package + ".TestMutualRecursionA"); + EXPECT_EQ(names[1], package + ".TestMutualRecursionA.SubGroup"); + EXPECT_EQ(names[2], package + ".TestMutualRecursionA.SubMessage"); + EXPECT_EQ(names[3], package + ".TestMutualRecursionB"); + + MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); + EXPECT_EQ(result.is_recursive, true); + EXPECT_EQ(result.contains_required, false); + EXPECT_EQ(result.contains_cord, true); // TestAllTypes + EXPECT_EQ(result.contains_extension, false); // TestAllTypes +} + +TEST(HELPERS_TEST_NAME, TestSCCAnalysis) { + { + UNITTEST::TestRecursiveMessage msg; + SCCAnalyzer scc_analyzer((Options())); + const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor()); + MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); + EXPECT_EQ(result.is_recursive, true); + EXPECT_EQ(result.contains_required, false); + EXPECT_EQ(result.contains_cord, false); + EXPECT_EQ(result.contains_extension, false); + } + { + UNITTEST::TestAllExtensions msg; + SCCAnalyzer scc_analyzer((Options())); + const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor()); + MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); + EXPECT_EQ(result.is_recursive, false); + EXPECT_EQ(result.contains_required, false); + EXPECT_EQ(result.contains_cord, false); + EXPECT_EQ(result.contains_extension, true); + } + { + UNITTEST::TestRequired msg; + SCCAnalyzer scc_analyzer((Options())); + const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor()); + MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); + EXPECT_EQ(result.is_recursive, false); + EXPECT_EQ(result.contains_required, true); + EXPECT_EQ(result.contains_cord, false); + EXPECT_EQ(result.contains_extension, false); + } +} + +} // namespace cpp_unittest +} // namespace cpp +} // namespace compiler + +namespace no_generic_services_test { + // Verify that no class called "TestService" was defined in + // unittest_no_generic_services.pb.h by defining a different type by the same + // name. If such a service was generated, this will not compile. + struct TestService { + int i; + }; +} + +namespace compiler { +namespace cpp { +namespace cpp_unittest { + +TEST_F(GENERATED_SERVICE_TEST_NAME, NoGenericServices) { + // Verify that non-services in unittest_no_generic_services.proto were + // generated. + no_generic_services_test::TestMessage message; + message.set_a(1); + message.SetExtension(no_generic_services_test::test_extension, 123); + no_generic_services_test::TestEnum e = no_generic_services_test::FOO; + EXPECT_EQ(e, 1); + + // Verify that a ServiceDescriptor is generated for the service even if the + // class itself is not. + const FileDescriptor* file = + no_generic_services_test::TestMessage::descriptor()->file(); + + ASSERT_EQ(1, file->service_count()); + EXPECT_EQ("TestService", file->service(0)->name()); + ASSERT_EQ(1, file->service(0)->method_count()); + EXPECT_EQ("Foo", file->service(0)->method(0)->name()); +} + +#endif // !PROTOBUF_TEST_NO_DESCRIPTORS + +// =================================================================== + +// This test must run last. It verifies that descriptors were or were not +// initialized depending on whether PROTOBUF_TEST_NO_DESCRIPTORS was defined. +// When this is defined, we skip all tests which are expected to trigger +// descriptor initialization. This verifies that everything else still works +// if descriptors are not initialized. +TEST(DESCRIPTOR_INIT_TEST_NAME, Initialized) { +#ifdef PROTOBUF_TEST_NO_DESCRIPTORS + bool should_have_descriptors = false; +#else + bool should_have_descriptors = true; +#endif + + EXPECT_EQ(should_have_descriptors, + DescriptorPool::generated_pool()->InternalIsFileLoaded( + UNITTEST_PROTO_PATH)); +} + +} // namespace cpp_unittest + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/cpp/metadata_test.cc b/src/google/protobuf/compiler/cpp/metadata_test.cc index 456784c6..2ad4edd2 100644 --- a/src/google/protobuf/compiler/cpp/metadata_test.cc +++ b/src/google/protobuf/compiler/cpp/metadata_test.cc @@ -29,9 +29,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/compiler/cpp/cpp_generator.h> diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc index a5341e0d..c3831e72 100644 --- a/src/google/protobuf/compiler/importer.cc +++ b/src/google/protobuf/compiler/importer.cc @@ -32,7 +32,6 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. - #ifdef _MSC_VER #include <direct.h> #else @@ -45,9 +44,6 @@ #include <algorithm> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/compiler/importer.h> @@ -55,6 +51,8 @@ #include <google/protobuf/io/tokenizer.h> #include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/stubs/strutil.h> + + #include <google/protobuf/stubs/io_win32.h> #ifdef _WIN32 @@ -131,7 +129,7 @@ SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {} bool SourceTreeDescriptorDatabase::FindFileByName( const string& filename, FileDescriptorProto* output) { - google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename)); + std::unique_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename)); if (input == NULL) { if (error_collector_ != NULL) { error_collector_->AddError(filename, -1, 0, @@ -420,7 +418,7 @@ DiskSourceTree::DiskFileToVirtualFile( // Verify that we can open the file. Note that this also has the side-effect // of verifying that we are not canonicalizing away any non-existent // directories. - google::protobuf::scoped_ptr<io::ZeroCopyInputStream> stream(OpenDiskFile(disk_file)); + std::unique_ptr<io::ZeroCopyInputStream> stream(OpenDiskFile(disk_file)); if (stream == NULL) { return CANNOT_OPEN; } @@ -430,7 +428,7 @@ DiskSourceTree::DiskFileToVirtualFile( bool DiskSourceTree::VirtualFileToDiskFile(const string& virtual_file, string* disk_file) { - google::protobuf::scoped_ptr<io::ZeroCopyInputStream> stream( + std::unique_ptr<io::ZeroCopyInputStream> stream( OpenVirtualFile(virtual_file, disk_file)); return stream != NULL; } diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc index a96ac853..73bef3f4 100644 --- a/src/google/protobuf/compiler/importer_unittest.cc +++ b/src/google/protobuf/compiler/importer_unittest.cc @@ -36,9 +36,6 @@ #include <google/protobuf/stubs/hash.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> @@ -268,7 +265,7 @@ class DiskSourceTreeTest : public testing::Test { void ExpectFileContents(const string& filename, const char* expected_contents) { - google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); + std::unique_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); ASSERT_FALSE(input == NULL); @@ -285,7 +282,7 @@ class DiskSourceTreeTest : public testing::Test { void ExpectCannotOpenFile(const string& filename, const string& error_message) { - google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); + std::unique_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); EXPECT_TRUE(input == NULL); EXPECT_EQ(error_message, source_tree_.GetLastErrorMessage()); } diff --git a/src/google/protobuf/compiler/java/java_context.cc b/src/google/protobuf/compiler/java/java_context.cc index 0771d5e1..2528c2d1 100644 --- a/src/google/protobuf/compiler/java/java_context.cc +++ b/src/google/protobuf/compiler/java/java_context.cc @@ -69,14 +69,14 @@ bool IsConflicting(const FieldDescriptor* field1, const string& name1, // field1 is repeated, and field2 is not. if (name1 + "Count" == name2) { *info = "both repeated field \"" + field1->name() + "\" and singular " + - "field \"" + field2->name() + "\" generates the method \"" + - "get" + name1 + "Count()\""; + "field \"" + field2->name() + "\" generate the method \"" + + "get" + name1 + "Count()\""; return true; } if (name1 + "List" == name2) { *info = "both repeated field \"" + field1->name() + "\" and singular " + - "field \"" + field2->name() + "\" generates the method \"" + - "get" + name1 + "List()\""; + "field \"" + field2->name() + "\" generate the method \"" + + "get" + name1 + "List()\""; return true; } // Well, there are obviously many more conflicting cases, but it probably diff --git a/src/google/protobuf/compiler/java/java_context.h b/src/google/protobuf/compiler/java/java_context.h index 9a74c430..9de7415a 100644 --- a/src/google/protobuf/compiler/java/java_context.h +++ b/src/google/protobuf/compiler/java/java_context.h @@ -33,9 +33,6 @@ #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <vector> #include <google/protobuf/stubs/common.h> @@ -97,7 +94,7 @@ class Context { void InitializeFieldGeneratorInfoForFields( const std::vector<const FieldDescriptor*>& fields); - google::protobuf::scoped_ptr<ClassNameResolver> name_resolver_; + std::unique_ptr<ClassNameResolver> name_resolver_; std::map<const FieldDescriptor*, FieldGeneratorInfo> field_generator_info_map_; std::map<const OneofDescriptor*, OneofGeneratorInfo> diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc index d125ebe5..bef69f1a 100644 --- a/src/google/protobuf/compiler/java/java_enum.cc +++ b/src/google/protobuf/compiler/java/java_enum.cc @@ -36,12 +36,12 @@ #include <string> #include <google/protobuf/compiler/java/java_context.h> -#include <google/protobuf/compiler/java/java_enum.h> #include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_enum.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/strutil.h> namespace google { diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc index 642cdd36..0686ea0f 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/src/google/protobuf/compiler/java/java_enum_field.cc @@ -674,8 +674,7 @@ GenerateMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); } - if (descriptor_->is_packed() && - context_->HasGeneratedMethods(descriptor_->containing_type())) { + if (descriptor_->is_packed()) { printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n"); } diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc index a4de1e23..f1fe71b0 100644 --- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc @@ -165,6 +165,7 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); @@ -173,6 +174,7 @@ GenerateMembers(io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return $name$_;\n" "}\n"); @@ -180,6 +182,7 @@ GenerateMembers(io::Printer* printer) const { } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " $type$ result = $type$.forNumber($name$_);\n" " return result == null ? $unknown$ : result;\n" @@ -217,6 +220,7 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); @@ -225,6 +229,7 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return instance.get$capitalized_name$Value();\n" "}\n"); @@ -241,6 +246,7 @@ GenerateBuilderMembers(io::Printer* printer) const { } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); @@ -378,6 +384,7 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); @@ -386,6 +393,7 @@ GenerateMembers(io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " if ($has_oneof_case_message$) {\n" " return (java.lang.Integer) $oneof_name$_;\n" @@ -396,6 +404,7 @@ GenerateMembers(io::Printer* printer) const { } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $type$ result = $type$.forNumber((java.lang.Integer) $oneof_name$_);\n" @@ -439,6 +448,7 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); @@ -447,6 +457,7 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return instance.get$capitalized_name$Value();\n" "}\n"); @@ -463,6 +474,7 @@ GenerateBuilderMembers(io::Printer* printer) const { } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); @@ -611,6 +623,7 @@ GenerateMembers(io::Printer* printer) const { " java.lang.Integer, $type$> $name$_converter_ =\n" " new com.google.protobuf.Internal.ListAdapter.Converter<\n" " java.lang.Integer, $type$>() {\n" + " @java.lang.Override\n" " public $type$ convert(java.lang.Integer from) {\n" " $type$ result = $type$.forNumber(from);\n" " return result == null ? $unknown$ : result;\n" @@ -619,6 +632,7 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<$type$> " "${$get$capitalized_name$List$}$() {\n" " return new com.google.protobuf.Internal.ListAdapter<\n" @@ -627,12 +641,14 @@ GenerateMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_converter_.convert($name$_.getInt(index));\n" "}\n"); @@ -640,6 +656,7 @@ GenerateMembers(io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<java.lang.Integer>\n" "${$get$capitalized_name$ValueList$}$() {\n" " return $name$_;\n" @@ -647,6 +664,7 @@ GenerateMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Value$}$(int index) {\n" " return $name$_.getInt(index);\n" "}\n"); @@ -732,6 +750,7 @@ void RepeatedImmutableEnumFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<$type$> " "${$get$capitalized_name$List$}$() {\n" " return instance.get$capitalized_name$List();\n" @@ -739,12 +758,14 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); @@ -787,6 +808,7 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<java.lang.Integer>\n" "${$get$capitalized_name$ValueList$}$() {\n" " return java.util.Collections.unmodifiableList(\n" @@ -795,6 +817,7 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Value$}$(int index) {\n" " return instance.get$capitalized_name$Value(index);\n" "}\n"); diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc index ab3b3323..806008ee 100644 --- a/src/google/protobuf/compiler/java/java_enum_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_lite.cc @@ -36,12 +36,12 @@ #include <string> #include <google/protobuf/compiler/java/java_context.h> -#include <google/protobuf/compiler/java/java_enum_lite.h> #include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_enum_lite.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> -#include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/strutil.h> namespace google { @@ -135,6 +135,7 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { printer->Print( "\n" + "@java.lang.Override\n" "public final int getNumber() {\n"); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( @@ -182,6 +183,7 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { "private static final com.google.protobuf.Internal.EnumLiteMap<\n" " $classname$> internalValueMap =\n" " new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n" + " @java.lang.Override\n" " public $classname$ findValueByNumber(int number) {\n" " return $classname$.forNumber(number);\n" " }\n" diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc index 9b9be55b..3eb1370d 100644 --- a/src/google/protobuf/compiler/java/java_extension.cc +++ b/src/google/protobuf/compiler/java/java_extension.cc @@ -141,6 +141,7 @@ void ImmutableExtensionGenerator::Generate(io::Printer* printer) { " $singular_type$.class,\n" " $prototype$);\n"); } + printer->Annotate("name", descriptor_); } int ImmutableExtensionGenerator::GenerateNonNestedInitializationCode( diff --git a/src/google/protobuf/compiler/java/java_extension_lite.cc b/src/google/protobuf/compiler/java/java_extension_lite.cc index c48c92e9..70ce8e7d 100644 --- a/src/google/protobuf/compiler/java/java_extension_lite.cc +++ b/src/google/protobuf/compiler/java/java_extension_lite.cc @@ -96,6 +96,7 @@ void ImmutableExtensionLiteGenerator::Generate(io::Printer* printer) { " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n" " $singular_type$.class);\n"); } + printer->Annotate("name", descriptor_); } int ImmutableExtensionLiteGenerator::GenerateNonNestedInitializationCode( diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc index 1ab18629..d7319681 100644 --- a/src/google/protobuf/compiler/java/java_field.cc +++ b/src/google/protobuf/compiler/java/java_field.cc @@ -35,9 +35,6 @@ #include <google/protobuf/compiler/java/java_field.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> @@ -214,7 +211,7 @@ template <> FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap( const Descriptor* descriptor, Context* context) : descriptor_(descriptor), - field_generators_(new google::protobuf::scoped_ptr< + field_generators_(new std::unique_ptr< ImmutableFieldGenerator>[descriptor->field_count()]) { // Construct all the FieldGenerators and assign them bit indices for their @@ -237,7 +234,7 @@ template <> FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap( const Descriptor* descriptor, Context* context) : descriptor_(descriptor), - field_generators_(new google::protobuf::scoped_ptr< + field_generators_(new std::unique_ptr< ImmutableFieldLiteGenerator>[descriptor->field_count()]) { // Construct all the FieldGenerators and assign them bit indices for their // bit fields. diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h index cc1d83d9..04bbe24a 100644 --- a/src/google/protobuf/compiler/java/java_field.h +++ b/src/google/protobuf/compiler/java/java_field.h @@ -37,9 +37,6 @@ #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <string> #include <google/protobuf/stubs/common.h> @@ -141,7 +138,7 @@ class FieldGeneratorMap { const Descriptor* descriptor_; Context* context_; ClassNameResolver* name_resolver_; - google::protobuf::scoped_array<google::protobuf::scoped_ptr<FieldGeneratorType> > field_generators_; + std::unique_ptr<std::unique_ptr<FieldGeneratorType> []> field_generators_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); }; @@ -163,6 +160,14 @@ template<> FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap(); +template <> +FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap( + const Descriptor* descriptor, Context* context); + +template <> +FieldGeneratorMap<ImmutableFieldLiteGenerator>::~FieldGeneratorMap(); + + // Field information used in FieldGeneartors. struct FieldGeneratorInfo { string name; diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index 21133a15..5ee04e5a 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -35,9 +35,6 @@ #include <google/protobuf/compiler/java/java_file.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <set> #include <google/protobuf/compiler/java/java_context.h> @@ -51,9 +48,9 @@ #include <google/protobuf/compiler/java/java_service.h> #include <google/protobuf/compiler/java/java_shared_code_generator.h> #include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/dynamic_message.h> #include <google/protobuf/stubs/strutil.h> @@ -136,7 +133,7 @@ void CollectExtensions(const FileDescriptorProto& file_proto, "descriptor.proto is not in the transitive dependencies. " "This normally should not happen. Please report a bug."; DynamicMessageFactory factory; - google::protobuf::scoped_ptr<Message> dynamic_file_proto( + std::unique_ptr<Message> dynamic_file_proto( factory.GetPrototype(file_proto_desc)->New()); GOOGLE_CHECK(dynamic_file_proto.get() != NULL); GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data)); @@ -190,9 +187,9 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options, : file_(file), java_package_(FileJavaPackage(file, immutable_api)), message_generators_( - new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]), + new std::unique_ptr<MessageGenerator>[file->message_type_count()]), extension_generators_( - new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]), + new std::unique_ptr<ExtensionGenerator>[file->extension_count()]), context_(new Context(file, options)), name_resolver_(context_->GetNameResolver()), options_(options), @@ -309,7 +306,7 @@ void FileGenerator::Generate(io::Printer* printer) { } if (HasGenericServices(file_, context_->EnforceLite())) { for (int i = 0; i < file_->service_count(); i++) { - google::protobuf::scoped_ptr<ServiceGenerator> generator( + std::unique_ptr<ServiceGenerator> generator( generator_factory_->NewServiceGenerator(file_->service(i))); generator->Generate(printer); } @@ -435,7 +432,7 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( " com.google.protobuf.ExtensionRegistry.newInstance();\n"); FieldDescriptorSet::iterator it; for (it = extensions.begin(); it != extensions.end(); it++) { - google::protobuf::scoped_ptr<ExtensionGenerator> generator( + std::unique_ptr<ExtensionGenerator> generator( generator_factory_->NewExtensionGenerator(*it)); bytecode_estimate += generator->GenerateRegistrationCode(printer); MaybeRestartJavaMethod( @@ -588,7 +585,7 @@ static void GenerateSibling(const string& package_dir, io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( &annotations); - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); + std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); io::Printer printer(output.get(), '$', annotate_code ? &annotation_collector : NULL); @@ -607,7 +604,7 @@ static void GenerateSibling(const string& package_dir, (generator->*pfn)(&printer); if (annotate_code) { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output( + std::unique_ptr<io::ZeroCopyOutputStream> info_output( context->Open(info_full_path)); annotations.SerializeToZeroCopyStream(info_output.get()); annotation_list->push_back(info_full_path); @@ -650,7 +647,7 @@ void FileGenerator::GenerateSiblings(const string& package_dir, } if (HasGenericServices(file_, context_->EnforceLite())) { for (int i = 0; i < file_->service_count(); i++) { - google::protobuf::scoped_ptr<ServiceGenerator> generator( + std::unique_ptr<ServiceGenerator> generator( generator_factory_->NewServiceGenerator(file_->service(i))); GenerateSibling<ServiceGenerator>( package_dir, java_package_, file_->service(i), context, file_list, diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h index e95aef09..9ad7937c 100644 --- a/src/google/protobuf/compiler/java/java_file.h +++ b/src/google/protobuf/compiler/java/java_file.h @@ -36,9 +36,6 @@ #define GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <string> #include <vector> #include <google/protobuf/stubs/common.h> @@ -101,10 +98,10 @@ class FileGenerator { string java_package_; string classname_; - google::protobuf::scoped_array<google::protobuf::scoped_ptr<MessageGenerator> > message_generators_; - google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> > extension_generators_; - google::protobuf::scoped_ptr<GeneratorFactory> generator_factory_; - google::protobuf::scoped_ptr<Context> context_; + std::unique_ptr<std::unique_ptr<MessageGenerator> []> message_generators_; + std::unique_ptr<std::unique_ptr<ExtensionGenerator> []> extension_generators_; + std::unique_ptr<GeneratorFactory> generator_factory_; + std::unique_ptr<Context> context_; ClassNameResolver* name_resolver_; const Options options_; bool immutable_api_; diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc index 84a3b90d..a5b2e784 100644 --- a/src/google/protobuf/compiler/java/java_generator.cc +++ b/src/google/protobuf/compiler/java/java_generator.cc @@ -35,9 +35,6 @@ #include <google/protobuf/compiler/java/java_generator.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/compiler/java/java_file.h> #include <google/protobuf/compiler/java/java_generator_factory.h> @@ -45,9 +42,9 @@ #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/compiler/java/java_options.h> #include <google/protobuf/compiler/java/java_shared_code_generator.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/stubs/strutil.h> @@ -144,7 +141,7 @@ bool JavaGenerator::Generate(const FileDescriptor* file, } // Generate main java file. - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->Open(java_filename)); GeneratedCodeInfo annotations; io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( @@ -160,7 +157,7 @@ bool JavaGenerator::Generate(const FileDescriptor* file, &all_annotations); if (file_options.annotate_code) { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output( + std::unique_ptr<io::ZeroCopyOutputStream> info_output( context->Open(info_full_path)); annotations.SerializeToZeroCopyStream(info_output.get()); } @@ -175,7 +172,7 @@ bool JavaGenerator::Generate(const FileDescriptor* file, if (!file_options.output_list_file.empty()) { // Generate output list. This is just a simple text file placed in a // deterministic location which lists the .java files being generated. - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output( + std::unique_ptr<io::ZeroCopyOutputStream> srclist_raw_output( context->Open(file_options.output_list_file)); io::Printer srclist_printer(srclist_raw_output.get(), '$'); for (int i = 0; i < all_files.size(); i++) { @@ -186,7 +183,7 @@ bool JavaGenerator::Generate(const FileDescriptor* file, if (!file_options.annotation_list_file.empty()) { // Generate output list. This is just a simple text file placed in a // deterministic location which lists the .java files being generated. - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> annotation_list_raw_output( + std::unique_ptr<io::ZeroCopyOutputStream> annotation_list_raw_output( context->Open(file_options.annotation_list_file)); io::Printer annotation_list_printer(annotation_list_raw_output.get(), '$'); for (int i = 0; i < all_annotations.size(); i++) { diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc index dbb86b87..957076cb 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -75,6 +75,8 @@ const char* kForbiddenWordList[] = { "class", }; +const int kDefaultLookUpStartFieldNumber = 40; + bool IsForbidden(const string& field_name) { for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) { if (field_name == kForbiddenWordList[i]) { @@ -103,6 +105,20 @@ string FieldName(const FieldDescriptor* field) { } +// Judge whether should use table or use look up. +// Copied from com.google.protobuf.SchemaUtil.shouldUseTableSwitch +bool ShouldUseTable(int lo, int hi, int number_of_fields) { + if (hi < kDefaultLookUpStartFieldNumber) { + return true; + } + int64 table_space_cost = (static_cast<int64>(hi) - lo + 1); // words + int64 table_time_cost = 3; // comparisons + int64 lookup_space_cost = 3 + 2 * static_cast<int64>(number_of_fields); + int64 lookup_time_cost = 3 + number_of_fields; + return table_space_cost + 3 * table_time_cost <= + lookup_space_cost + 3 * lookup_time_cost; +} + } // namespace void PrintGeneratedAnnotation(io::Printer* printer, char delimiter, @@ -915,6 +931,23 @@ void EscapeUtf16ToString(uint16 code, string* output) { output->append(StringPrintf("\\u%04x", code)); } } + +std::pair<int, int> GetTableDrivenNumberOfEntriesAndLookUpStartFieldNumber( + const FieldDescriptor** fields, int count) { + GOOGLE_CHECK_GT(count, 0); + int table_driven_number_of_entries = count; + int look_up_start_field_number = 0; + for (int i = 0; i < count; i++) { + const int field_number = fields[i]->number(); + if (ShouldUseTable(fields[0]->number(), field_number, i + 1)) { + table_driven_number_of_entries = + field_number - fields[0]->number() + 1 + count - i - 1; + look_up_start_field_number = field_number + 1; + } + } + return std::make_pair( + table_driven_number_of_entries, look_up_start_field_number); +} } // namespace java } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h index 00d683db..dd9b65b8 100644 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ b/src/google/protobuf/compiler/java/java_helpers.h @@ -37,8 +37,8 @@ #include <string> #include <google/protobuf/compiler/java/java_context.h> -#include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.h> namespace google { @@ -414,6 +414,11 @@ void EscapeUtf16ToString(uint16 code, string* output); // bit 3: whether the field is a map field with proto2 enum value. // bits 4-7: unused int GetExperimentalJavaFieldType(const FieldDescriptor* field); + +// To get the total number of entries need to be built for experimental runtime +// and the first field number that are not in the table part +std::pair<int, int> GetTableDrivenNumberOfEntriesAndLookUpStartFieldNumber( + const FieldDescriptor** fields, int count); } // namespace java } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.cc b/src/google/protobuf/compiler/java/java_map_field_lite.cc index f19ec271..e2e68076 100644 --- a/src/google/protobuf/compiler/java/java_map_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc @@ -301,6 +301,7 @@ GenerateMembers(io::Printer* printer) const { "}\n"); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public int ${$get$capitalized_name$Count$}$() {\n" " return internalGet$capitalized_name$().size();\n" @@ -309,6 +310,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key) {\n" @@ -339,6 +341,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" "${$get$capitalized_name$Map$}$() {\n" @@ -352,6 +355,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" @@ -367,6 +371,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" @@ -385,6 +390,7 @@ GenerateMembers(io::Printer* printer) const { "/**\n" " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" " */\n" + "@java.lang.Override\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "${$get$capitalized_name$Value$}$() {\n" @@ -394,6 +400,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "${$get$capitalized_name$ValueMap$}$() {\n" @@ -404,6 +411,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" @@ -417,6 +425,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key) {\n" @@ -436,6 +445,7 @@ GenerateMembers(io::Printer* printer) const { "/**\n" " * Use {@link #get$capitalized_name$Map()} instead.\n" " */\n" + "@java.lang.Override\n" "@java.lang.Deprecated\n" "public java.util.Map<$type_parameters$> " "${$get$capitalized_name$$}$() {\n" @@ -445,6 +455,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public java.util.Map<$type_parameters$> " "${$get$capitalized_name$Map$}$() {\n" @@ -455,6 +466,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" @@ -468,6 +480,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" @@ -519,6 +532,7 @@ void ImmutableMapFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Map().size();\n" @@ -527,6 +541,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key) {\n" @@ -570,6 +585,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" "${$get$capitalized_name$Map$}$() {\n" @@ -580,6 +596,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" @@ -595,6 +612,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" @@ -636,6 +654,7 @@ GenerateBuilderMembers(io::Printer* printer) const { "/**\n" " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" " */\n" + "@java.lang.Override\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "${$get$capitalized_name$Value$}$() {\n" @@ -645,6 +664,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "${$get$capitalized_name$ValueMap$}$() {\n" @@ -655,6 +675,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" @@ -668,6 +689,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key) {\n" @@ -709,6 +731,7 @@ GenerateBuilderMembers(io::Printer* printer) const { "/**\n" " * Use {@link #get$capitalized_name$Map()} instead.\n" " */\n" + "@java.lang.Override\n" "@java.lang.Deprecated\n" "public java.util.Map<$type_parameters$> " "${$get$capitalized_name$$}$() {\n" @@ -718,6 +741,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$" "public java.util.Map<$type_parameters$> " "${$get$capitalized_name$Map$}$() {\n" @@ -728,6 +752,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" @@ -741,6 +766,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 8964f632..209c0b2a 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -38,9 +38,6 @@ #include <google/protobuf/stubs/hash.h> #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <vector> #include <google/protobuf/compiler/java/java_context.h> @@ -52,9 +49,9 @@ #include <google/protobuf/compiler/java/java_message_builder.h> #include <google/protobuf/compiler/java/java_message_builder_lite.h> #include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/substitute.h> #include <google/protobuf/stubs/strutil.h> @@ -438,7 +435,8 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); printer->Print( "$deprecation$$field_name$($field_number$),\n", - "deprecation", field->options().deprecated() ? "@java.lang.Deprecated " : "", + "deprecation", + field->options().deprecated() ? "@java.lang.Deprecated " : "", "field_name", ToUpper(field->name()), "field_number", SimpleItoa(field->number())); } @@ -578,7 +576,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { void ImmutableMessageGenerator:: GenerateMessageSerializationMethods(io::Printer* printer) { - google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields( + std::unique_ptr<const FieldDescriptor * []> sorted_fields( SortFieldsByNumber(descriptor_)); std::vector<const Descriptor::ExtensionRange*> sorted_extensions; @@ -1216,7 +1214,7 @@ GenerateExtensionRegistrationCode(io::Printer* printer) { // =================================================================== void ImmutableMessageGenerator:: GenerateParsingConstructor(io::Printer* printer) { - google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields( + std::unique_ptr<const FieldDescriptor * []> sorted_fields( SortFieldsByNumber(descriptor_)); printer->Print( diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc index 43c39b4a..4c67e806 100644 --- a/src/google/protobuf/compiler/java/java_message_builder.cc +++ b/src/google/protobuf/compiler/java/java_message_builder.cc @@ -38,9 +38,6 @@ #include <google/protobuf/stubs/hash.h> #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <vector> #include <google/protobuf/compiler/java/java_context.h> @@ -50,9 +47,9 @@ #include <google/protobuf/compiler/java/java_generator_factory.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/substitute.h> #include <google/protobuf/stubs/strutil.h> diff --git a/src/google/protobuf/compiler/java/java_message_builder_lite.cc b/src/google/protobuf/compiler/java/java_message_builder_lite.cc index 1ad58c09..f04d394e 100644 --- a/src/google/protobuf/compiler/java/java_message_builder_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_builder_lite.cc @@ -38,9 +38,6 @@ #include <google/protobuf/stubs/hash.h> #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <vector> #include <google/protobuf/compiler/java/java_context.h> @@ -50,12 +47,12 @@ #include <google/protobuf/compiler/java/java_generator_factory.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { @@ -109,6 +106,7 @@ Generate(io::Printer* printer) { // oneofCase() and clearOneof() printer->Print(vars, + "@java.lang.Override\n" "public $oneof_capitalized_name$Case\n" " get$oneof_capitalized_name$Case() {\n" " return instance.get$oneof_capitalized_name$Case();\n" diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.cc b/src/google/protobuf/compiler/java/java_message_field_lite.cc index df3e80d4..9cf6f363 100644 --- a/src/google/protobuf/compiler/java/java_message_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc @@ -147,12 +147,14 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); @@ -160,12 +162,14 @@ GenerateMembers(io::Printer* printer) const { } else { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $name$_ != null;\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); @@ -195,7 +199,11 @@ GenerateMembers(io::Printer* printer) const { // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.SuppressWarnings({\"ReferenceEquality\"})\n" "private void merge$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" " if ($name$_ != null &&\n" " $name$_ != $type$.getDefaultInstance()) {\n" " $name$_ =\n" @@ -223,6 +231,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // boolean hasField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); @@ -231,6 +240,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field getField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); @@ -396,12 +406,14 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" @@ -434,6 +446,9 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "private void merge$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" " if ($has_oneof_case_message$ &&\n" " $oneof_name$_ != $type$.getDefaultInstance()) {\n" " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n" @@ -464,6 +479,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // boolean hasField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); @@ -472,6 +488,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field getField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); @@ -624,6 +641,7 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<$type$> " "${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list @@ -638,12 +656,14 @@ GenerateMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); @@ -761,6 +781,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // List<Field> getRepeatedFieldList() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<$type$> " "${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList(\n" @@ -771,6 +792,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // int getRepeatedFieldCount() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}"); @@ -779,6 +801,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field getRepeatedField(int index) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index 108504c7..3a512e8d 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -38,9 +38,6 @@ #include <google/protobuf/stubs/hash.h> #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <vector> #include <google/protobuf/compiler/java/java_context.h> @@ -52,9 +49,9 @@ #include <google/protobuf/compiler/java/java_message_builder.h> #include <google/protobuf/compiler/java/java_message_builder_lite.h> #include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/substitute.h> #include <google/protobuf/stubs/strutil.h> @@ -310,6 +307,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { " default: return null;\n" " }\n" "}\n" + "@java.lang.Override\n" "public int getNumber() {\n" " return this.value;\n" "}\n", @@ -318,6 +316,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { printer->Print("};\n\n"); // oneofCase() printer->Print(vars, + "@java.lang.Override\n" "public $oneof_capitalized_name$Case\n" "get$oneof_capitalized_name$Case() {\n" " return $oneof_capitalized_name$Case.forNumber(\n" @@ -356,6 +355,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { } printer->Print( + "@java.lang.Override\n" "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n" "protected final java.lang.Object dynamicMethod(\n" " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" @@ -369,22 +369,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { printer->Indent(); printer->Indent(); - printer->Print("case IS_INITIALIZED: {\n"); - printer->Indent(); - GenerateDynamicMethodIsInitialized(printer); - printer->Outdent(); - - printer->Print("}\n"); - printer->Print( - "case MAKE_IMMUTABLE: {\n"); - - printer->Indent(); - GenerateDynamicMethodMakeImmutable(printer); - printer->Outdent(); - - printer->Print( - "}\n" "case NEW_BUILDER: {\n"); printer->Indent(); @@ -393,21 +378,38 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { if (!EnableExperimentalRuntimeForLite()) { printer->Print( + "}\n" + "case IS_INITIALIZED: {\n"); + printer->Indent(); + GenerateDynamicMethodIsInitialized(printer); + printer->Outdent(); + + printer->Print("}\n"); + + printer->Print( + "case MAKE_IMMUTABLE: {\n"); + + printer->Indent(); + GenerateDynamicMethodMakeImmutable(printer); + printer->Outdent(); + + printer->Print( "}\n" "case VISIT: {\n"); printer->Indent(); GenerateDynamicMethodVisit(printer); printer->Outdent(); - } - printer->Print( - "}\n" - "case MERGE_FROM_STREAM: {\n"); + printer->Print( + "}\n" + "case MERGE_FROM_STREAM: {\n"); + + printer->Indent(); + GenerateDynamicMethodMergeFromStream(printer); + printer->Outdent(); + } - printer->Indent(); - GenerateDynamicMethodMergeFromStream(printer); - printer->Outdent(); printer->Print( "}\n" @@ -420,14 +422,20 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { // manipulating static fields but that has exceptional cost on Android as // it will generate an extra class for every message. Instead, use the // double-check locking pattern which works just as well. - " if (PARSER == null) {" + // + // The "parser" temporary mirrors the "PARSER" field to eliminate a read + // at the final return statement. + " com.google.protobuf.Parser<$classname$> parser = PARSER;\n" + " if (parser == null) {\n" " synchronized ($classname$.class) {\n" - " if (PARSER == null) {\n" - " PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n" + " parser = PARSER;\n" + " if (parser == null) {\n" + " parser = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n" + " PARSER = parser;\n" " }\n" " }\n" " }\n" - " return PARSER;\n", + " return parser;\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); printer->Outdent(); @@ -475,8 +483,9 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { printer->Print( "static {\n" + " // New instances are implicitly immutable so no need to make\n" + " // immutable.\n" " DEFAULT_INSTANCE = new $classname$();\n" - " DEFAULT_INSTANCE.makeImmutable();\n" "}\n" "\n", "classname", descriptor_->name()); @@ -491,6 +500,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { "}\n", "classname", descriptor_->name()); } + printer->Print( "public static $classname$ getDefaultInstance() {\n" " return DEFAULT_INSTANCE;\n" @@ -519,6 +529,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { .Generate(printer); } + printer->Outdent(); printer->Print("}\n\n"); } @@ -528,7 +539,11 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { void ImmutableMessageLiteGenerator:: GenerateMessageSerializationMethods(io::Printer* printer) { - google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields( + if (EnableExperimentalRuntimeForLite()) { + return; + } + + std::unique_ptr<const FieldDescriptor * []> sorted_fields( SortFieldsByNumber(descriptor_)); std::vector<const Descriptor::ExtensionRange*> sorted_extensions; @@ -539,6 +554,7 @@ GenerateMessageSerializationMethods(io::Printer* printer) { ExtensionRangeOrdering()); printer->Print( + "@java.lang.Override\n" "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" " throws java.io.IOException {\n"); printer->Indent(); @@ -594,6 +610,7 @@ GenerateMessageSerializationMethods(io::Printer* printer) { printer->Print( "}\n" "\n" + "@java.lang.Override\n" "public int getSerializedSize() {\n" " int size = memoizedSerializedSize;\n" " if (size != -1) return size;\n" @@ -1005,7 +1022,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFromStream( " done = true;\n" " break;\n"); - google::protobuf::scoped_array<const FieldDescriptor* > sorted_fields( + std::unique_ptr<const FieldDescriptor* []> sorted_fields( SortFieldsByNumber(descriptor_)); for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = sorted_fields[i]; diff --git a/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/src/google/protobuf/compiler/java/java_plugin_unittest.cc index 3e4910c8..87f687da 100644 --- a/src/google/protobuf/compiler/java/java_plugin_unittest.cc +++ b/src/google/protobuf/compiler/java/java_plugin_unittest.cc @@ -35,9 +35,6 @@ // worth. #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/compiler/java/java_generator.h> #include <google/protobuf/compiler/command_line_interface.h> @@ -76,7 +73,7 @@ class TestGenerator : public CodeGenerator { void TryInsert(const string& filename, const string& insertion_point, GeneratorContext* context) const { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->OpenForInsert(filename, insertion_point)); io::Printer printer(output.get(), '$'); printer.Print("// inserted $name$\n", "name", insertion_point); diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index 074a6be8..71ee0992 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -633,8 +633,7 @@ GenerateMembers(io::Printer* printer) const { "}\n"); printer->Annotate("{", "}", descriptor_); - if (descriptor_->is_packed() && - context_->HasGeneratedMethods(descriptor_->containing_type())) { + if (descriptor_->is_packed()) { printer->Print(variables_, "private int $name$MemoizedSerializedSize = -1;\n"); } diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc index f9293171..d2ebc567 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc @@ -222,6 +222,7 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); @@ -230,6 +231,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); @@ -266,6 +268,7 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); @@ -274,6 +277,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); @@ -488,6 +492,7 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); @@ -496,6 +501,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($boxed_type$) $oneof_name$_;\n" @@ -528,6 +534,7 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); @@ -536,6 +543,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); @@ -645,6 +653,7 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<$boxed_type$>\n" " ${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list @@ -652,12 +661,14 @@ GenerateMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $repeated_get$(index);\n" "}\n"); @@ -711,6 +722,7 @@ void RepeatedImmutablePrimitiveFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<$boxed_type$>\n" " ${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList(\n" @@ -719,12 +731,14 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.cc b/src/google/protobuf/compiler/java/java_shared_code_generator.cc index 9a42aba9..0cec20b9 100644 --- a/src/google/protobuf/compiler/java/java_shared_code_generator.cc +++ b/src/google/protobuf/compiler/java/java_shared_code_generator.cc @@ -33,16 +33,13 @@ #include <google/protobuf/compiler/java/java_shared_code_generator.h> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.pb.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/stubs/strutil.h> @@ -69,11 +66,11 @@ void SharedCodeGenerator::Generate(GeneratorContext* context, string classname = name_resolver_->GetDescriptorClassName(file_); string filename = package_dir + classname + ".java"; file_list->push_back(filename); - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); + std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); GeneratedCodeInfo annotations; io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( &annotations); - google::protobuf::scoped_ptr<io::Printer> printer( + std::unique_ptr<io::Printer> printer( new io::Printer(output.get(), '$', options_.annotate_code ? &annotation_collector : NULL)); string info_relative_path = classname + ".java.pb.meta"; @@ -108,7 +105,7 @@ void SharedCodeGenerator::Generate(GeneratorContext* context, "}\n"); if (options_.annotate_code) { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output( + std::unique_ptr<io::ZeroCopyOutputStream> info_output( context->Open(info_full_path)); annotations.SerializeToZeroCopyStream(info_output.get()); annotation_file_list->push_back(info_full_path); diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.h b/src/google/protobuf/compiler/java/java_shared_code_generator.h index 40502270..58a31f5d 100644 --- a/src/google/protobuf/compiler/java/java_shared_code_generator.h +++ b/src/google/protobuf/compiler/java/java_shared_code_generator.h @@ -36,9 +36,6 @@ #define GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__ #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <string> #include <vector> @@ -77,7 +74,7 @@ class SharedCodeGenerator { void GenerateDescriptors(io::Printer* printer); private: - google::protobuf::scoped_ptr<ClassNameResolver> name_resolver_; + std::unique_ptr<ClassNameResolver> name_resolver_; const FileDescriptor* file_; const Options options_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SharedCodeGenerator); diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc index adda307c..a238c67d 100644 --- a/src/google/protobuf/compiler/java/java_string_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc @@ -192,6 +192,7 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); @@ -200,12 +201,14 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public com.google.protobuf.ByteString\n" " ${$get$capitalized_name$Bytes$}$() {\n" " return com.google.protobuf.ByteString.copyFromUtf8($name$_);\n" @@ -249,6 +252,7 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); @@ -257,6 +261,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); @@ -264,6 +269,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public com.google.protobuf.ByteString\n" " ${$get$capitalized_name$Bytes$}$() {\n" " return instance.get$capitalized_name$Bytes();\n" @@ -419,6 +425,7 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); @@ -427,6 +434,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.String ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" @@ -438,6 +446,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public com.google.protobuf.ByteString\n" " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.String ref $default_init$;\n" @@ -489,6 +498,7 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); @@ -497,6 +507,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); @@ -504,6 +515,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public com.google.protobuf.ByteString\n" " ${$get$capitalized_name$Bytes$}$() {\n" " return instance.get$capitalized_name$Bytes();\n" @@ -641,6 +653,7 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<java.lang.String> " "${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list @@ -648,12 +661,14 @@ GenerateMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.lang.String " "${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" @@ -661,6 +676,7 @@ GenerateMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public com.google.protobuf.ByteString\n" " ${$get$capitalized_name$Bytes$}$(int index) {\n" " return com.google.protobuf.ByteString.copyFromUtf8(\n" @@ -725,6 +741,7 @@ void RepeatedImmutableStringFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<java.lang.String>\n" " ${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList(\n" @@ -733,12 +750,14 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.lang.String " "${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" @@ -746,6 +765,7 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public com.google.protobuf.ByteString\n" " ${$get$capitalized_name$Bytes$}$(int index) {\n" " return instance.get$capitalized_name$Bytes(index);\n" diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index fd2d3dfd..d8282e40 100755 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -35,9 +35,6 @@ #include <limits> #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <string> #include <utility> #include <vector> @@ -52,6 +49,7 @@ #include <google/protobuf/descriptor.h> #include <google/protobuf/stubs/strutil.h> + namespace google { namespace protobuf { namespace compiler { @@ -2062,6 +2060,7 @@ void Generator::GenerateOneofCaseDefinition( " $upcase$: $number$", "upcase", ToEnumCase(oneof->field(i)->name()), "number", JSFieldIndex(oneof->field(i))); + printer->Annotate("upcase", oneof->field(i)); } printer->Print( @@ -2768,28 +2767,33 @@ void Generator::GenerateClassField(const GeneratorOptions& options, void Generator::GenerateRepeatedPrimitiveHelperMethods( const GeneratorOptions& options, io::Printer* printer, const FieldDescriptor* field, bool untyped) const { + // clang-format off printer->Print( "/**\n" " * @param {!$optionaltype$} value\n" - " * @param {number=} opt_index\n" + " * @param {number=} opt_index$returndoc$\n" " */\n" "$class$.prototype.$addername$ = function(value, opt_index) {\n" " jspb.Message.addToRepeatedField(this, $index$", "class", GetMessagePath(options, field->containing_type()), "addername", "add" + JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true), - "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "index", - JSFieldIndex(field)); + "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), + "index", JSFieldIndex(field), + "returndoc", JSReturnDoc(options, field)); printer->Annotate("addername", field); printer->Print( - "$oneofgroup$, $type$value$rptvalueinit$$typeclose$, opt_index);\n" + "$oneofgroup$, $type$value$rptvalueinit$$typeclose$, " + "opt_index);$returnvalue$\n" "};\n" "\n" "\n", "type", untyped ? "/** @type{string|number|boolean|!Uint8Array} */(" : "", "typeclose", untyped ? ")" : "", "oneofgroup", (field->containing_oneof() ? (", " + JSOneofArray(options, field)) : ""), - "rptvalueinit", ""); + "rptvalueinit", "", + "returnvalue", JSReturnClause(field)); + // clang-format on } void Generator::GenerateRepeatedMessageHelperMethods( @@ -3206,21 +3210,24 @@ void Generator::GenerateExtension(const GeneratorOptions& options, ? GetMessagePath(options, field->extension_scope()) : GetFilePath(options, field->file())); + const string extension_object_name = JSObjectFieldName(options, field); printer->Print( "\n" "/**\n" " * A tuple of {field number, class constructor} for the extension\n" - " * field named `$name$`.\n" + " * field named `$nameInComment$`.\n" " * @type {!jspb.ExtensionFieldInfo<$extensionType$>}\n" " */\n" "$class$.$name$ = new jspb.ExtensionFieldInfo(\n", - "name", JSObjectFieldName(options, field), + "nameInComment", extension_object_name, + "name", extension_object_name, "class", extension_scope, "extensionType", JSFieldTypeAnnotation( options, field, /* is_setter_argument = */ false, /* force_present = */ true, /* singular_if_not_packed = */ false)); + printer->Annotate("name", field); printer->Print( " $index$,\n" " {$name$: 0},\n" @@ -3230,7 +3237,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options, " $toObject$),\n" " $repeated$);\n", "index", SimpleItoa(field->number()), - "name", JSObjectFieldName(options, field), + "name", extension_object_name, "ctor", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ? SubmessageTypeRef(options, field) : string("null")), "toObject", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ? @@ -3249,7 +3256,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options, "extendName", JSExtensionsObjectName(options, field->file(), field->containing_type()), "index", SimpleItoa(field->number()), "class", extension_scope, "name", - JSObjectFieldName(options, field), "binaryReaderFn", + extension_object_name, "binaryReaderFn", JSBinaryReaderMethodName(options, field), "binaryWriterFn", JSBinaryWriterMethodName(options, field), "binaryMessageSerializeFn", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) @@ -3272,7 +3279,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options, field->containing_type()), "index", SimpleItoa(field->number()), "class", extension_scope, - "name", JSObjectFieldName(options, field)); + "name", extension_object_name); } bool GeneratorOptions::ParseFromOptions( @@ -3500,7 +3507,7 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files, // All output should go in a single file. string filename = options.output_dir + "/" + options.library + options.GetFileNameExtension(); - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); + std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); GOOGLE_CHECK(output.get()); io::Printer printer(output.get(), '$'); @@ -3549,7 +3556,7 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files, } string filename = GetMessageFileName(options, desc); - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->Open(filename)); GOOGLE_CHECK(output.get()); io::Printer printer(output.get(), '$'); @@ -3575,7 +3582,7 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files, } string filename = GetEnumFileName(options, enumdesc); - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->Open(filename)); GOOGLE_CHECK(output.get()); io::Printer printer(output.get(), '$'); @@ -3598,7 +3605,7 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files, if (allowed_set.count(file) == 1) { string filename = GetExtensionFileName(options, file); - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->Open(filename)); GOOGLE_CHECK(output.get()); io::Printer printer(output.get(), '$'); @@ -3634,7 +3641,7 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files, string filename = options.output_dir + "/" + GetJSFilename(options, file->name()); - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); + std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); GOOGLE_CHECK(output.get()); GeneratedCodeInfo annotations; io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index 7719ec3d..e150f97d 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -35,9 +35,6 @@ #include <stdlib.h> #include <iostream> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <vector> @@ -103,8 +100,7 @@ void MockCodeGenerator::ExpectGenerated( File::GetContents(output_directory + "/" + GetOutputFileName(name, file), &content, true)); - std::vector<string> lines = - Split(content, "\n", true); + std::vector<string> lines = Split(content, "\n", true); while (!lines.empty() && lines.back().empty()) { lines.pop_back(); @@ -232,7 +228,7 @@ bool MockCodeGenerator::Generate( for (size_t i = 0; i < insert_into.size(); i++) { { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert( + std::unique_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert( GetOutputFileName(insert_into[i], file), kFirstInsertionPointName)); io::Printer printer(output.get(), '$'); printer.PrintRaw(GetOutputFileContent(name_, "first_insert", @@ -244,7 +240,7 @@ bool MockCodeGenerator::Generate( } { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->OpenForInsert(GetOutputFileName(insert_into[i], file), kSecondInsertionPointName)); io::Printer printer(output.get(), '$'); @@ -257,7 +253,7 @@ bool MockCodeGenerator::Generate( } } } else { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->Open(GetOutputFileName(name_, file))); GeneratedCodeInfo annotations; @@ -287,7 +283,7 @@ bool MockCodeGenerator::Generate( return false; } if (annotate) { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> meta_output( + std::unique_ptr<io::ZeroCopyOutputStream> meta_output( context->Open(GetOutputFileName(name_, file) + ".meta")); if (!TextFormat::Print(annotations, meta_output.get())) { *error = "MockCodeGenerator couldn't write .meta"; diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 03d05ad4..df81e55f 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -39,13 +39,14 @@ #include <limits> +#include <google/protobuf/stubs/casts.h> +#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/stubs/common.h> #include <google/protobuf/compiler/parser.h> -#include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/wire_format.h> #include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/stubs/logging.h> -#include <google/protobuf/stubs/common.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/map_util.h> @@ -1650,10 +1651,6 @@ bool Parser::ParseReservedNumbers(EnumDescriptorProto* message, if (TryConsume("max")) { // This is in the enum descriptor path, which doesn't have the message // set duality to fix up, so it doesn't integrate with the sentinel. - - // Evaluate 'max' to INT_MAX - 1 so that incrementing to create the - // exclusive range end doesn't cause an overflow. - // Note, this prevents reserving the actual INT_MAX enum value. end = INT_MAX; } else { DO(ConsumeSignedInteger(&end, "Expected integer.")); diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h index 33b4c700..01d8a66b 100644 --- a/src/google/protobuf/compiler/parser.h +++ b/src/google/protobuf/compiler/parser.h @@ -40,10 +40,10 @@ #include <map> #include <string> #include <utility> -#include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/repeated_field.h> #include <google/protobuf/io/tokenizer.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/repeated_field.h> namespace google { namespace protobuf { class Message; } diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index 9b59842e..0725a682 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -33,9 +33,6 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <vector> #include <algorithm> #include <map> @@ -50,6 +47,7 @@ #include <google/protobuf/text_format.h> #include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/substitute.h> + #include <google/protobuf/stubs/map_util.h> #include <google/protobuf/testing/googletest.h> @@ -177,9 +175,9 @@ class ParserTest : public testing::Test { MockErrorCollector error_collector_; DescriptorPool pool_; - google::protobuf::scoped_ptr<io::ZeroCopyInputStream> raw_input_; - google::protobuf::scoped_ptr<io::Tokenizer> input_; - google::protobuf::scoped_ptr<Parser> parser_; + std::unique_ptr<io::ZeroCopyInputStream> raw_input_; + std::unique_ptr<io::Tokenizer> input_; + std::unique_ptr<Parser> parser_; bool require_syntax_identifier_; }; diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index bde3d798..9c1c757c 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -45,8 +45,8 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/compiler/plugin.pb.h> #include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/descriptor.h> #include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.h> #include <google/protobuf/stubs/io_win32.h> diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index d13ad2b3..ef52def3 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -7,7 +7,6 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/port.h> -#include <google/protobuf/stubs/once.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/wire_format_lite_inl.h> #include <google/protobuf/descriptor.h> @@ -19,6 +18,14 @@ #include "third_party/protobuf/version.h" #endif // @@protoc_insertion_point(includes) + +namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto { +extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File; +extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Version; +} // namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto +namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto { +extern PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fdescriptor_2eproto ::google::protobuf::internal::SCCInfo<6> scc_info_FileDescriptorProto; +} // namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto namespace google { namespace protobuf { namespace compiler { @@ -46,14 +53,9 @@ class CodeGeneratorResponseDefaultTypeInternal { } // namespace protobuf } // namespace google namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto { -void InitDefaultsVersionImpl() { +static void InitDefaultsVersion() { GOOGLE_PROTOBUF_VERIFY_VERSION; -#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS - ::google::protobuf::internal::InitProtobufDefaultsForceUnique(); -#else - ::google::protobuf::internal::InitProtobufDefaults(); -#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS { void* ptr = &::google::protobuf::compiler::_Version_default_instance_; new (ptr) ::google::protobuf::compiler::Version(); @@ -62,21 +64,12 @@ void InitDefaultsVersionImpl() { ::google::protobuf::compiler::Version::InitAsDefaultInstance(); } -void InitDefaultsVersion() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsVersionImpl); -} +LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_Version = + {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsVersion}, {}}; -void InitDefaultsCodeGeneratorRequestImpl() { +static void InitDefaultsCodeGeneratorRequest() { GOOGLE_PROTOBUF_VERIFY_VERSION; -#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS - ::google::protobuf::internal::InitProtobufDefaultsForceUnique(); -#else - ::google::protobuf::internal::InitProtobufDefaults(); -#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS - protobuf_google_2fprotobuf_2fdescriptor_2eproto::InitDefaultsFileDescriptorProto(); - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsVersion(); { void* ptr = &::google::protobuf::compiler::_CodeGeneratorRequest_default_instance_; new (ptr) ::google::protobuf::compiler::CodeGeneratorRequest(); @@ -85,19 +78,14 @@ void InitDefaultsCodeGeneratorRequestImpl() { ::google::protobuf::compiler::CodeGeneratorRequest::InitAsDefaultInstance(); } -void InitDefaultsCodeGeneratorRequest() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsCodeGeneratorRequestImpl); -} +LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<2> scc_info_CodeGeneratorRequest = + {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 2, InitDefaultsCodeGeneratorRequest}, { + &protobuf_google_2fprotobuf_2fdescriptor_2eproto::scc_info_FileDescriptorProto.base, + &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_Version.base,}}; -void InitDefaultsCodeGeneratorResponse_FileImpl() { +static void InitDefaultsCodeGeneratorResponse_File() { GOOGLE_PROTOBUF_VERIFY_VERSION; -#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS - ::google::protobuf::internal::InitProtobufDefaultsForceUnique(); -#else - ::google::protobuf::internal::InitProtobufDefaults(); -#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS { void* ptr = &::google::protobuf::compiler::_CodeGeneratorResponse_File_default_instance_; new (ptr) ::google::protobuf::compiler::CodeGeneratorResponse_File(); @@ -106,20 +94,12 @@ void InitDefaultsCodeGeneratorResponse_FileImpl() { ::google::protobuf::compiler::CodeGeneratorResponse_File::InitAsDefaultInstance(); } -void InitDefaultsCodeGeneratorResponse_File() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsCodeGeneratorResponse_FileImpl); -} +LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File = + {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsCodeGeneratorResponse_File}, {}}; -void InitDefaultsCodeGeneratorResponseImpl() { +static void InitDefaultsCodeGeneratorResponse() { GOOGLE_PROTOBUF_VERIFY_VERSION; -#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS - ::google::protobuf::internal::InitProtobufDefaultsForceUnique(); -#else - ::google::protobuf::internal::InitProtobufDefaults(); -#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse_File(); { void* ptr = &::google::protobuf::compiler::_CodeGeneratorResponse_default_instance_; new (ptr) ::google::protobuf::compiler::CodeGeneratorResponse(); @@ -128,9 +108,15 @@ void InitDefaultsCodeGeneratorResponseImpl() { ::google::protobuf::compiler::CodeGeneratorResponse::InitAsDefaultInstance(); } -void InitDefaultsCodeGeneratorResponse() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsCodeGeneratorResponseImpl); +LIBPROTOC_EXPORT ::google::protobuf::internal::SCCInfo<1> scc_info_CodeGeneratorResponse = + {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsCodeGeneratorResponse}, { + &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorResponse_File.base,}}; + +void InitDefaults() { + ::google::protobuf::internal::InitSCC(&scc_info_Version.base); + ::google::protobuf::internal::InitSCC(&scc_info_CodeGeneratorRequest.base); + ::google::protobuf::internal::InitSCC(&scc_info_CodeGeneratorResponse_File.base); + ::google::protobuf::internal::InitSCC(&scc_info_CodeGeneratorResponse.base); } ::google::protobuf::Metadata file_level_metadata[4]; @@ -199,15 +185,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { void protobuf_AssignDescriptors() { AddDescriptors(); - ::google::protobuf::MessageFactory* factory = NULL; AssignDescriptors( - "google/protobuf/compiler/plugin.proto", schemas, file_default_instances, TableStruct::offsets, factory, + "google/protobuf/compiler/plugin.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, NULL, NULL); } void protobuf_AssignDescriptorsOnce() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors); + static ::google::protobuf::internal::once_flag once; + ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD; @@ -244,8 +229,8 @@ void AddDescriptorsImpl() { } void AddDescriptors() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl); + static ::google::protobuf::internal::once_flag once; + ::google::protobuf::internal::call_once(once, AddDescriptorsImpl); } // Force AddDescriptors() to be called at dynamic initialization time. struct StaticDescriptorInitializer { @@ -271,17 +256,15 @@ const int Version::kSuffixFieldNumber; Version::Version() : ::google::protobuf::Message(), _internal_metadata_(NULL) { - if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsVersion(); - } + ::google::protobuf::internal::InitSCC( + &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_Version.base); SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.Version) } Version::Version(const Version& from) : ::google::protobuf::Message(), _internal_metadata_(NULL), - _has_bits_(from._has_bits_), - _cached_size_(0) { + _has_bits_(from._has_bits_) { _internal_metadata_.MergeFrom(from._internal_metadata_); suffix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); if (from.has_suffix()) { @@ -294,7 +277,6 @@ Version::Version(const Version& from) } void Version::SharedCtor() { - _cached_size_ = 0; suffix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); ::memset(&major_, 0, static_cast<size_t>( reinterpret_cast<char*>(&patch_) - @@ -311,9 +293,7 @@ void Version::SharedDtor() { } void Version::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); + _cached_size_.Set(size); } const ::google::protobuf::Descriptor* Version::descriptor() { ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); @@ -321,7 +301,7 @@ const ::google::protobuf::Descriptor* Version::descriptor() { } const Version& Version::default_instance() { - ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsVersion(); + ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_Version.base); return *internal_default_instance(); } @@ -334,8 +314,7 @@ void Version::Clear() { cached_has_bits = _has_bits_[0]; if (cached_has_bits & 0x00000001u) { - GOOGLE_DCHECK(!suffix_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - suffix_.UnsafeMutablePointer()->clear(); + suffix_.ClearNonDefaultToEmptyNoArena(); } if (cached_has_bits & 14u) { ::memset(&major_, 0, static_cast<size_t>( @@ -352,7 +331,7 @@ bool Version::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; // @@protoc_insertion_point(parse_start:google.protobuf.compiler.Version) for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); tag = p.first; if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { @@ -555,9 +534,7 @@ size_t Version::ByteSizeLong() const { } int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = cached_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); + SetCachedSize(cached_size); return total_size; } @@ -626,13 +603,13 @@ void Version::Swap(Version* other) { } void Version::InternalSwap(Version* other) { using std::swap; - suffix_.Swap(&other->suffix_); + suffix_.Swap(&other->suffix_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); swap(major_, other->major_); swap(minor_, other->minor_); swap(patch_, other->patch_); swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Version::GetMetadata() const { @@ -659,9 +636,8 @@ const int CodeGeneratorRequest::kCompilerVersionFieldNumber; CodeGeneratorRequest::CodeGeneratorRequest() : ::google::protobuf::Message(), _internal_metadata_(NULL) { - if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorRequest(); - } + ::google::protobuf::internal::InitSCC( + &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorRequest.base); SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorRequest) } @@ -669,7 +645,6 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) : ::google::protobuf::Message(), _internal_metadata_(NULL), _has_bits_(from._has_bits_), - _cached_size_(0), file_to_generate_(from.file_to_generate_), proto_file_(from.proto_file_) { _internal_metadata_.MergeFrom(from._internal_metadata_); @@ -686,7 +661,6 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) } void CodeGeneratorRequest::SharedCtor() { - _cached_size_ = 0; parameter_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); compiler_version_ = NULL; } @@ -702,9 +676,7 @@ void CodeGeneratorRequest::SharedDtor() { } void CodeGeneratorRequest::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); + _cached_size_.Set(size); } const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() { ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); @@ -712,7 +684,7 @@ const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() { } const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() { - ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorRequest(); + ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorRequest.base); return *internal_default_instance(); } @@ -728,8 +700,7 @@ void CodeGeneratorRequest::Clear() { cached_has_bits = _has_bits_[0]; if (cached_has_bits & 3u) { if (cached_has_bits & 0x00000001u) { - GOOGLE_DCHECK(!parameter_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - parameter_.UnsafeMutablePointer()->clear(); + parameter_.ClearNonDefaultToEmptyNoArena(); } if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(compiler_version_ != NULL); @@ -746,7 +717,7 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorRequest) for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); tag = p.first; if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { @@ -857,7 +828,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( // optional .google.protobuf.compiler.Version compiler_version = 3; if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 3, *compiler_version_, output); + 3, this->_internal_compiler_version(), output); } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; @@ -909,7 +880,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageToArray( - 3, *compiler_version_, deterministic, target); + 3, this->_internal_compiler_version(), deterministic, target); } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; @@ -973,9 +944,7 @@ size_t CodeGeneratorRequest::ByteSizeLong() const { } int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = cached_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); + SetCachedSize(cached_size); return total_size; } @@ -1042,11 +1011,11 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { using std::swap; file_to_generate_.InternalSwap(CastToBase(&other->file_to_generate_)); CastToBase(&proto_file_)->InternalSwap(CastToBase(&other->proto_file_)); - parameter_.Swap(&other->parameter_); + parameter_.Swap(&other->parameter_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); swap(compiler_version_, other->compiler_version_); swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const { @@ -1067,17 +1036,15 @@ const int CodeGeneratorResponse_File::kContentFieldNumber; CodeGeneratorResponse_File::CodeGeneratorResponse_File() : ::google::protobuf::Message(), _internal_metadata_(NULL) { - if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse_File(); - } + ::google::protobuf::internal::InitSCC( + &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorResponse_File.base); SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) : ::google::protobuf::Message(), _internal_metadata_(NULL), - _has_bits_(from._has_bits_), - _cached_size_(0) { + _has_bits_(from._has_bits_) { _internal_metadata_.MergeFrom(from._internal_metadata_); name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); if (from.has_name()) { @@ -1095,7 +1062,6 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon } void CodeGeneratorResponse_File::SharedCtor() { - _cached_size_ = 0; name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); insertion_point_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); content_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -1113,9 +1079,7 @@ void CodeGeneratorResponse_File::SharedDtor() { } void CodeGeneratorResponse_File::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); + _cached_size_.Set(size); } const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() { ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); @@ -1123,7 +1087,7 @@ const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() { } const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() { - ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse_File(); + ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorResponse_File.base); return *internal_default_instance(); } @@ -1137,16 +1101,13 @@ void CodeGeneratorResponse_File::Clear() { cached_has_bits = _has_bits_[0]; if (cached_has_bits & 7u) { if (cached_has_bits & 0x00000001u) { - GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - name_.UnsafeMutablePointer()->clear(); + name_.ClearNonDefaultToEmptyNoArena(); } if (cached_has_bits & 0x00000002u) { - GOOGLE_DCHECK(!insertion_point_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - insertion_point_.UnsafeMutablePointer()->clear(); + insertion_point_.ClearNonDefaultToEmptyNoArena(); } if (cached_has_bits & 0x00000004u) { - GOOGLE_DCHECK(!content_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - content_.UnsafeMutablePointer()->clear(); + content_.ClearNonDefaultToEmptyNoArena(); } } _has_bits_.Clear(); @@ -1159,7 +1120,7 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorResponse.File) for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); tag = p.first; if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { @@ -1357,9 +1318,7 @@ size_t CodeGeneratorResponse_File::ByteSizeLong() const { } int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = cached_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); + SetCachedSize(cached_size); return total_size; } @@ -1426,12 +1385,14 @@ void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) { } void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) { using std::swap; - name_.Swap(&other->name_); - insertion_point_.Swap(&other->insertion_point_); - content_.Swap(&other->content_); + name_.Swap(&other->name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); + insertion_point_.Swap(&other->insertion_point_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); + content_.Swap(&other->content_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const { @@ -1451,9 +1412,8 @@ const int CodeGeneratorResponse::kFileFieldNumber; CodeGeneratorResponse::CodeGeneratorResponse() : ::google::protobuf::Message(), _internal_metadata_(NULL) { - if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse(); - } + ::google::protobuf::internal::InitSCC( + &protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorResponse.base); SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse) } @@ -1461,7 +1421,6 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) : ::google::protobuf::Message(), _internal_metadata_(NULL), _has_bits_(from._has_bits_), - _cached_size_(0), file_(from.file_) { _internal_metadata_.MergeFrom(from._internal_metadata_); error_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -1472,7 +1431,6 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) } void CodeGeneratorResponse::SharedCtor() { - _cached_size_ = 0; error_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } @@ -1486,9 +1444,7 @@ void CodeGeneratorResponse::SharedDtor() { } void CodeGeneratorResponse::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); + _cached_size_.Set(size); } const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() { ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); @@ -1496,7 +1452,7 @@ const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() { } const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() { - ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse(); + ::google::protobuf::internal::InitSCC(&protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::scc_info_CodeGeneratorResponse.base); return *internal_default_instance(); } @@ -1510,8 +1466,7 @@ void CodeGeneratorResponse::Clear() { file_.Clear(); cached_has_bits = _has_bits_[0]; if (cached_has_bits & 0x00000001u) { - GOOGLE_DCHECK(!error_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - error_.UnsafeMutablePointer()->clear(); + error_.ClearNonDefaultToEmptyNoArena(); } _has_bits_.Clear(); _internal_metadata_.Clear(); @@ -1523,7 +1478,7 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorResponse) for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); tag = p.first; if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { @@ -1671,9 +1626,7 @@ size_t CodeGeneratorResponse::ByteSizeLong() const { } int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = cached_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); + SetCachedSize(cached_size); return total_size; } @@ -1731,10 +1684,10 @@ void CodeGeneratorResponse::Swap(CodeGeneratorResponse* other) { void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { using std::swap; CastToBase(&file_)->InternalSwap(CastToBase(&other->file_)); - error_.Swap(&other->error_); + error_.Swap(&other->error_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const { @@ -1749,16 +1702,16 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { } // namespace google namespace google { namespace protobuf { -template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::Version* Arena::Create< ::google::protobuf::compiler::Version >(Arena* arena) { +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::Version* Arena::CreateMaybeMessage< ::google::protobuf::compiler::Version >(Arena* arena) { return Arena::CreateInternal< ::google::protobuf::compiler::Version >(arena); } -template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::CodeGeneratorRequest* Arena::Create< ::google::protobuf::compiler::CodeGeneratorRequest >(Arena* arena) { +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::CodeGeneratorRequest* Arena::CreateMaybeMessage< ::google::protobuf::compiler::CodeGeneratorRequest >(Arena* arena) { return Arena::CreateInternal< ::google::protobuf::compiler::CodeGeneratorRequest >(arena); } -template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::CodeGeneratorResponse_File* Arena::Create< ::google::protobuf::compiler::CodeGeneratorResponse_File >(Arena* arena) { +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::CodeGeneratorResponse_File* Arena::CreateMaybeMessage< ::google::protobuf::compiler::CodeGeneratorResponse_File >(Arena* arena) { return Arena::CreateInternal< ::google::protobuf::compiler::CodeGeneratorResponse_File >(arena); } -template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::CodeGeneratorResponse* Arena::Create< ::google::protobuf::compiler::CodeGeneratorResponse >(Arena* arena) { +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::CodeGeneratorResponse* Arena::CreateMaybeMessage< ::google::protobuf::compiler::CodeGeneratorResponse >(Arena* arena) { return Arena::CreateInternal< ::google::protobuf::compiler::CodeGeneratorResponse >(arena); } } // namespace protobuf diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index a6c1300e..5ad6b4d3 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -1,8 +1,8 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/compiler/plugin.proto -#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto_INCLUDED -#define PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto_INCLUDED +#ifndef PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto +#define PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto #include <string> @@ -24,6 +24,7 @@ #include <google/protobuf/arenastring.h> #include <google/protobuf/generated_message_table_driven.h> #include <google/protobuf/generated_message_util.h> +#include <google/protobuf/inlined_string_field.h> #include <google/protobuf/metadata.h> #include <google/protobuf/message.h> #include <google/protobuf/repeated_field.h> // IWYU pragma: export @@ -31,6 +32,7 @@ #include <google/protobuf/unknown_field_set.h> #include <google/protobuf/descriptor.pb.h> // @@protoc_insertion_point(includes) +#define PROTOBUF_INTERNAL_EXPORT_protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto LIBPROTOC_EXPORT #ifdef major #undef major #endif @@ -49,20 +51,6 @@ struct LIBPROTOC_EXPORT TableStruct { static const ::google::protobuf::uint32 offsets[]; }; void LIBPROTOC_EXPORT AddDescriptors(); -void LIBPROTOC_EXPORT InitDefaultsVersionImpl(); -void LIBPROTOC_EXPORT InitDefaultsVersion(); -void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorRequestImpl(); -void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorRequest(); -void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorResponse_FileImpl(); -void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorResponse_File(); -void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorResponseImpl(); -void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorResponse(); -inline void LIBPROTOC_EXPORT InitDefaults() { - InitDefaultsVersion(); - InitDefaultsCodeGeneratorRequest(); - InitDefaultsCodeGeneratorResponse_File(); - InitDefaultsCodeGeneratorResponse(); -} } // namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto namespace google { namespace protobuf { @@ -84,10 +72,10 @@ LIBPROTOC_EXPORT extern VersionDefaultTypeInternal _Version_default_instance_; } // namespace google namespace google { namespace protobuf { -template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorRequest* Arena::Create< ::google::protobuf::compiler::CodeGeneratorRequest>(Arena*); -template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorResponse* Arena::Create< ::google::protobuf::compiler::CodeGeneratorResponse>(Arena*); -template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorResponse_File* Arena::Create< ::google::protobuf::compiler::CodeGeneratorResponse_File>(Arena*); -template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::Version* Arena::Create< ::google::protobuf::compiler::Version>(Arena*); +template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorRequest* Arena::CreateMaybeMessage<::google::protobuf::compiler::CodeGeneratorRequest>(Arena*); +template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorResponse* Arena::CreateMaybeMessage<::google::protobuf::compiler::CodeGeneratorResponse>(Arena*); +template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorResponse_File* Arena::CreateMaybeMessage<::google::protobuf::compiler::CodeGeneratorResponse_File>(Arena*); +template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::Version* Arena::CreateMaybeMessage<::google::protobuf::compiler::Version>(Arena*); } // namespace protobuf } // namespace google namespace google { @@ -137,7 +125,7 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ return reinterpret_cast<const Version*>( &_Version_default_instance_); } - static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + static constexpr int kIndexInFileMessages = 0; void Swap(Version* other); @@ -147,32 +135,33 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ // implements Message ---------------------------------------------- - inline Version* New() const PROTOBUF_FINAL { - return ::google::protobuf::Arena::Create<Version>(NULL); + inline Version* New() const final { + return CreateMaybeMessage<Version>(NULL); } - Version* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL { - return ::google::protobuf::Arena::Create<Version>(arena); + Version* New(::google::protobuf::Arena* arena) const final { + return CreateMaybeMessage<Version>(arena); } - void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; - void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; + void CopyFrom(const ::google::protobuf::Message& from) final; + void MergeFrom(const ::google::protobuf::Message& from) final; void CopyFrom(const Version& from); void MergeFrom(const Version& from); - void Clear() PROTOBUF_FINAL; - bool IsInitialized() const PROTOBUF_FINAL; + void Clear() final; + bool IsInitialized() const final; - size_t ByteSizeLong() const PROTOBUF_FINAL; + size_t ByteSizeLong() const final; bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; + ::google::protobuf::io::CodedInputStream* input) final; void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; + ::google::protobuf::io::CodedOutputStream* output) const final; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } + bool deterministic, ::google::protobuf::uint8* target) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const PROTOBUF_FINAL; + void SetCachedSize(int size) const final; void InternalSwap(Version* other); private: inline ::google::protobuf::Arena* GetArenaNoVirtual() const { @@ -183,7 +172,7 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ } public: - ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL; + ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -238,13 +227,12 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; ::google::protobuf::internal::HasBits<1> _has_bits_; - mutable int _cached_size_; + mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr suffix_; ::google::protobuf::int32 major_; ::google::protobuf::int32 minor_; ::google::protobuf::int32 patch_; friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; - friend void ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsVersionImpl(); }; // ------------------------------------------------------------------- @@ -289,7 +277,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message return reinterpret_cast<const CodeGeneratorRequest*>( &_CodeGeneratorRequest_default_instance_); } - static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + static constexpr int kIndexInFileMessages = 1; void Swap(CodeGeneratorRequest* other); @@ -299,32 +287,33 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message // implements Message ---------------------------------------------- - inline CodeGeneratorRequest* New() const PROTOBUF_FINAL { - return ::google::protobuf::Arena::Create<CodeGeneratorRequest>(NULL); + inline CodeGeneratorRequest* New() const final { + return CreateMaybeMessage<CodeGeneratorRequest>(NULL); } - CodeGeneratorRequest* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL { - return ::google::protobuf::Arena::Create<CodeGeneratorRequest>(arena); + CodeGeneratorRequest* New(::google::protobuf::Arena* arena) const final { + return CreateMaybeMessage<CodeGeneratorRequest>(arena); } - void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; - void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; + void CopyFrom(const ::google::protobuf::Message& from) final; + void MergeFrom(const ::google::protobuf::Message& from) final; void CopyFrom(const CodeGeneratorRequest& from); void MergeFrom(const CodeGeneratorRequest& from); - void Clear() PROTOBUF_FINAL; - bool IsInitialized() const PROTOBUF_FINAL; + void Clear() final; + bool IsInitialized() const final; - size_t ByteSizeLong() const PROTOBUF_FINAL; + size_t ByteSizeLong() const final; bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; + ::google::protobuf::io::CodedInputStream* input) final; void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; + ::google::protobuf::io::CodedOutputStream* output) const final; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } + bool deterministic, ::google::protobuf::uint8* target) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const PROTOBUF_FINAL; + void SetCachedSize(int size) const final; void InternalSwap(CodeGeneratorRequest* other); private: inline ::google::protobuf::Arena* GetArenaNoVirtual() const { @@ -335,7 +324,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message } public: - ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL; + ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -394,6 +383,9 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message bool has_compiler_version() const; void clear_compiler_version(); static const int kCompilerVersionFieldNumber = 3; + private: + const ::google::protobuf::compiler::Version& _internal_compiler_version() const; + public: const ::google::protobuf::compiler::Version& compiler_version() const; ::google::protobuf::compiler::Version* release_compiler_version(); ::google::protobuf::compiler::Version* mutable_compiler_version(); @@ -408,13 +400,12 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; ::google::protobuf::internal::HasBits<1> _has_bits_; - mutable int _cached_size_; + mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_; ::google::protobuf::internal::ArenaStringPtr parameter_; ::google::protobuf::compiler::Version* compiler_version_; friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; - friend void ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorRequestImpl(); }; // ------------------------------------------------------------------- @@ -459,7 +450,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M return reinterpret_cast<const CodeGeneratorResponse_File*>( &_CodeGeneratorResponse_File_default_instance_); } - static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + static constexpr int kIndexInFileMessages = 2; void Swap(CodeGeneratorResponse_File* other); @@ -469,32 +460,33 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M // implements Message ---------------------------------------------- - inline CodeGeneratorResponse_File* New() const PROTOBUF_FINAL { - return ::google::protobuf::Arena::Create<CodeGeneratorResponse_File>(NULL); + inline CodeGeneratorResponse_File* New() const final { + return CreateMaybeMessage<CodeGeneratorResponse_File>(NULL); } - CodeGeneratorResponse_File* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL { - return ::google::protobuf::Arena::Create<CodeGeneratorResponse_File>(arena); + CodeGeneratorResponse_File* New(::google::protobuf::Arena* arena) const final { + return CreateMaybeMessage<CodeGeneratorResponse_File>(arena); } - void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; - void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; + void CopyFrom(const ::google::protobuf::Message& from) final; + void MergeFrom(const ::google::protobuf::Message& from) final; void CopyFrom(const CodeGeneratorResponse_File& from); void MergeFrom(const CodeGeneratorResponse_File& from); - void Clear() PROTOBUF_FINAL; - bool IsInitialized() const PROTOBUF_FINAL; + void Clear() final; + bool IsInitialized() const final; - size_t ByteSizeLong() const PROTOBUF_FINAL; + size_t ByteSizeLong() const final; bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; + ::google::protobuf::io::CodedInputStream* input) final; void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; + ::google::protobuf::io::CodedOutputStream* output) const final; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } + bool deterministic, ::google::protobuf::uint8* target) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const PROTOBUF_FINAL; + void SetCachedSize(int size) const final; void InternalSwap(CodeGeneratorResponse_File* other); private: inline ::google::protobuf::Arena* GetArenaNoVirtual() const { @@ -505,7 +497,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M } public: - ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL; + ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -567,12 +559,11 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; ::google::protobuf::internal::HasBits<1> _has_bits_; - mutable int _cached_size_; + mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::internal::ArenaStringPtr insertion_point_; ::google::protobuf::internal::ArenaStringPtr content_; friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; - friend void ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse_FileImpl(); }; // ------------------------------------------------------------------- @@ -617,7 +608,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag return reinterpret_cast<const CodeGeneratorResponse*>( &_CodeGeneratorResponse_default_instance_); } - static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + static constexpr int kIndexInFileMessages = 3; void Swap(CodeGeneratorResponse* other); @@ -627,32 +618,33 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag // implements Message ---------------------------------------------- - inline CodeGeneratorResponse* New() const PROTOBUF_FINAL { - return ::google::protobuf::Arena::Create<CodeGeneratorResponse>(NULL); + inline CodeGeneratorResponse* New() const final { + return CreateMaybeMessage<CodeGeneratorResponse>(NULL); } - CodeGeneratorResponse* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL { - return ::google::protobuf::Arena::Create<CodeGeneratorResponse>(arena); + CodeGeneratorResponse* New(::google::protobuf::Arena* arena) const final { + return CreateMaybeMessage<CodeGeneratorResponse>(arena); } - void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; - void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; + void CopyFrom(const ::google::protobuf::Message& from) final; + void MergeFrom(const ::google::protobuf::Message& from) final; void CopyFrom(const CodeGeneratorResponse& from); void MergeFrom(const CodeGeneratorResponse& from); - void Clear() PROTOBUF_FINAL; - bool IsInitialized() const PROTOBUF_FINAL; + void Clear() final; + bool IsInitialized() const final; - size_t ByteSizeLong() const PROTOBUF_FINAL; + size_t ByteSizeLong() const final; bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; + ::google::protobuf::io::CodedInputStream* input) final; void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; + ::google::protobuf::io::CodedOutputStream* output) const final; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } + bool deterministic, ::google::protobuf::uint8* target) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + private: void SharedCtor(); void SharedDtor(); - void SetCachedSize(int size) const PROTOBUF_FINAL; + void SetCachedSize(int size) const final; void InternalSwap(CodeGeneratorResponse* other); private: inline ::google::protobuf::Arena* GetArenaNoVirtual() const { @@ -663,7 +655,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag } public: - ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL; + ::google::protobuf::Metadata GetMetadata() const final; // nested types ---------------------------------------------------- @@ -705,11 +697,10 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; ::google::protobuf::internal::HasBits<1> _has_bits_; - mutable int _cached_size_; + mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_; ::google::protobuf::internal::ArenaStringPtr error_; friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; - friend void ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponseImpl(); }; // =================================================================== @@ -844,8 +835,11 @@ inline ::std::string* Version::mutable_suffix() { } inline ::std::string* Version::release_suffix() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix) + if (!has_suffix()) { + return NULL; + } clear_has_suffix(); - return suffix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return suffix_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } inline void Version::set_allocated_suffix(::std::string* suffix) { if (suffix != NULL) { @@ -980,8 +974,11 @@ inline ::std::string* CodeGeneratorRequest::mutable_parameter() { } inline ::std::string* CodeGeneratorRequest::release_parameter() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter) + if (!has_parameter()) { + return NULL; + } clear_has_parameter(); - return parameter_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return parameter_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* parameter) { if (parameter != NULL) { @@ -1034,6 +1031,9 @@ inline void CodeGeneratorRequest::clear_compiler_version() { if (compiler_version_ != NULL) compiler_version_->Clear(); clear_has_compiler_version(); } +inline const ::google::protobuf::compiler::Version& CodeGeneratorRequest::_internal_compiler_version() const { + return *compiler_version_; +} inline const ::google::protobuf::compiler::Version& CodeGeneratorRequest::compiler_version() const { const ::google::protobuf::compiler::Version* p = compiler_version_; // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) @@ -1050,8 +1050,8 @@ inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::release_comp inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() { set_has_compiler_version(); if (compiler_version_ == NULL) { - compiler_version_ = ::google::protobuf::Arena::Create< ::google::protobuf::compiler::Version >( - GetArenaNoVirtual()); + auto* p = CreateMaybeMessage<::google::protobuf::compiler::Version>(GetArenaNoVirtual()); + compiler_version_ = p; } // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) return compiler_version_; @@ -1129,8 +1129,11 @@ inline ::std::string* CodeGeneratorResponse_File::mutable_name() { } inline ::std::string* CodeGeneratorResponse_File::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name) + if (!has_name()) { + return NULL; + } clear_has_name(); - return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return name_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } inline void CodeGeneratorResponse_File::set_allocated_name(::std::string* name) { if (name != NULL) { @@ -1192,8 +1195,11 @@ inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() { } inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) + if (!has_insertion_point()) { + return NULL; + } clear_has_insertion_point(); - return insertion_point_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return insertion_point_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } inline void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::string* insertion_point) { if (insertion_point != NULL) { @@ -1255,8 +1261,11 @@ inline ::std::string* CodeGeneratorResponse_File::mutable_content() { } inline ::std::string* CodeGeneratorResponse_File::release_content() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content) + if (!has_content()) { + return NULL; + } clear_has_content(); - return content_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return content_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } inline void CodeGeneratorResponse_File::set_allocated_content(::std::string* content) { if (content != NULL) { @@ -1322,8 +1331,11 @@ inline ::std::string* CodeGeneratorResponse::mutable_error() { } inline ::std::string* CodeGeneratorResponse::release_error() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error) + if (!has_error()) { + return NULL; + } clear_has_error(); - return error_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + return error_.ReleaseNonDefaultNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } inline void CodeGeneratorResponse::set_allocated_error(::std::string* error) { if (error != NULL) { @@ -1383,4 +1395,4 @@ CodeGeneratorResponse::file() const { // @@protoc_insertion_point(global_scope) -#endif // PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto_INCLUDED +#endif // PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc index 5ca6b4ee..01f28b37 100644 --- a/src/google/protobuf/compiler/python/python_generator.cc +++ b/src/google/protobuf/compiler/python/python_generator.cc @@ -49,9 +49,6 @@ #include <limits> #include <map> #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <string> #include <utility> #include <vector> @@ -202,11 +199,6 @@ void PrintTopBoilerplate( "from google.protobuf import service_reflection\n"); } - // Avoid circular imports if this module is descriptor_pb2. - if (!descriptor_proto) { - printer->Print( - "from google.protobuf import descriptor_pb2\n"); - } printer->Print( "# @@protoc_insertion_point(imports)\n\n" "_sym_db = _symbol_database.Default()\n"); @@ -338,7 +330,7 @@ bool Generator::Generate(const FileDescriptor* file, fdp.SerializeToString(&file_descriptor_serialized_); - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); + std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); GOOGLE_CHECK(output.get()); io::Printer printer(output.get(), '$'); printer_ = &printer; @@ -422,11 +414,13 @@ void Generator::PrintFileDescriptor() const { m["name"] = file_->name(); m["package"] = file_->package(); m["syntax"] = StringifySyntax(file_->syntax()); + m["options"] = OptionsValue(file_->options().SerializeAsString()); const char file_descriptor_template[] = "$descriptor_name$ = _descriptor.FileDescriptor(\n" " name='$name$',\n" " package='$package$',\n" - " syntax='$syntax$',\n"; + " syntax='$syntax$',\n" + " serialized_options=$options$,\n"; printer_->Print(m, file_descriptor_template); printer_->Indent(); printer_->Print( @@ -526,9 +520,9 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { printer_->Outdent(); printer_->Print("],\n"); printer_->Print("containing_type=None,\n"); - printer_->Print("options=$options_value$,\n", + printer_->Print("serialized_options=$options_value$,\n", "options_value", - OptionsValue("EnumOptions", options_string)); + OptionsValue(options_string)); EnumDescriptorProto edp; PrintSerializedPbInterval(enum_descriptor, edp); printer_->Outdent(); @@ -606,13 +600,13 @@ void Generator::PrintServiceDescriptor( m["full_name"] = descriptor.full_name(); m["file"] = kDescriptorKey; m["index"] = SimpleItoa(descriptor.index()); - m["options_value"] = OptionsValue("ServiceOptions", options_string); + m["options_value"] = OptionsValue(options_string); const char required_function_arguments[] = "name='$name$',\n" "full_name='$full_name$',\n" "file=$file$,\n" "index=$index$,\n" - "options=$options_value$,\n"; + "serialized_options=$options_value$,\n"; printer_->Print(m, required_function_arguments); ServiceDescriptorProto sdp; @@ -630,7 +624,7 @@ void Generator::PrintServiceDescriptor( m["serialized_options"] = CEscape(options_string); m["input_type"] = ModuleLevelDescriptorName(*(method->input_type())); m["output_type"] = ModuleLevelDescriptorName(*(method->output_type())); - m["options_value"] = OptionsValue("MethodOptions", options_string); + m["options_value"] = OptionsValue(options_string); printer_->Print("_descriptor.MethodDescriptor(\n"); printer_->Indent(); printer_->Print( @@ -641,7 +635,7 @@ void Generator::PrintServiceDescriptor( "containing_service=None,\n" "input_type=$input_type$,\n" "output_type=$output_type$,\n" - "options=$options_value$,\n"); + "serialized_options=$options_value$,\n"); printer_->Outdent(); printer_->Print("),\n"); } @@ -737,10 +731,10 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { string options_string; message_descriptor.options().SerializeToString(&options_string); printer_->Print( - "options=$options_value$,\n" + "serialized_options=$options_value$,\n" "is_extendable=$extendable$,\n" "syntax='$syntax$'", - "options_value", OptionsValue("MessageOptions", options_string), + "options_value", OptionsValue(options_string), "extendable", message_descriptor.extension_range_count() > 0 ? "True" : "False", "syntax", StringifySyntax(message_descriptor.file()->syntax())); @@ -765,17 +759,18 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { m["full_name"] = desc->full_name(); m["index"] = SimpleItoa(desc->index()); string options_string = - OptionsValue("OneofOptions", desc->options().SerializeAsString()); + OptionsValue(desc->options().SerializeAsString()); if (options_string == "None") { - m["options"] = ""; + m["serialized_options"] = ""; } else { - m["options"] = ", options=" + options_string; + m["serialized_options"] = ", serialized_options=" + options_string; } printer_->Print( m, "_descriptor.OneofDescriptor(\n" " name='$name$', full_name='$full_name$',\n" - " index=$index$, containing_type=None, fields=[]$options$),\n"); + " index=$index$, containing_type=None, " + "fields=[]$serialized_options$),\n"); } printer_->Outdent(); printer_->Print("],\n"); @@ -1098,27 +1093,22 @@ void Generator::PrintEnumValueDescriptor( m["name"] = descriptor.name(); m["index"] = SimpleItoa(descriptor.index()); m["number"] = SimpleItoa(descriptor.number()); - m["options"] = OptionsValue("EnumValueOptions", options_string); + m["options"] = OptionsValue(options_string); printer_->Print( m, "_descriptor.EnumValueDescriptor(\n" " name='$name$', index=$index$, number=$number$,\n" - " options=$options$,\n" + " serialized_options=$options$,\n" " type=None)"); } -// Returns a Python expression that calls descriptor._ParseOptions using -// the given descriptor class name and serialized options protobuf string. -string Generator::OptionsValue( - const string& class_name, const string& serialized_options) const { +// Returns a CEscaped string of serialized_options. +string Generator::OptionsValue(const string& serialized_options) const { if (serialized_options.length() == 0 || GeneratingDescriptorProto()) { return "None"; } else { - string full_class_name = "descriptor_pb2." + class_name; -//##!PY25 return "_descriptor._ParseOptions(" + full_class_name + "(), b'" -//##!PY25 + CEscape(serialized_options)+ "')"; - return "_descriptor._ParseOptions(" + full_class_name + "(), _b('" //##PY25 - + CEscape(serialized_options)+ "'))"; //##PY25 +//##!PY25 return "b'('" + CEscape(serialized_options)+ "')"; + return "_b('"+ CEscape(serialized_options) + "')"; //##PY25 } } @@ -1138,7 +1128,7 @@ void Generator::PrintFieldDescriptor( m["has_default_value"] = field.has_default_value() ? "True" : "False"; m["default_value"] = StringifyDefaultValue(field); m["is_extension"] = is_extension ? "True" : "False"; - m["options"] = OptionsValue("FieldOptions", options_string); + m["serialized_options"] = OptionsValue(options_string); m["json_name"] = field.has_json_name() ? ", json_name='" + field.json_name() + "'": ""; // We always set message_type and enum_type to None at this point, and then @@ -1151,7 +1141,7 @@ void Generator::PrintFieldDescriptor( " has_default_value=$has_default_value$, default_value=$default_value$,\n" " message_type=None, enum_type=None, containing_type=None,\n" " is_extension=$is_extension$, extension_scope=None,\n" - " options=$options$$json_name$, file=DESCRIPTOR)"; + " serialized_options=$serialized_options$$json_name$, file=DESCRIPTOR)"; printer_->Print(m, field_descriptor_decl); } @@ -1280,23 +1270,18 @@ namespace { void PrintDescriptorOptionsFixingCode(const string& descriptor, const string& options, io::Printer* printer) { - // TODO(xiaofeng): I have added a method _SetOptions() to DescriptorBase - // in proto2 python runtime but it couldn't be used here because appengine - // uses a snapshot version of the library in which the new method is not - // yet present. After appengine has synced their runtime library, the code - // below should be cleaned up to use _SetOptions(). + // Reset the _options to None thus DescriptorBase.GetOptions() can + // parse _options again after extensions are registered. printer->Print( - "$descriptor$.has_options = True\n" - "$descriptor$._options = $options$\n", - "descriptor", descriptor, "options", options); + "$descriptor$._options = None\n", + "descriptor", descriptor); } } // namespace // Prints expressions that set the options field of all descriptors. void Generator::FixAllDescriptorOptions() const { // Prints an expression that sets the file descriptor's options. - string file_options = OptionsValue( - "FileOptions", file_->options().SerializeAsString()); + string file_options = OptionsValue(file_->options().SerializeAsString()); if (file_options != "None") { PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_); } @@ -1318,8 +1303,7 @@ void Generator::FixAllDescriptorOptions() const { } void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const { - string oneof_options = OptionsValue( - "OneofOptions", oneof.options().SerializeAsString()); + string oneof_options = OptionsValue(oneof.options().SerializeAsString()); if (oneof_options != "None") { string oneof_name = strings::Substitute( "$0.$1['$2']", @@ -1334,14 +1318,14 @@ void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const { void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { string descriptor_name = ModuleLevelDescriptorName(enum_descriptor); string enum_options = OptionsValue( - "EnumOptions", enum_descriptor.options().SerializeAsString()); + enum_descriptor.options().SerializeAsString()); if (enum_options != "None") { PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_); } for (int i = 0; i < enum_descriptor.value_count(); ++i) { const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i); string value_options = OptionsValue( - "EnumValueOptions", value_descriptor.options().SerializeAsString()); + value_descriptor.options().SerializeAsString()); if (value_options != "None") { PrintDescriptorOptionsFixingCode( StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(), @@ -1355,8 +1339,7 @@ void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { // extensions). void Generator::FixOptionsForField( const FieldDescriptor& field) const { - string field_options = OptionsValue( - "FieldOptions", field.options().SerializeAsString()); + string field_options = OptionsValue(field.options().SerializeAsString()); if (field_options != "None") { string field_name; if (field.is_extension()) { @@ -1402,7 +1385,7 @@ void Generator::FixOptionsForMessage(const Descriptor& descriptor) const { } // Message option for this message. string message_options = OptionsValue( - "MessageOptions", descriptor.options().SerializeAsString()); + descriptor.options().SerializeAsString()); if (message_options != "None") { string descriptor_name = ModuleLevelDescriptorName(descriptor); PrintDescriptorOptionsFixingCode(descriptor_name, diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h index 2b5a028b..8e4050de 100644 --- a/src/google/protobuf/compiler/python/python_generator.h +++ b/src/google/protobuf/compiler/python/python_generator.h @@ -135,8 +135,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { const ServiceDescriptor& descriptor) const; void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const; - string OptionsValue(const string& class_name, - const string& serialized_options) const; + string OptionsValue(const string& serialized_options) const; bool GeneratingDescriptorProto() const; template <typename DescriptorT> diff --git a/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/src/google/protobuf/compiler/python/python_plugin_unittest.cc index 34f857fd..2f096808 100644 --- a/src/google/protobuf/compiler/python/python_plugin_unittest.cc +++ b/src/google/protobuf/compiler/python/python_plugin_unittest.cc @@ -35,9 +35,6 @@ // worth. #include <memory> -#ifndef _SHARED_PTR_H -#include <google/protobuf/stubs/shared_ptr.h> -#endif #include <google/protobuf/compiler/python/python_generator.h> #include <google/protobuf/compiler/command_line_interface.h> @@ -74,7 +71,7 @@ class TestGenerator : public CodeGenerator { void TryInsert(const string& filename, const string& insertion_point, GeneratorContext* context) const { - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( context->OpenForInsert(filename, insertion_point)); io::Printer printer(output.get(), '$'); printer.Print("// inserted $name$\n", "name", insertion_point); |