diff options
author | Jisi Liu <jisi.liu@gmail.com> | 2015-02-28 14:51:22 -0800 |
---|---|---|
committer | Jisi Liu <jisi.liu@gmail.com> | 2015-02-28 17:06:49 -0800 |
commit | 885b612f74f133678bf82808c589331e4c59dad9 (patch) | |
tree | e5f3f65b41af477c52810053b8694896c8bcd1f7 /src/google/protobuf/compiler | |
parent | 1939efed2db35020b7830a4927f10feac47b6757 (diff) | |
download | protobuf-885b612f74f133678bf82808c589331e4c59dad9.tar.gz protobuf-885b612f74f133678bf82808c589331e4c59dad9.tar.bz2 protobuf-885b612f74f133678bf82808c589331e4c59dad9.zip |
Down integrate from Google internal branch for C++ and Java.
- Maps for C++ lite
- C++ Arena optimizations.
- Java Lite runtime code size optimization.
Change-Id: I7537a4357c1cb385d23f9e8aa7ffdfeefe079f13
Diffstat (limited to 'src/google/protobuf/compiler')
39 files changed, 1738 insertions, 758 deletions
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 13250702..09106313 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -152,7 +152,7 @@ bool VerifyDirectoryExists(const string& path) { if (path.empty()) return true; if (access(path.c_str(), F_OK) == -1) { - cerr << path << ": " << strerror(errno) << endl; + std::cerr << path << ": " << strerror(errno) << std::endl; return false; } else { return true; @@ -171,8 +171,8 @@ bool TryCreateParentDirectory(const string& prefix, const string& filename) { path_so_far += parts[i]; if (mkdir(path_so_far.c_str(), 0777) != 0) { if (errno != EEXIST) { - cerr << filename << ": while trying to create directory " - << path_so_far << ": " << strerror(errno) << endl; + std::cerr << filename << ": while trying to create directory " + << path_so_far << ": " << strerror(errno) << std::endl; return false; } } @@ -201,9 +201,9 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && tree_ != NULL && tree_->VirtualFileToDiskFile(filename, &dfile)) { - cerr << dfile; + std::cerr << dfile; } else { - cerr << filename; + std::cerr << filename; } // Users typically expect 1-based line/column numbers, so we add 1 @@ -212,15 +212,16 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, // Allow for both GCC- and Visual-Studio-compatible output. switch (format_) { case CommandLineInterface::ERROR_FORMAT_GCC: - cerr << ":" << (line + 1) << ":" << (column + 1); + std::cerr << ":" << (line + 1) << ":" << (column + 1); break; case CommandLineInterface::ERROR_FORMAT_MSVS: - cerr << "(" << (line + 1) << ") : error in column=" << (column + 1); + std::cerr << "(" << (line + 1) + << ") : error in column=" << (column + 1); break; } } - cerr << ": " << message << endl; + std::cerr << ": " << message << std::endl; } // implements io::ErrorCollector ----------------------------------- @@ -345,7 +346,7 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk( if (file_descriptor < 0) { int error = errno; - cerr << filename << ": " << strerror(error); + std::cerr << filename << ": " << strerror(error); return false; } @@ -369,9 +370,9 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk( if (write_result < 0) { int error = errno; - cerr << filename << ": write: " << strerror(error); + std::cerr << filename << ": write: " << strerror(error); } else { - cerr << filename << ": write() returned zero?" << endl; + std::cerr << filename << ": write() returned zero?" << std::endl; } return false; } @@ -382,7 +383,7 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk( if (close(file_descriptor) != 0) { int error = errno; - cerr << filename << ": close: " << strerror(error); + std::cerr << filename << ": close: " << strerror(error); return false; } } @@ -405,7 +406,7 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip( if (file_descriptor < 0) { int error = errno; - cerr << filename << ": " << strerror(error); + std::cerr << filename << ": " << strerror(error); return false; } @@ -421,11 +422,11 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip( zip_writer.WriteDirectory(); if (stream.GetErrno() != 0) { - cerr << filename << ": " << strerror(stream.GetErrno()) << endl; + std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl; } if (!stream.Close()) { - cerr << filename << ": " << strerror(stream.GetErrno()) << endl; + std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl; } return true; @@ -490,7 +491,8 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { if (append_mode_) { (*map_slot)->append(data_); } else { - cerr << filename_ << ": Tried to write the same file twice." << endl; + std::cerr << filename_ << ": Tried to write the same file twice." + << std::endl; directory_->had_error_ = true; } return; @@ -508,8 +510,9 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { // Find the file we are going to insert into. if (*map_slot == NULL) { - cerr << filename_ << ": Tried to insert into file that doesn't exist." - << endl; + std::cerr << filename_ + << ": Tried to insert into file that doesn't exist." + << std::endl; directory_->had_error_ = true; return; } @@ -521,8 +524,8 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { string::size_type pos = target->find(magic_string); if (pos == string::npos) { - cerr << filename_ << ": insertion point \"" << insertion_point_ - << "\" not found." << endl; + std::cerr << filename_ << ": insertion point \"" << insertion_point_ + << "\" not found." << std::endl; directory_->had_error_ = true; return; } @@ -793,27 +796,31 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative( input_files_[i] = virtual_file; break; case DiskSourceTree::SHADOWED: - cerr << input_files_[i] << ": Input is shadowed in the --proto_path " - "by \"" << shadowing_disk_file << "\". Either use the latter " - "file as your input or reorder the --proto_path so that the " - "former file's location comes first." << endl; + std::cerr << input_files_[i] + << ": Input is shadowed in the --proto_path by \"" + << shadowing_disk_file + << "\". Either use the latter file as your input or reorder " + "the --proto_path so that the former file's location " + "comes first." << std::endl; return false; case DiskSourceTree::CANNOT_OPEN: - cerr << input_files_[i] << ": " << strerror(errno) << endl; + std::cerr << input_files_[i] << ": " << strerror(errno) << std::endl; return false; case DiskSourceTree::NO_MAPPING: // First check if the file exists at all. if (access(input_files_[i].c_str(), F_OK) < 0) { // File does not even exist. - cerr << input_files_[i] << ": " << strerror(ENOENT) << endl; + std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl; } else { - cerr << input_files_[i] << ": File does not reside within any path " - "specified using --proto_path (or -I). You must specify a " - "--proto_path which encompasses this file. Note that the " - "proto_path must be an exact prefix of the .proto file " - "names -- protoc is too dumb to figure out when two paths " - "(e.g. absolute and relative) are equivalent (it's harder " - "than you think)." << endl; + std::cerr + << input_files_[i] + << ": File does not reside within any path " + "specified using --proto_path (or -I). You must specify a " + "--proto_path which encompasses this file. Note that the " + "proto_path must be an exact prefix of the .proto file " + "names -- protoc is too dumb to figure out when two paths " + "(e.g. absolute and relative) are equivalent (it's harder " + "than you think)." << std::endl; } return false; } @@ -833,9 +840,10 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { if (ParseArgument(argv[i], &name, &value)) { // Returned true => Use the next argument as the flag value. if (i + 1 == argc || argv[i+1][0] == '-') { - cerr << "Missing value for flag: " << name << endl; + std::cerr << "Missing value for flag: " << name << std::endl; if (name == "--decode") { - cerr << "To decode an unknown message, use --decode_raw." << endl; + std::cerr << "To decode an unknown message, use --decode_raw." + << std::endl; } return PARSE_ARGUMENT_FAIL; } else { @@ -860,24 +868,25 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { // Check some errror cases. bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty(); if (decoding_raw && !input_files_.empty()) { - cerr << "When using --decode_raw, no input files should be given." << endl; + std::cerr << "When using --decode_raw, no input files should be given." + << std::endl; return PARSE_ARGUMENT_FAIL; } else if (!decoding_raw && input_files_.empty()) { - cerr << "Missing input file." << endl; + std::cerr << "Missing input file." << std::endl; return PARSE_ARGUMENT_FAIL; } if (mode_ == MODE_COMPILE && output_directives_.empty() && descriptor_set_name_.empty()) { - cerr << "Missing output directives." << endl; + std::cerr << "Missing output directives." << std::endl; return PARSE_ARGUMENT_FAIL; } if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) { - cerr << "--include_imports only makes sense when combined with " - "--descriptor_set_out." << endl; + std::cerr << "--include_imports only makes sense when combined with " + "--descriptor_set_out." << std::endl; } if (source_info_in_descriptor_set_ && descriptor_set_name_.empty()) { - cerr << "--include_source_info only makes sense when combined with " - "--descriptor_set_out." << endl; + std::cerr << "--include_source_info only makes sense when combined with " + "--descriptor_set_out." << std::endl; } return PARSE_ARGUMENT_DONE_AND_CONTINUE; @@ -950,10 +959,12 @@ CommandLineInterface::InterpretArgument(const string& name, if (name.empty()) { // Not a flag. Just a filename. if (value.empty()) { - cerr << "You seem to have passed an empty string as one of the " - "arguments to " << executable_name_ << ". This is actually " - "sort of hard to do. Congrats. Unfortunately it is not valid " - "input so the program is going to die now." << endl; + std::cerr + << "You seem to have passed an empty string as one of the " + "arguments to " << executable_name_ + << ". This is actually " + "sort of hard to do. Congrats. Unfortunately it is not valid " + "input so the program is going to die now." << std::endl; return PARSE_ARGUMENT_FAIL; } @@ -980,14 +991,16 @@ CommandLineInterface::InterpretArgument(const string& name, } if (disk_path.empty()) { - cerr << "--proto_path passed empty directory name. (Use \".\" for " - "current directory.)" << endl; + std::cerr + << "--proto_path passed empty directory name. (Use \".\" for " + "current directory.)" << std::endl; return PARSE_ARGUMENT_FAIL; } // Make sure disk path exists, warn otherwise. if (access(disk_path.c_str(), F_OK) < 0) { - cerr << disk_path << ": warning: directory does not exist." << endl; + std::cerr << disk_path << ": warning: directory does not exist." + << std::endl; } // Don't use make_pair as the old/default standard library on Solaris @@ -998,30 +1011,31 @@ CommandLineInterface::InterpretArgument(const string& name, } else if (name == "-o" || name == "--descriptor_set_out") { if (!descriptor_set_name_.empty()) { - cerr << name << " may only be passed once." << endl; + std::cerr << name << " may only be passed once." << std::endl; return PARSE_ARGUMENT_FAIL; } if (value.empty()) { - cerr << name << " requires a non-empty value." << endl; + std::cerr << name << " requires a non-empty value." << std::endl; return PARSE_ARGUMENT_FAIL; } if (mode_ != MODE_COMPILE) { - cerr << "Cannot use --encode or --decode and generate descriptors at the " - "same time." << endl; + std::cerr + << "Cannot use --encode or --decode and generate descriptors at the " + "same time." << std::endl; return PARSE_ARGUMENT_FAIL; } descriptor_set_name_ = value; } else if (name == "--include_imports") { if (imports_in_descriptor_set_) { - cerr << name << " may only be passed once." << endl; + std::cerr << name << " may only be passed once." << std::endl; return PARSE_ARGUMENT_FAIL; } imports_in_descriptor_set_ = true; } else if (name == "--include_source_info") { if (source_info_in_descriptor_set_) { - cerr << name << " may only be passed once." << endl; + std::cerr << name << " may only be passed once." << std::endl; return PARSE_ARGUMENT_FAIL; } source_info_in_descriptor_set_ = true; @@ -1032,7 +1046,7 @@ CommandLineInterface::InterpretArgument(const string& name, } else if (name == "--version") { if (!version_info_.empty()) { - cout << version_info_ << endl; + std::cout << version_info_ << std::endl; } cout << "libprotoc " << protobuf::internal::VersionString(GOOGLE_PROTOBUF_VERSION) @@ -1045,25 +1059,28 @@ CommandLineInterface::InterpretArgument(const string& name, } else if (name == "--encode" || name == "--decode" || name == "--decode_raw") { if (mode_ != MODE_COMPILE) { - cerr << "Only one of --encode and --decode can be specified." << endl; + std::cerr << "Only one of --encode and --decode can be specified." + << std::endl; return PARSE_ARGUMENT_FAIL; } if (!output_directives_.empty() || !descriptor_set_name_.empty()) { - cerr << "Cannot use " << name - << " and generate code or descriptors at the same time." << endl; + std::cerr << "Cannot use " << name + << " and generate code or descriptors at the same time." + << std::endl; return PARSE_ARGUMENT_FAIL; } mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE; if (value.empty() && name != "--decode_raw") { - cerr << "Type name for " << name << " cannot be blank." << endl; + std::cerr << "Type name for " << name << " cannot be blank." << std::endl; if (name == "--decode") { - cerr << "To decode an unknown message, use --decode_raw." << endl; + std::cerr << "To decode an unknown message, use --decode_raw." + << std::endl; } return PARSE_ARGUMENT_FAIL; } else if (!value.empty() && name == "--decode_raw") { - cerr << "--decode_raw does not take a parameter." << endl; + std::cerr << "--decode_raw does not take a parameter." << std::endl; return PARSE_ARGUMENT_FAIL; } @@ -1075,13 +1092,13 @@ CommandLineInterface::InterpretArgument(const string& name, } else if (value == "msvs") { error_format_ = ERROR_FORMAT_MSVS; } else { - cerr << "Unknown error format: " << value << endl; + std::cerr << "Unknown error format: " << value << std::endl; return PARSE_ARGUMENT_FAIL; } } else if (name == "--plugin") { if (plugin_prefix_.empty()) { - cerr << "This compiler does not support plugins." << endl; + std::cerr << "This compiler does not support plugins." << std::endl; return PARSE_ARGUMENT_FAIL; } @@ -1107,13 +1124,15 @@ CommandLineInterface::InterpretArgument(const string& name, } else if (name == "--print_free_field_numbers") { if (mode_ != MODE_COMPILE) { - cerr << "Cannot use " << name << " and use --encode, --decode or print " - << "other info at the same time." << endl; + std::cerr << "Cannot use " << name + << " and use --encode, --decode or print " + << "other info at the same time." << std::endl; return PARSE_ARGUMENT_FAIL; } if (!output_directives_.empty() || !descriptor_set_name_.empty()) { - cerr << "Cannot use " << name - << " and generate code or descriptors at the same time." << endl; + std::cerr << "Cannot use " << name + << " and generate code or descriptors at the same time." + << std::endl; return PARSE_ARGUMENT_FAIL; } mode_ = MODE_PRINT; @@ -1127,7 +1146,7 @@ CommandLineInterface::InterpretArgument(const string& name, // Check if it's a generator option flag. generator_info = FindOrNull(generators_by_option_name_, name); if (generator_info == NULL) { - cerr << "Unknown flag: " << name << endl; + std::cerr << "Unknown flag: " << name << std::endl; return PARSE_ARGUMENT_FAIL; } else { string* parameters = &generator_parameters_[generator_info->flag_name]; @@ -1139,8 +1158,8 @@ CommandLineInterface::InterpretArgument(const string& name, } else { // It's an output flag. Add it to the output directives. if (mode_ != MODE_COMPILE) { - cerr << "Cannot use --encode, --decode or print .proto info and " - "generate code at the same time." << endl; + std::cerr << "Cannot use --encode, --decode or print .proto info and " + "generate code at the same time." << std::endl; return PARSE_ARGUMENT_FAIL; } @@ -1172,7 +1191,7 @@ CommandLineInterface::InterpretArgument(const string& name, void CommandLineInterface::PrintHelpText() { // Sorry for indentation here; line wrapping would be uglier. - cerr << + std::cerr << "Usage: " << executable_name_ << " [OPTION] PROTO_FILES\n" "Parse PROTO_FILES and generate output based on the options given:\n" " -IPATH, --proto_path=PATH Specify the directory in which to search for\n" @@ -1213,9 +1232,9 @@ void CommandLineInterface::PrintHelpText() { " defined in the given proto files. Groups share\n" " the same field number space with the parent \n" " message. Extension ranges are counted as \n" -" occupied fields numbers." << endl; +" occupied fields numbers." << std::endl; if (!plugin_prefix_.empty()) { - cerr << + std::cerr << " --plugin=EXECUTABLE Specifies a plugin executable to use.\n" " Normally, protoc searches the PATH for\n" " plugins, but you may specify additional\n" @@ -1223,7 +1242,7 @@ void CommandLineInterface::PrintHelpText() { " Additionally, EXECUTABLE may be of the form\n" " NAME=PATH, in which case the given plugin name\n" " is mapped to the given executable even if\n" -" the executable's own name differs." << endl; +" the executable's own name differs." << std::endl; } for (GeneratorMap::iterator iter = generators_by_flag_name_.begin(); @@ -1231,9 +1250,9 @@ void CommandLineInterface::PrintHelpText() { // FIXME(kenton): If the text is long enough it will wrap, which is ugly, // but fixing this nicely (e.g. splitting on spaces) is probably more // trouble than it's worth. - cerr << " " << iter->first << "=OUT_DIR " - << string(19 - iter->first.size(), ' ') // Spaces for alignment. - << iter->second.help_text << endl; + std::cerr << " " << iter->first << "=OUT_DIR " + << string(19 - iter->first.size(), ' ') // Spaces for alignment. + << iter->second.help_text << std::endl; } } @@ -1256,7 +1275,7 @@ bool CommandLineInterface::GenerateOutput( if (!GeneratePluginOutput(parsed_files, plugin_name, output_directive.parameter, generator_context, &error)) { - cerr << output_directive.name << ": " << error << endl; + std::cerr << output_directive.name << ": " << error << std::endl; return false; } } else { @@ -1272,8 +1291,8 @@ bool CommandLineInterface::GenerateOutput( if (!output_directive.generator->Generate(parsed_files[i], parameters, generator_context, &error)) { // Generator returned an error. - cerr << output_directive.name << ": " << parsed_files[i]->name() << ": " - << error << endl; + std::cerr << output_directive.name << ": " << parsed_files[i]->name() + << ": " << error << std::endl; return false; } } @@ -1365,7 +1384,7 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { // Look up the type. const Descriptor* type = pool->FindMessageTypeByName(codec_type_); if (type == NULL) { - cerr << "Type not defined: " << codec_type_ << endl; + std::cerr << "Type not defined: " << codec_type_ << std::endl; return false; } @@ -1391,32 +1410,32 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { parser.AllowPartialMessage(true); if (!parser.Parse(&in, message.get())) { - cerr << "Failed to parse input." << endl; + std::cerr << "Failed to parse input." << std::endl; return false; } } else { // Input is binary. if (!message->ParsePartialFromZeroCopyStream(&in)) { - cerr << "Failed to parse input." << endl; + std::cerr << "Failed to parse input." << std::endl; return false; } } if (!message->IsInitialized()) { - cerr << "warning: Input message is missing required fields: " - << message->InitializationErrorString() << endl; + std::cerr << "warning: Input message is missing required fields: " + << message->InitializationErrorString() << std::endl; } if (mode_ == MODE_ENCODE) { // Output is binary. if (!message->SerializePartialToZeroCopyStream(&out)) { - cerr << "output: I/O error." << endl; + std::cerr << "output: I/O error." << std::endl; return false; } } else { // Output is text. if (!TextFormat::Print(*message, &out)) { - cerr << "output: I/O error." << endl; + std::cerr << "output: I/O error." << std::endl; return false; } } @@ -1458,12 +1477,14 @@ bool CommandLineInterface::WriteDescriptorSet( io::FileOutputStream out(fd); if (!file_set.SerializeToZeroCopyStream(&out)) { - cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl; + std::cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) + << std::endl; out.Close(); return false; } if (!out.Close()) { - cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl; + std::cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) + << std::endl; return false; } @@ -1582,7 +1603,7 @@ void FormatFreeFieldNumbers(const string& name, if (next_free_number <= FieldDescriptor::kMaxNumber) { StringAppendF(&output, " %d-INF", next_free_number); } - cout << output << endl; + std::cout << output << std::endl; } } // namespace diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 64e877a3..3d27829e 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -67,7 +67,6 @@ // Disable the whole test when we use tcmalloc for "draconian" heap checks, in // which case tcmalloc will print warnings that fail the plugin tests. #if !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN - namespace google { namespace protobuf { namespace compiler { @@ -1666,6 +1665,6 @@ TEST_F(EncodeDecodeTest, ProtoParseError) { } // namespace compiler } // namespace protobuf -} // namespace google -#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN +#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN +} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc index 48788197..13ed0b64 100644 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -98,7 +98,8 @@ class MockGeneratorContext : public GeneratorContext { &actual_contents, true)); EXPECT_TRUE(actual_contents == *expected_contents) << physical_filename << " needs to be regenerated. Please run " - "generate_descriptor_proto.sh and add this file " + "google/protobuf/compiler/release_compiler.sh and " + "generate_descriptor_proto.sh. Then add this file " "to your CL."; } diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc index 3ce1f120..0404b739 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc @@ -47,7 +47,7 @@ namespace cpp { namespace { // The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value -// is kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the +// is ::google::protobuf::kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the // generation of the GOOGLE_ARRAYSIZE constant. bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) { int32 max_value = descriptor->value(0)->number(); @@ -56,7 +56,7 @@ bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) { max_value = descriptor->value(i)->number(); } } - return max_value != kint32max; + return max_value != ::google::protobuf::kint32max; } } // namespace @@ -153,9 +153,12 @@ 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 " + "{};\n", + "classname", ClassName(descriptor_, true)); if (HasDescriptorMethods(descriptor_->file())) { printer->Print( - "template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type {};\n" "template <>\n" "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n" " return $classname$_descriptor();\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index 17926135..74989703 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -76,23 +76,26 @@ GeneratePrivateMembers(io::Printer* printer) const { void EnumFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline $type$ $name$() const$deprecation$;\n" - "inline void set_$name$($type$ value)$deprecation$;\n"); + "$type$ $name$() const$deprecation$;\n" + "void set_$name$($type$ value)$deprecation$;\n"); } void EnumFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return static_cast< $type$ >($name$_);\n" "}\n" - "inline void $classname$::set_$name$($type$ value) {\n"); + "$inline$ void $classname$::set_$name$($type$ value) {\n"); if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { - printer->Print(variables_, + printer->Print(variables, " assert($type$_IsValid(value));\n"); } - printer->Print(variables_, + printer->Print(variables, " $set_hasbit$\n" " $name$_ = value;\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" @@ -181,21 +184,24 @@ EnumOneofFieldGenerator(const FieldDescriptor* descriptor, EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {} void EnumOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " if (has_$name$()) {\n" " return static_cast< $type$ >($oneof_prefix$$name$_);\n" " }\n" " return static_cast< $type$ >($default$);\n" "}\n" - "inline void $classname$::set_$name$($type$ value) {\n"); + "$inline$ void $classname$::set_$name$($type$ value) {\n"); if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { - printer->Print(variables_, + printer->Print(variables, " assert($type$_IsValid(value));\n"); } - printer->Print(variables_, + printer->Print(variables, " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -246,46 +252,49 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline $type$ $name$(int index) const$deprecation$;\n" - "inline void set_$name$(int index, $type$ value)$deprecation$;\n" - "inline void add_$name$($type$ value)$deprecation$;\n"); + "$type$ $name$(int index) const$deprecation$;\n" + "void set_$name$(int index, $type$ value)$deprecation$;\n" + "void add_$name$($type$ value)$deprecation$;\n"); printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n" - "inline ::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n"); + "const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n" + "::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n"); } void RepeatedEnumFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$(int index) const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$(int index) const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return static_cast< $type$ >($name$_.Get(index));\n" "}\n" - "inline void $classname$::set_$name$(int index, $type$ value) {\n"); + "$inline$ void $classname$::set_$name$(int index, $type$ value) {\n"); if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { - printer->Print(variables_, + printer->Print(variables, " assert($type$_IsValid(value));\n"); } - printer->Print(variables_, + printer->Print(variables, " $name$_.Set(index, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::add_$name$($type$ value) {\n"); + "$inline$ void $classname$::add_$name$($type$ value) {\n"); if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { - printer->Print(variables_, + printer->Print(variables, " assert($type$_IsValid(value));\n"); } - printer->Print(variables_, + printer->Print(variables, " $name$_.Add(value);\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n"); - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField<int>&\n" + printer->Print(variables, + "$inline$ const ::google::protobuf::RepeatedField<int>&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_list:$full_name$)\n" " return $name$_;\n" "}\n" - "inline ::google::protobuf::RepeatedField<int>*\n" + "$inline$ ::google::protobuf::RepeatedField<int>*\n" "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" " return &$name$_;\n" @@ -344,20 +353,34 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { if (!descriptor_->options().packed()) { - // We use a non-inlined implementation in this case, since this path will - // rarely be executed. - printer->Print(variables_, - "DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(\n" - " input,\n"); + // This path is rarely executed, so we use a non-inlined implementation. if (HasPreservingUnknownEnumSemantics(descriptor_->file())) { printer->Print(variables_, - " NULL,\n"); + "DO_((::google::protobuf::internal::" + "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n" + " input,\n" + " $number$,\n" + " NULL,\n" + " NULL,\n" + " this->mutable_$name$())));\n"); + } else if (UseUnknownFieldSet(descriptor_->file())) { + printer->Print(variables_, + "DO_((::google::protobuf::internal::WireFormat::ReadPackedEnumPreserveUnknowns(\n" + " input,\n" + " $number$,\n" + " $type$_IsValid,\n" + " mutable_unknown_fields(),\n" + " this->mutable_$name$())));\n"); } else { printer->Print(variables_, - " &$type$_IsValid,\n"); + "DO_((::google::protobuf::internal::" + "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n" + " input,\n" + " $number$,\n" + " $type$_IsValid,\n" + " &unknown_fields_stream,\n" + " this->mutable_$name$())));\n"); } - printer->Print(variables_, - " this->mutable_$name$())));\n"); } else { printer->Print(variables_, "::google::protobuf::uint32 length;\n" @@ -376,6 +399,16 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { printer->Print(variables_, " if ($type$_IsValid(value)) {\n" " add_$name$(static_cast< $type$ >(value));\n" + " } else {\n"); + if (UseUnknownFieldSet(descriptor_->file())) { + printer->Print(variables_, + " mutable_unknown_fields()->AddVarint($number$, value);\n"); + } else { + printer->Print(variables_, + " unknown_fields_stream.WriteVarint32(tag);\n" + " unknown_fields_stream.WriteVarint32(value);\n"); + } + printer->Print( " }\n"); } printer->Print(variables_, diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h index def2b232..5b1d01ea 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h @@ -53,7 +53,8 @@ class EnumFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; @@ -78,7 +79,8 @@ class EnumOneofFieldGenerator : public EnumFieldGenerator { ~EnumOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; @@ -96,7 +98,8 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index c37fe0be..cd2b6b75 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -89,7 +89,7 @@ class FieldGenerator { // Generate inline definitions of accessor functions for this field. // These are placed inside the header after all class definitions. virtual void GenerateInlineAccessorDefinitions( - io::Printer* printer) const = 0; + io::Printer* printer, bool is_inline) const = 0; // Generate definitions of accessors that aren't inlined. These are // placed somewhere in the .cc file. diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index fae4df40..a98c7d92 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -136,8 +136,11 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { printer->Print( "#include <google/protobuf/arena.h>\n" "#include <google/protobuf/arenastring.h>\n" - "#include <google/protobuf/generated_message_util.h>\n" - "#include <google/protobuf/metadata.h>\n"); + "#include <google/protobuf/generated_message_util.h>\n"); + if (UseUnknownFieldSet(file_)) { + printer->Print( + "#include <google/protobuf/metadata.h>\n"); + } if (file_->message_type_count() > 0) { if (HasDescriptorMethods(file_)) { printer->Print( @@ -152,13 +155,24 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { "#include <google/protobuf/extension_set.h>\n"); if (HasMapFields(file_)) { printer->Print( - "#include <google/protobuf/map.h>\n" - "#include <google/protobuf/map_field_inl.h>\n"); + "#include <google/protobuf/map.h>\n"); + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include <google/protobuf/map_field_inl.h>\n"); + } else { + printer->Print( + "#include <google/protobuf/map_field_lite.h>\n"); + } } - if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) { - printer->Print( - "#include <google/protobuf/generated_enum_reflection.h>\n"); + if (HasEnumDefinitions(file_)) { + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include <google/protobuf/generated_enum_reflection.h>\n"); + } else { + printer->Print( + "#include <google/protobuf/generated_enum_util.h>\n"); + } } if (HasGenericServices(file_)) { @@ -272,15 +286,17 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { printer->Print(kThickSeparator); printer->Print("\n"); - + printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); // Generate class inline methods. for (int i = 0; i < file_->message_type_count(); i++) { if (i > 0) { printer->Print(kThinSeparator); printer->Print("\n"); } - message_generators_[i]->GenerateInlineMethods(printer); + message_generators_[i]->GenerateInlineMethods(printer, + /* is_inline = */ true); } + printer->Print("#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); printer->Print( "\n" @@ -290,7 +306,7 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { GenerateNamespaceClosers(printer); // Emit GetEnumDescriptor specializations into google::protobuf namespace: - if (HasDescriptorMethods(file_)) { + if (HasEnumDefinitions(file_)) { // The SWIG conditional is to avoid a null-pointer dereference // (bug 1984964) in swig-1.3.21 resulting from the following syntax: // namespace X { void Y<Z::W>(); } @@ -417,6 +433,12 @@ void FileGenerator::GenerateSource(io::Printer* printer) { printer->Print(kThickSeparator); printer->Print("\n"); message_generators_[i]->GenerateClassMethods(printer); + + printer->Print("#if PROTOBUF_INLINE_NOT_IN_HEADERS\n"); + // Generate class inline methods. + message_generators_[i]->GenerateInlineMethods(printer, + /* is_inline = */ false); + printer->Print("#endif // PROTOBUF_INLINE_NOT_IN_HEADERS\n"); } if (HasGenericServices(file_)) { diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 28c4dd54..237278db 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -352,9 +352,7 @@ string FilenameIdentifier(const string& filename) { } else { // Not alphanumeric. To avoid any possibility of name conflicts we // use the hex code for the character. - result.push_back('_'); - char buffer[kFastToBufferSize]; - result.append(FastHexToBuffer(static_cast<uint8>(filename[i]), buffer)); + StrAppend(&result, "_", ToHex(static_cast<uint8>(filename[i]))); } } return result; @@ -508,6 +506,13 @@ bool IsStringOrMessage(const FieldDescriptor* field) { return false; } +FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field) { + GOOGLE_DCHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_STRING); + // Open-source protobuf release only supports STRING ctype. + return FieldOptions::STRING; + +} + } // 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 e60fa7c2..c7bb8f98 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -211,6 +211,10 @@ inline bool IsMapEntryMessage(const Descriptor* descriptor) { // Returns true if the field's CPPTYPE is string or message. bool IsStringOrMessage(const FieldDescriptor* field); +// For a string field, returns the effective ctype. If the actual ctype is +// not supported, returns the default of STRING. +FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field); + string UnderscoresToCamelCase(const string& input, bool cap_next_letter); inline bool HasFieldPresence(const FileDescriptor* file) { diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc index 0154eeb8..8c38db2b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -31,6 +31,7 @@ #include <google/protobuf/compiler/cpp/cpp_map_field.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/strutil.h> namespace google { @@ -72,14 +73,21 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["val_cpp"] = PrimitiveTypeName(val->cpp_type()); (*variables)["wrapper"] = "EntryWrapper"; } - (*variables)["key_type"] = - "::google::protobuf::FieldDescriptor::TYPE_" + + (*variables)["key_wire_type"] = + "::google::protobuf::internal::WireFormatLite::TYPE_" + ToUpper(DeclaredTypeMethodName(key->type())); - (*variables)["val_type"] = - "::google::protobuf::FieldDescriptor::TYPE_" + + (*variables)["val_wire_type"] = + "::google::protobuf::internal::WireFormatLite::TYPE_" + ToUpper(DeclaredTypeMethodName(val->type())); (*variables)["map_classname"] = ClassName(descriptor->message_type(), false); - (*variables)["number"] = Int32ToString(descriptor->number()); + (*variables)["number"] = SimpleItoa(descriptor->number()); + (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); + + if (HasDescriptorMethods(descriptor->file())) { + (*variables)["lite"] = ""; + } else { + (*variables)["lite"] = "Lite"; + } if (!IsProto3Field(descriptor) && val->type() == FieldDescriptor::TYPE_ENUM) { @@ -102,33 +110,40 @@ MapFieldGenerator::~MapFieldGenerator() {} void MapFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { printer->Print(variables_, - "typedef ::google::protobuf::internal::MapEntry<\n" + "typedef ::google::protobuf::internal::MapEntryLite<\n" " $key_cpp$, $val_cpp$,\n" - " $key_type$,\n" - " $val_type$, $default_enum_value$>\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ >\n" " $map_classname$;\n" - "::google::protobuf::internal::MapField< $key_cpp$, $val_cpp$," - "$key_type$, $val_type$, $default_enum_value$ > $name$_;\n"); + "::google::protobuf::internal::MapField$lite$<\n" + " $key_cpp$, $val_cpp$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ > $name$_;\n"); } void MapFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" + "const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" " $name$() const$deprecation$;\n" - "inline ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" + "::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" " mutable_$name$()$deprecation$;\n"); } void MapFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_map:$full_name$)\n" " return $name$_.GetMap();\n" "}\n" - "inline ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" + "$inline$ ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_map:$full_name$)\n" " return $name$_.MutableMap();\n" @@ -198,11 +213,29 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { " if ($val_cpp$_IsValid(*entry->mutable_value())) {\n" " (*mutable_$name$())[entry->key()] =\n" " static_cast<$val_cpp$>(*entry->mutable_value());\n" - " } else {\n" - " mutable_unknown_fields()->AddLengthDelimited($number$, data);\n" + " } else {\n"); + if (HasDescriptorMethods(descriptor_->file())) { + printer->Print(variables_, + " mutable_unknown_fields()" + "->AddLengthDelimited($number$, data);\n"); + } else { + printer->Print(variables_, + " unknown_fields_stream.WriteVarint32($tag$);\n" + " unknown_fields_stream.WriteVarint32(data.size());\n" + " unknown_fields_stream.WriteString(data);\n"); + } + + + printer->Print(variables_, " }\n" "}\n"); } + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + "if (entry->GetArena() != NULL) entry.release();\n"); + } } void MapFieldGenerator:: @@ -211,12 +244,31 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { "{\n" " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = $name$().begin(); it != $name$().end(); ++it) {\n" + " it = $name$().begin(); it != $name$().end(); ++it) {\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print(variables_, " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n" " $number$, *entry, output);\n" - " }\n" - "}\n"); + " }\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print("}\n"); } void MapFieldGenerator:: @@ -225,13 +277,32 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { "{\n" " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = $name$().begin(); it != $name$().end(); ++it) {\n" + " it = $name$().begin(); it != $name$().end(); ++it) {\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print(variables_, " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" " target = ::google::protobuf::internal::WireFormatLite::\n" " Write$declared_type$NoVirtualToArray(\n" " $number$, *entry, target);\n" - " }\n" - "}\n"); + " }\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print("}\n"); } void MapFieldGenerator:: @@ -241,12 +312,31 @@ GenerateByteSize(io::Printer* printer) const { "{\n" " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = $name$().begin(); it != $name$().end(); ++it) {\n" + " it = $name$().begin(); it != $name$().end(); ++it) {\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print(variables_, " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" " total_size += ::google::protobuf::internal::WireFormatLite::\n" " $declared_type$SizeNoVirtual(*entry);\n" - " }\n" - "}\n"); + " }\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print("}\n"); } } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h index 0ff032fd..d27d4851 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h @@ -50,7 +50,8 @@ class MapFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index d0fd6c6d..bafa36f5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -87,8 +87,8 @@ const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { for (int i = 0; i < descriptor->field_count(); i++) { fields[i] = descriptor->field(i); } - sort(fields, fields + descriptor->field_count(), - FieldOrderingByNumber()); + std::sort(fields, fields + descriptor->field_count(), + FieldOrderingByNumber()); return fields; } @@ -253,7 +253,7 @@ void OptimizePadding(vector<const FieldDescriptor*>* fields) { // Sort by preferred location to keep fields as close to their original // location as possible. Using stable_sort ensures that the output is // consistent across runs. - stable_sort(aligned_to_4.begin(), aligned_to_4.end()); + std::stable_sort(aligned_to_4.begin(), aligned_to_4.end()); // Now group fields aligned to 4 bytes (or the 4-field groups created above) // into pairs, and treat those like a single field aligned to 8 bytes. @@ -269,7 +269,7 @@ void OptimizePadding(vector<const FieldDescriptor*>* fields) { aligned_to_8.push_back(field_group); } // Sort by preferred location. - stable_sort(aligned_to_8.begin(), aligned_to_8.end()); + std::stable_sort(aligned_to_8.begin(), aligned_to_8.end()); // Now pull out all the FieldDescriptors in order. fields->clear(); @@ -347,11 +347,11 @@ void CollectMapInfo(const Descriptor* descriptor, default: (*variables)["val"] = PrimitiveTypeName(val->cpp_type()); } - (*variables)["key_type"] = - "::google::protobuf::FieldDescriptor::TYPE_" + + (*variables)["key_wire_type"] = + "::google::protobuf::internal::WireFormatLite::TYPE_" + ToUpper(DeclaredTypeMethodName(key->type())); - (*variables)["val_type"] = - "::google::protobuf::FieldDescriptor::TYPE_" + + (*variables)["val_wire_type"] = + "::google::protobuf::internal::WireFormatLite::TYPE_" + ToUpper(DeclaredTypeMethodName(val->type())); } @@ -453,17 +453,17 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { vars["constant_name"] = FieldConstantName(field); if (field->is_repeated()) { - printer->Print(vars, "inline int $name$_size() const$deprecation$;\n"); + printer->Print(vars, "int $name$_size() const$deprecation$;\n"); } else if (HasHasMethod(field)) { - printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n"); + printer->Print(vars, "bool has_$name$() const$deprecation$;\n"); } else if (HasPrivateHasMethod(field)) { printer->Print(vars, "private:\n" - "inline bool has_$name$() const$deprecation$;\n" + "bool has_$name$() const$deprecation$;\n" "public:\n"); } - printer->Print(vars, "inline void clear_$name$()$deprecation$;\n"); + printer->Print(vars, "void clear_$name$()$deprecation$;\n"); printer->Print(vars, "static const int $constant_name$ = $number$;\n"); // Generate type-specific accessor declarations. @@ -482,7 +482,7 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { printer->Print( - "inline $camel_oneof_name$Case $oneof_name$_case() const;\n", + "$camel_oneof_name$Case $oneof_name$_case() const;\n", "camel_oneof_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true), "oneof_name", descriptor_->oneof_decl(i)->name()); @@ -490,7 +490,7 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { } void MessageGenerator:: -GenerateFieldAccessorDefinitions(io::Printer* printer) { +GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) { printer->Print("// $classname$\n\n", "classname", classname_); for (int i = 0; i < descriptor_->field_count(); i++) { @@ -500,11 +500,12 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { map<string, string> vars; SetCommonFieldVariables(field, &vars, options_); + vars["inline"] = is_inline ? "inline" : ""; // Generate has_$name$() or $name$_size(). if (field->is_repeated()) { printer->Print(vars, - "inline int $classname$::$name$_size() const {\n" + "$inline$ int $classname$::$name$_size() const {\n" " return $name$_.size();\n" "}\n"); } else if (field->containing_oneof()) { @@ -518,11 +519,11 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { vars["oneof_name"] = field->containing_oneof()->name(); vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index()); printer->Print(vars, - "inline bool $classname$::has_$name$() const {\n" + "$inline$ bool $classname$::has_$name$() const {\n" " return $oneof_name$_case() == k$field_name$;\n" "}\n"); printer->Print(vars, - "inline void $classname$::set_has_$name$() {\n" + "$inline$ void $classname$::set_has_$name$() {\n" " _oneof_case_[$oneof_index$] = k$field_name$;\n" "}\n"); } else { @@ -535,13 +536,13 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer); printer->Print(vars, - "inline bool $classname$::has_$name$() const {\n" + "$inline$ bool $classname$::has_$name$() const {\n" " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n" "}\n" - "inline void $classname$::set_has_$name$() {\n" + "$inline$ void $classname$::set_has_$name$() {\n" " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n" "}\n" - "inline void $classname$::clear_has_$name$() {\n" + "$inline$ void $classname$::clear_has_$name$() {\n" " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n" "}\n" ); @@ -551,12 +552,12 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { bool is_lazy = false; if (is_lazy) { printer->Print(vars, - "inline bool $classname$::has_$name$() const {\n" + "$inline$ bool $classname$::has_$name$() const {\n" " return !$name$_.IsCleared();\n" "}\n"); } else { printer->Print(vars, - "inline bool $classname$::has_$name$() const {\n" + "$inline$ bool $classname$::has_$name$() const {\n" " return !_is_default_instance_ && $name$_ != NULL;\n" "}\n"); } @@ -566,7 +567,7 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { // Generate clear_$name$() printer->Print(vars, - "inline void $classname$::clear_$name$() {\n"); + "$inline$ void $classname$::clear_$name$() {\n"); printer->Indent(); @@ -595,7 +596,8 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { printer->Print("}\n"); // Generate type-specific accessors. - field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); + field_generators_.get(field).GenerateInlineAccessorDefinitions(printer, + is_inline); printer->Print("\n"); } @@ -608,12 +610,13 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { vars["cap_oneof_name"] = ToUpper(descriptor_->oneof_decl(i)->name()); vars["classname"] = classname_; + vars["inline"] = is_inline ? "inline" : ""; printer->Print( vars, - "inline bool $classname$::has_$oneof_name$() const {\n" + "$inline$ bool $classname$::has_$oneof_name$() const {\n" " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n" "}\n" - "inline void $classname$::clear_has_$oneof_name$() {\n" + "$inline$ void $classname$::clear_has_$oneof_name$() {\n" " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n" "}\n"); } @@ -1169,18 +1172,18 @@ GenerateClassDefinition(io::Printer* printer) { } void MessageGenerator:: -GenerateInlineMethods(io::Printer* printer) { +GenerateInlineMethods(io::Printer* printer, bool is_inline) { for (int i = 0; i < descriptor_->nested_type_count(); i++) { // map entry message doesn't need inline methods. Since map entry message // cannot be a top level class, we just need to avoid calling // GenerateInlineMethods here. if (IsMapEntryMessage(descriptor_->nested_type(i))) continue; - nested_generators_[i]->GenerateInlineMethods(printer); + nested_generators_[i]->GenerateInlineMethods(printer, is_inline); printer->Print(kThinSeparator); printer->Print("\n"); } - GenerateFieldAccessorDefinitions(printer); + GenerateFieldAccessorDefinitions(printer, is_inline); // Generate oneof_case() functions. for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { @@ -1190,9 +1193,10 @@ GenerateInlineMethods(io::Printer* printer) { descriptor_->oneof_decl(i)->name(), true); vars["oneof_name"] = descriptor_->oneof_decl(i)->name(); vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index()); + vars["inline"] = is_inline ? "inline " : ""; printer->Print( vars, - "inline $class_name$::$camel_oneof_name$Case $class_name$::" + "$inline$$class_name$::$camel_oneof_name$Case $class_name$::" "$oneof_name$_case() const {\n" " return $class_name$::$camel_oneof_name$Case(" "_oneof_case_[$oneof_index$]);\n" @@ -1222,7 +1226,9 @@ GenerateDescriptorDeclarations(io::Printer* printer) { for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); printer->Print(" "); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || + (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING && + EffectiveStringCType(field) != FieldOptions::STRING)) { printer->Print("const "); } field_generators_.get(field).GeneratePrivateMembers(printer); @@ -1391,8 +1397,8 @@ GenerateTypeRegistrations(io::Printer* printer) { " ::google::protobuf::internal::MapEntry<\n" " $key$,\n" " $val$,\n" - " $key_type$,\n" - " $val_type$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" " $default_enum_value$>::CreateDefaultInstance(\n" " $classname$_descriptor_));\n"); } @@ -2034,17 +2040,16 @@ GenerateClear(io::Printer* printer) { // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0. // The generated code uses two macros to help it clear runs of fields: - // OFFSET_OF_FIELD_ computes the offset (in bytes) of a field in the Message. + // ZR_HELPER_(f1) - ZR_HELPER_(f0) computes the difference, in bytes, of the + // positions of two fields in the Message. // ZR_ zeroes a non-empty range of fields via memset. const char* macros = - "#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \\\n" - " &reinterpret_cast<$classname$*>(16)->f) - \\\n" - " reinterpret_cast<char*>(16))\n\n" - "#define ZR_(first, last) do { \\\n" - " size_t f = OFFSET_OF_FIELD_(first); \\\n" - " size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \\\n" - " ::memset(&first, 0, n); \\\n" - " } while (0)\n\n"; + "#define ZR_HELPER_(f) reinterpret_cast<char*>(\\\n" + " &reinterpret_cast<$classname$*>(16)->f)\n\n" + "#define ZR_(first, last) do {\\\n" + " ::memset(&first, 0,\\\n" + " ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n" + "} while (0)\n\n"; for (int i = 0; i < runs_of_fields_.size(); i++) { const vector<string>& run = runs_of_fields_[i]; if (run.size() < 2) continue; @@ -2133,7 +2138,7 @@ GenerateClear(io::Printer* printer) { } if (macros_are_needed) { printer->Outdent(); - printer->Print("\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n"); + printer->Print("\n#undef ZR_HELPER_\n#undef ZR_\n\n"); printer->Indent(); } @@ -2919,8 +2924,8 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { for (int i = 0; i < descriptor_->extension_range_count(); ++i) { sorted_extensions.push_back(descriptor_->extension_range(i)); } - sort(sorted_extensions.begin(), sorted_extensions.end(), - ExtensionRangeSorter()); + std::sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeSorter()); // Merge the fields and the extension ranges, both sorted by field number. int i, j; diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index dfbc9af5..ea96581d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -82,7 +82,7 @@ class MessageGenerator { // Generate definitions of inline methods (placed at the end of the header // file). - void GenerateInlineMethods(io::Printer* printer); + void GenerateInlineMethods(io::Printer* printer, bool is_inline); // Source file stuff. @@ -116,7 +116,7 @@ class MessageGenerator { private: // Generate declarations and definitions of accessors for fields. void GenerateFieldAccessorDeclarations(io::Printer* printer); - void GenerateFieldAccessorDefinitions(io::Printer* printer); + void GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline); // Generate the field offsets array. void GenerateOffsets(io::Printer* printer); diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index b3cd0ba1..467b6bf6 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -85,76 +85,141 @@ GeneratePrivateMembers(io::Printer* printer) const { void MessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + "private:\n" + "void _slow_mutable_$name$()$deprecation$;\n"); + if (SupportsArenas(descriptor_->message_type())) { + printer->Print(variables_, + "void _slow_set_allocated_$name$(\n" + " ::google::protobuf::Arena* message_arena, $type$** $name$)$deprecation$;\n"); + } + printer->Print(variables_, + "$type$* _slow_$release_name$()$deprecation$;\n" + "public:\n"); + } printer->Print(variables_, - "inline const $type$& $name$() const$deprecation$;\n" - "inline $type$* mutable_$name$()$deprecation$;\n" - "inline $type$* $release_name$()$deprecation$;\n" - "inline void set_allocated_$name$($type$* $name$)$deprecation$;\n"); + "const $type$& $name$() const$deprecation$;\n" + "$type$* mutable_$name$()$deprecation$;\n" + "$type$* $release_name$()$deprecation$;\n" + "void set_allocated_$name$($type$* $name$)$deprecation$;\n"); if (SupportsArenas(descriptor_)) { printer->Print(variables_, - "inline $type$* unsafe_arena_release_$name$()$deprecation$;\n" - "inline void unsafe_arena_set_allocated_$name$(\n" + "$type$* unsafe_arena_release_$name$()$deprecation$;\n" + "void unsafe_arena_set_allocated_$name$(\n" " $type$* $name$)$deprecation$;\n"); } } +void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( + io::Printer* printer) const { + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + "void $classname$::_slow_mutable_$name$() {\n"); + if (SupportsArenas(descriptor_->message_type())) { + printer->Print(variables_, + " $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n" + " GetArenaNoVirtual());\n"); + } else { + printer->Print(variables_, + " $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n" + " GetArenaNoVirtual());\n"); + } + printer->Print(variables_, + "}\n" + "$type$* $classname$::_slow_$release_name$() {\n" + " if ($name$_ == NULL) {\n" + " return NULL;\n" + " } else {\n" + " $type$* temp = new $type$;\n" + " temp->MergeFrom(*$name$_);\n" + " $name$_ = NULL;\n" + " return temp;\n" + " }\n" + "}\n" + "$type$* $classname$::unsafe_arena_release_$name$() {\n" + " $clear_hasbit$\n" + " $type$* temp = $name$_;\n" + " $name$_ = NULL;\n" + " return temp;\n" + "}\n"); + if (SupportsArenas(descriptor_->message_type())) { + printer->Print(variables_, + "void $classname$::_slow_set_allocated_$name$(\n" + " ::google::protobuf::Arena* message_arena, $type$** $name$) {\n" + " if (message_arena != NULL && \n" + " ::google::protobuf::Arena::GetArena(*$name$) == NULL) {\n" + " message_arena->Own(*$name$);\n" + " } else if (message_arena !=\n" + " ::google::protobuf::Arena::GetArena(*$name$)) {\n" + " $type$* new_$name$ = \n" + " ::google::protobuf::Arena::CreateMessage< $type$ >(\n" + " message_arena);\n" + " new_$name$->CopyFrom(**$name$);\n" + " *$name$ = new_$name$;\n" + " }\n" + "}\n"); + } + printer->Print(variables_, + "void $classname$::unsafe_arena_set_allocated_$name$(\n" + " $type$* $name$) {\n" + // If we're not on an arena, free whatever we were holding before. + // (If we are on arena, we can just forget the earlier pointer.) + " if (GetArenaNoVirtual() == NULL) {\n" + " delete $name$_;\n" + " }\n" + " $name$_ = $name$;\n" + " if ($name$) {\n" + " $set_hasbit$\n" + " } else {\n" + " $clear_hasbit$\n" + " }\n" + " // @@protoc_insertion_point(field_unsafe_arena_set_allocated" + ":$full_name$)\n" + "}\n"); + } +} + void MessageFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const $type$& $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ const $type$& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n"); PrintHandlingOptionalStaticInitializers( - variables_, descriptor_->file(), printer, + variables, descriptor_->file(), printer, // With static initializers. " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n", // Without. " return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n"); if (SupportsArenas(descriptor_)) { - printer->Print(variables_, + printer->Print(variables, "}\n" - "inline $type$* $classname$::mutable_$name$() {\n" + "$inline$ $type$* $classname$::mutable_$name$() {\n" " $set_hasbit$\n" - " if ($name$_ == NULL) {\n"); - if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, - " $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n" - " GetArenaNoVirtual());\n"); - } else { - printer->Print(variables_, - " $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n" - " GetArenaNoVirtual());\n"); - } - printer->Print(variables_, " }\n" + " if ($name$_ == NULL) {\n" + " _slow_mutable_$name$();" + " }\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_;\n" "}\n" - "inline $type$* $classname$::$release_name$() {\n" + "$inline$ $type$* $classname$::$release_name$() {\n" " $clear_hasbit$\n" " if (GetArenaNoVirtual() != NULL) {\n" - " if ($name$_ == NULL) {\n" - " return NULL;\n" - " } else {\n" - " $type$* temp = new $type$;\n" - " temp->MergeFrom(*$name$_);\n" - " $name$_ = NULL;\n" - " return temp;\n" - " }\n" + " return _slow_$release_name$();\n" " } else {\n" " $type$* temp = $name$_;\n" " $name$_ = NULL;\n" " return temp;\n" " }\n" "}\n" - "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" - " $clear_hasbit$\n" - " $type$* temp = $name$_;\n" - " $name$_ = NULL;\n" - " return temp;\n" - "}\n" - "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" - " if (GetArenaNoVirtual() == NULL) {\n" + "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n" + " ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();\n" + " if (message_arena == NULL) {\n" " delete $name$_;\n" " }\n" " if ($name$ != NULL) {\n"); @@ -164,26 +229,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { // so we might as well defer it. Otherwise, if incoming message is on a // different ownership domain (specific arena, or the heap) than we are, // copy to our arena (or heap, as the case may be). - printer->Print(variables_, - " if (GetArenaNoVirtual() != NULL && \n" - " ::google::protobuf::Arena::GetArena($name$) == NULL) {\n" - " GetArenaNoVirtual()->Own($name$);\n" - " } else if (GetArenaNoVirtual() !=\n" - " ::google::protobuf::Arena::GetArena($name$)) {\n" - " $type$* new_$name$ = \n" - " ::google::protobuf::Arena::CreateMessage< $type$ >(\n" - " GetArenaNoVirtual());\n" - " new_$name$->CopyFrom(*$name$);\n" - " $name$ = new_$name$;\n" - " }\n"); + printer->Print(variables, + " _slow_set_allocated_$name$(message_arena, &$name$);\n"); } else { - printer->Print(variables_, - " if (GetArenaNoVirtual() != NULL) {\n" - " GetArenaNoVirtual()->Own($name$);\n" + printer->Print(variables, + " if (message_arena != NULL) {\n" + " message_arena->Own($name$);\n" " }\n"); } - - printer->Print(variables_, + printer->Print(variables, " }\n" " $name$_ = $name$;\n" " if ($name$) {\n" @@ -192,27 +246,11 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $clear_hasbit$\n" " }\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$(\n" - " $type$* $name$) {\n" - // If we're not on an arena, free whatever we were holding before. - // (If we are on arena, we can just forget the earlier pointer.) - " if (GetArenaNoVirtual() == NULL) {\n" - " delete $name$_;\n" - " }\n" - " $name$_ = $name$;\n" - " if ($name$) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - " // @@protoc_insertion_point(field_unsafe_arena_set_allocated" - ":$full_name$)\n" "}\n"); } else { - printer->Print(variables_, + printer->Print(variables, "}\n" - "inline $type$* $classname$::mutable_$name$() {\n" + "$inline$ $type$* $classname$::mutable_$name$() {\n" " $set_hasbit$\n" " if ($name$_ == NULL) {\n" " $name$_ = new $type$;\n" @@ -220,17 +258,17 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_;\n" "}\n" - "inline $type$* $classname$::$release_name$() {\n" + "$inline$ $type$* $classname$::$release_name$() {\n" " $clear_hasbit$\n" " $type$* temp = $name$_;\n" " $name$_ = NULL;\n" " return temp;\n" "}\n" - "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n" " delete $name$_;\n"); if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, + printer->Print(variables, " if ($name$ != NULL && $name$->GetArena() != NULL) {\n" " $type$* new_$name$ = new $type$;\n" " new_$name$->CopyFrom(*$name$);\n" @@ -238,7 +276,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " }\n"); } - printer->Print(variables_, + printer->Print(variables, " $name$_ = $name$;\n" " if ($name$) {\n" " $set_hasbit$\n" @@ -328,35 +366,38 @@ MessageOneofFieldGenerator(const FieldDescriptor* descriptor, MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {} void MessageOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; if (SupportsArenas(descriptor_)) { - printer->Print(variables_, - "inline const $type$& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const $type$& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return has_$name$() ? *$oneof_prefix$$name$_\n" " : $type$::default_instance();\n" "}\n" - "inline $type$* $classname$::mutable_$name$() {\n" + "$inline$ $type$* $classname$::mutable_$name$() {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n"); if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, + printer->Print(variables, " $oneof_prefix$$name$_ = \n" " ::google::protobuf::Arena::CreateMessage< $type$ >(\n" " GetArenaNoVirtual());\n"); } else { - printer->Print(variables_, + printer->Print(variables, " $oneof_prefix$$name$_ = \n" " ::google::protobuf::Arena::Create< $type$ >(\n" " GetArenaNoVirtual());\n"); } - printer->Print(variables_, + printer->Print(variables, " }\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $oneof_prefix$$name$_;\n" "}\n" - "inline $type$* $classname$::$release_name$() {\n" + "$inline$ $type$* $classname$::$release_name$() {\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" " if (GetArenaNoVirtual() != NULL) {\n" @@ -375,7 +416,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" + "$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" " $type$* temp = $oneof_prefix$$name$_;\n" @@ -385,12 +426,12 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n" " clear_$oneof_name$();\n" " if ($name$) {\n"); if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, + printer->Print(variables, // If incoming message is on the heap and we are on an arena, just Own() // it (see above). If it's on a different arena than we are or one of us // is on the heap, we make a copy to our arena/heap. @@ -406,19 +447,19 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $name$ = new_$name$;\n" " }\n"); } else { - printer->Print(variables_, + printer->Print(variables, " if (GetArenaNoVirtual() != NULL) {\n" " GetArenaNoVirtual()->Own($name$);\n" " }\n"); } - printer->Print(variables_, + printer->Print(variables, " set_has_$name$();\n" " $oneof_prefix$$name$_ = $name$;\n" " }\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$(" + "$inline$ void $classname$::unsafe_arena_set_allocated_$name$(" "$type$* $name$) {\n" // We rely on the oneof clear method to free the earlier contents of this // oneof. We can directly use the pointer we're given to set the new @@ -432,13 +473,13 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "$full_name$)\n" "}\n"); } else { - printer->Print(variables_, - "inline const $type$& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const $type$& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return has_$name$() ? *$oneof_prefix$$name$_\n" " : $type$::default_instance();\n" "}\n" - "inline $type$* $classname$::mutable_$name$() {\n" + "$inline$ $type$* $classname$::mutable_$name$() {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -447,7 +488,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $oneof_prefix$$name$_;\n" "}\n" - "inline $type$* $classname$::$release_name$() {\n" + "$inline$ $type$* $classname$::$release_name$() {\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" " $type$* temp = $oneof_prefix$$name$_;\n" @@ -457,18 +498,18 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n" " clear_$oneof_name$();\n" " if ($name$) {\n"); if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, + printer->Print(variables, " if ($name$->GetArena() != NULL) {\n" " $type$* new_$name$ = new $type$;\n" " new_$name$->CopyFrom(*$name$);\n" " $name$ = new_$name$;\n" " }\n"); } - printer->Print(variables_, + printer->Print(variables, " set_has_$name$();\n" " $oneof_prefix$$name$_ = $name$;\n" " }\n" @@ -521,38 +562,41 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedMessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline const $type$& $name$(int index) const$deprecation$;\n" - "inline $type$* mutable_$name$(int index)$deprecation$;\n" - "inline $type$* add_$name$()$deprecation$;\n"); + "const $type$& $name$(int index) const$deprecation$;\n" + "$type$* mutable_$name$(int index)$deprecation$;\n" + "$type$* add_$name$()$deprecation$;\n"); printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" + "const ::google::protobuf::RepeatedPtrField< $type$ >&\n" " $name$() const$deprecation$;\n" - "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" + "::google::protobuf::RepeatedPtrField< $type$ >*\n" " mutable_$name$()$deprecation$;\n"); } void RepeatedMessageFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const $type$& $classname$::$name$(int index) const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ const $type$& $classname$::$name$(int index) const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.$cppget$(index);\n" "}\n" - "inline $type$* $classname$::mutable_$name$(int index) {\n" + "$inline$ $type$* $classname$::mutable_$name$(int index) {\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_.Mutable(index);\n" "}\n" - "inline $type$* $classname$::add_$name$() {\n" + "$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" + printer->Print(variables, + "$inline$ const ::google::protobuf::RepeatedPtrField< $type$ >&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_list:$full_name$)\n" " return $name$_;\n" "}\n" - "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" + "$inline$ ::google::protobuf::RepeatedPtrField< $type$ >*\n" "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" " return &$name$_;\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h index 2dff3144..c1704fc1 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h @@ -53,7 +53,9 @@ class MessageFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; + void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; @@ -78,7 +80,9 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { ~MessageOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; + void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {} void GenerateClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; @@ -96,7 +100,8 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc index 9a2c930e..329eae32 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -117,18 +117,20 @@ GeneratePrivateMembers(io::Printer* printer) const { void PrimitiveFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline $type$ $name$() const$deprecation$;\n" - "inline void set_$name$($type$ value)$deprecation$;\n"); + "$type$ $name$() const$deprecation$;\n" + "void set_$name$($type$ value)$deprecation$;\n"); } void PrimitiveFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_;\n" "}\n" - "inline void $classname$::set_$name$($type$ value) {\n" + "$inline$ void $classname$::set_$name$($type$ value) {\n" " $set_hasbit$\n" " $name$_ = value;\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" @@ -204,16 +206,18 @@ PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {} void PrimitiveOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " if (has_$name$()) {\n" " return $oneof_prefix$$name$_;\n" " }\n" " return $default$;\n" "}\n" - "inline void $classname$::set_$name$($type$ value) {\n" + "$inline$ void $classname$::set_$name$($type$ value) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -282,38 +286,40 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline $type$ $name$(int index) const$deprecation$;\n" - "inline void set_$name$(int index, $type$ value)$deprecation$;\n" - "inline void add_$name$($type$ value)$deprecation$;\n"); + "$type$ $name$(int index) const$deprecation$;\n" + "void set_$name$(int index, $type$ value)$deprecation$;\n" + "void add_$name$($type$ value)$deprecation$;\n"); printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField< $type$ >&\n" + "const ::google::protobuf::RepeatedField< $type$ >&\n" " $name$() const$deprecation$;\n" - "inline ::google::protobuf::RepeatedField< $type$ >*\n" + "::google::protobuf::RepeatedField< $type$ >*\n" " mutable_$name$()$deprecation$;\n"); } void RepeatedPrimitiveFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$(int index) const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$(int index) const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.Get(index);\n" "}\n" - "inline void $classname$::set_$name$(int index, $type$ value) {\n" + "$inline$ void $classname$::set_$name$(int index, $type$ value) {\n" " $name$_.Set(index, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::add_$name$($type$ value) {\n" + "$inline$ void $classname$::add_$name$($type$ value) {\n" " $name$_.Add(value);\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n"); - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField< $type$ >&\n" + printer->Print(variables, + "$inline$ const ::google::protobuf::RepeatedField< $type$ >&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_list:$full_name$)\n" " return $name$_;\n" "}\n" - "inline ::google::protobuf::RepeatedField< $type$ >*\n" + "$inline$ ::google::protobuf::RepeatedField< $type$ >*\n" "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" " return &$name$_;\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h index 97b5e867..fcd7d684 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h @@ -53,7 +53,8 @@ class PrimitiveFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; @@ -78,7 +79,8 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator { ~PrimitiveOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; @@ -97,7 +99,8 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 04ed08c9..1a1bcd3d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -127,7 +127,11 @@ GenerateAccessorDeclarations(io::Printer* printer) const { // files that applied the ctype. The field can still be accessed via the // reflection interface since the reflection interface is independent of // the string's underlying representation. - if (descriptor_->options().ctype() != FieldOptions::STRING) { + + bool unknown_ctype = + descriptor_->options().ctype() != EffectiveStringCType(descriptor_); + + if (unknown_ctype) { printer->Outdent(); printer->Print( " private:\n" @@ -136,23 +140,23 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } printer->Print(variables_, - "inline const ::std::string& $name$() const$deprecation$;\n" - "inline void set_$name$(const ::std::string& value)$deprecation$;\n" - "inline void set_$name$(const char* value)$deprecation$;\n" - "inline void set_$name$(const $pointer_type$* value, size_t size)" + "const ::std::string& $name$() const$deprecation$;\n" + "void set_$name$(const ::std::string& value)$deprecation$;\n" + "void set_$name$(const char* value)$deprecation$;\n" + "void set_$name$(const $pointer_type$* value, size_t size)" "$deprecation$;\n" - "inline ::std::string* mutable_$name$()$deprecation$;\n" - "inline ::std::string* $release_name$()$deprecation$;\n" - "inline void set_allocated_$name$(::std::string* $name$)$deprecation$;\n"); + "::std::string* mutable_$name$()$deprecation$;\n" + "::std::string* $release_name$()$deprecation$;\n" + "void set_allocated_$name$(::std::string* $name$)$deprecation$;\n"); if (SupportsArenas(descriptor_)) { printer->Print(variables_, - "inline ::std::string* unsafe_arena_release_$name$()$deprecation$;\n" - "inline void unsafe_arena_set_allocated_$name$(\n" + "::std::string* unsafe_arena_release_$name$()$deprecation$;\n" + "void unsafe_arena_set_allocated_$name$(\n" " ::std::string* $name$)$deprecation$;\n"); } - if (descriptor_->options().ctype() != FieldOptions::STRING) { + if (unknown_ctype) { printer->Outdent(); printer->Print(" public:\n"); printer->Indent(); @@ -160,25 +164,28 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } void StringFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; if (SupportsArenas(descriptor_)) { - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const ::std::string& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.Get($default_variable$);\n" "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" + "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n" " $set_hasbit$\n" " $name$_.Set($default_variable$, value, GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" + "$inline$ void $classname$::set_$name$(const char* value) {\n" " $set_hasbit$\n" " $name$_.Set($default_variable$, $string_piece$(value),\n" " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" - "inline " + "$inline$ " "void $classname$::set_$name$(const $pointer_type$* value,\n" " size_t size) {\n" " $set_hasbit$\n" @@ -186,22 +193,22 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::mutable_$name$() {\n" + "$inline$ ::std::string* $classname$::mutable_$name$() {\n" " $set_hasbit$\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_.Mutable($default_variable$, GetArenaNoVirtual());\n" "}\n" - "inline ::std::string* $classname$::$release_name$() {\n" + "$inline$ ::std::string* $classname$::$release_name$() {\n" " $clear_hasbit$\n" " return $name$_.Release($default_variable$, GetArenaNoVirtual());\n" "}\n" - "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n" + "$inline$ ::std::string* $classname$::unsafe_arena_release_$name$() {\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " $clear_hasbit$\n" " return $name$_.UnsafeArenaRelease($default_variable$,\n" " GetArenaNoVirtual());\n" "}\n" - "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n" " if ($name$ != NULL) {\n" " $set_hasbit$\n" " } else {\n" @@ -211,7 +218,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$(\n" + "$inline$ void $classname$::unsafe_arena_set_allocated_$name$(\n" " ::std::string* $name$) {\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " if ($name$ != NULL) {\n" @@ -226,22 +233,22 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "}\n"); } else { // No-arena case. - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const ::std::string& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.GetNoArena($default_variable$);\n" "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" + "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n" " $set_hasbit$\n" " $name$_.SetNoArena($default_variable$, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" + "$inline$ void $classname$::set_$name$(const char* value) {\n" " $set_hasbit$\n" " $name$_.SetNoArena($default_variable$, $string_piece$(value));\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" - "inline " + "$inline$ " "void $classname$::set_$name$(const $pointer_type$* value, " "size_t size) {\n" " $set_hasbit$\n" @@ -249,16 +256,16 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $string_piece$(reinterpret_cast<const char*>(value), size));\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::mutable_$name$() {\n" + "$inline$ ::std::string* $classname$::mutable_$name$() {\n" " $set_hasbit$\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_.MutableNoArena($default_variable$);\n" "}\n" - "inline ::std::string* $classname$::$release_name$() {\n" + "$inline$ ::std::string* $classname$::$release_name$() {\n" " $clear_hasbit$\n" " return $name$_.ReleaseNoArena($default_variable$);\n" "}\n" - "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n" " if ($name$ != NULL) {\n" " $set_hasbit$\n" " } else {\n" @@ -422,17 +429,20 @@ StringOneofFieldGenerator(const FieldDescriptor* descriptor, StringOneofFieldGenerator::~StringOneofFieldGenerator() {} void StringOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; if (SupportsArenas(descriptor_)) { - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const ::std::string& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " if (has_$name$()) {\n" " return $oneof_prefix$$name$_.Get($default_variable$);\n" " }\n" " return *$default_variable$;\n" "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" + "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -442,7 +452,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" + "$inline$ void $classname$::set_$name$(const char* value) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -452,7 +462,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $string_piece$(value), GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" - "inline " + "$inline$ " "void $classname$::set_$name$(const $pointer_type$* value,\n" " size_t size) {\n" " if (!has_$name$()) {\n" @@ -465,7 +475,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::mutable_$name$() {\n" + "$inline$ ::std::string* $classname$::mutable_$name$() {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -475,7 +485,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::$release_name$() {\n" + "$inline$ ::std::string* $classname$::$release_name$() {\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" " return $oneof_prefix$$name$_.Release($default_variable$,\n" @@ -484,7 +494,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n" + "$inline$ ::std::string* $classname$::unsafe_arena_release_$name$() {\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" @@ -494,7 +504,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n" " if (!has_$name$()) {\n" " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" " }\n" @@ -506,7 +516,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " }\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$(" + "$inline$ void $classname$::unsafe_arena_set_allocated_$name$(" "::std::string* $name$) {\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " if (!has_$name$()) {\n" @@ -522,15 +532,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "}\n"); } else { // No-arena case. - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const ::std::string& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " if (has_$name$()) {\n" " return $oneof_prefix$$name$_.GetNoArena($default_variable$);\n" " }\n" " return *$default_variable$;\n" "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" + "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" @@ -540,7 +550,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $oneof_prefix$$name$_.SetNoArena($default_variable$, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" + "$inline$ void $classname$::set_$name$(const char* value) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -550,7 +560,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $string_piece$(value));\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" - "inline " + "$inline$ " "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" @@ -561,7 +571,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " reinterpret_cast<const char*>(value), size));\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::mutable_$name$() {\n" + "$inline$ ::std::string* $classname$::mutable_$name$() {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -570,7 +580,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $oneof_prefix$$name$_.MutableNoArena($default_variable$);\n" "}\n" - "inline ::std::string* $classname$::$release_name$() {\n" + "$inline$ ::std::string* $classname$::$release_name$() {\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" " return $oneof_prefix$$name$_.ReleaseNoArena($default_variable$);\n" @@ -578,7 +588,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n" " if (!has_$name$()) {\n" " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" " }\n" @@ -670,7 +680,10 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedStringFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { // See comment above about unknown ctypes. - if (descriptor_->options().ctype() != FieldOptions::STRING) { + bool unknown_ctype = + descriptor_->options().ctype() != EffectiveStringCType(descriptor_); + + if (unknown_ctype) { printer->Outdent(); printer->Print( " private:\n" @@ -679,26 +692,26 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } printer->Print(variables_, - "inline const ::std::string& $name$(int index) const$deprecation$;\n" - "inline ::std::string* mutable_$name$(int index)$deprecation$;\n" - "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n" - "inline void set_$name$(int index, const char* value)$deprecation$;\n" - "inline " + "const ::std::string& $name$(int index) const$deprecation$;\n" + "::std::string* mutable_$name$(int index)$deprecation$;\n" + "void set_$name$(int index, const ::std::string& value)$deprecation$;\n" + "void set_$name$(int index, const char* value)$deprecation$;\n" + "" "void set_$name$(int index, const $pointer_type$* value, size_t size)" "$deprecation$;\n" - "inline ::std::string* add_$name$()$deprecation$;\n" - "inline void add_$name$(const ::std::string& value)$deprecation$;\n" - "inline void add_$name$(const char* value)$deprecation$;\n" - "inline void add_$name$(const $pointer_type$* value, size_t size)" + "::std::string* add_$name$()$deprecation$;\n" + "void add_$name$(const ::std::string& value)$deprecation$;\n" + "void add_$name$(const char* value)$deprecation$;\n" + "void add_$name$(const $pointer_type$* value, size_t size)" "$deprecation$;\n"); printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const" + "const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const" "$deprecation$;\n" - "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()" + "::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()" "$deprecation$;\n"); - if (descriptor_->options().ctype() != FieldOptions::STRING) { + if (unknown_ctype) { printer->Outdent(); printer->Print(" public:\n"); printer->Indent(); @@ -706,54 +719,57 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } void RepeatedStringFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$(int index) const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ const ::std::string& $classname$::$name$(int index) const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.$cppget$(index);\n" "}\n" - "inline ::std::string* $classname$::mutable_$name$(int index) {\n" + "$inline$ ::std::string* $classname$::mutable_$name$(int index) {\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_.Mutable(index);\n" "}\n" - "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n" + "$inline$ void $classname$::set_$name$(int index, const ::std::string& value) {\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" " $name$_.Mutable(index)->assign(value);\n" "}\n" - "inline void $classname$::set_$name$(int index, const char* value) {\n" + "$inline$ void $classname$::set_$name$(int index, const char* value) {\n" " $name$_.Mutable(index)->assign(value);\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" - "inline void " + "$inline$ void " "$classname$::set_$name$" "(int index, const $pointer_type$* value, size_t size) {\n" " $name$_.Mutable(index)->assign(\n" " reinterpret_cast<const char*>(value), size);\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::add_$name$() {\n" + "$inline$ ::std::string* $classname$::add_$name$() {\n" " return $name$_.Add();\n" "}\n" - "inline void $classname$::add_$name$(const ::std::string& value) {\n" + "$inline$ void $classname$::add_$name$(const ::std::string& value) {\n" " $name$_.Add()->assign(value);\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n" - "inline void $classname$::add_$name$(const char* value) {\n" + "$inline$ void $classname$::add_$name$(const char* value) {\n" " $name$_.Add()->assign(value);\n" " // @@protoc_insertion_point(field_add_char:$full_name$)\n" "}\n" - "inline void " + "$inline$ void " "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n" " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n" " // @@protoc_insertion_point(field_add_pointer:$full_name$)\n" "}\n"); - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n" + printer->Print(variables, + "$inline$ const ::google::protobuf::RepeatedPtrField< ::std::string>&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_list:$full_name$)\n" " return $name$_;\n" "}\n" - "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n" + "$inline$ ::google::protobuf::RepeatedPtrField< ::std::string>*\n" "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" " return &$name$_;\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h index 0a5ca440..d1f19cd9 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h @@ -54,7 +54,8 @@ class StringFieldGenerator : public FieldGenerator { void GeneratePrivateMembers(io::Printer* printer) const; void GenerateStaticMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; @@ -83,7 +84,8 @@ class StringOneofFieldGenerator : public StringFieldGenerator { ~StringOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; @@ -103,7 +105,8 @@ class RepeatedStringFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h index e8d6f3a2..1cf360c1 100644 --- a/src/google/protobuf/compiler/java/java_field.h +++ b/src/google/protobuf/compiler/java/java_field.h @@ -83,6 +83,7 @@ class ImmutableFieldGenerator { virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer) const = 0; + virtual void GenerateStaticInitializationCode(io::Printer* printer) const {} virtual void GenerateEqualsCode(io::Printer* printer) const = 0; virtual void GenerateHashCode(io::Printer* printer) const = 0; diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc index 23685385..e24894b1 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -690,8 +690,8 @@ const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { for (int i = 0; i < descriptor->field_count(); i++) { fields[i] = descriptor->field(i); } - sort(fields, fields + descriptor->field_count(), - FieldOrderingByNumber()); + std::sort(fields, fields + descriptor->field_count(), + FieldOrderingByNumber()); return fields; } diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h index d957fdc4..62efbefa 100644 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ b/src/google/protobuf/compiler/java/java_helpers.h @@ -297,6 +297,16 @@ struct ExtensionRangeOrdering { // and return it. The caller should delete the returned array. const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor); +// Does this message class have any packed fields? +inline bool HasPackedFields(const Descriptor* descriptor) { + for (int i = 0; i < descriptor->field_count(); i++) { + if (descriptor->field(i)->is_packed()) { + return true; + } + } + return false; +} + // Check a message type and its sub-message types recursively to see if any of // them has a required field. Return true if a required field is found. bool HasRequiredFields(const Descriptor* descriptor); diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field.cc b/src/google/protobuf/compiler/java/java_lazy_message_field.cc index 21cab7db..6e29a40b 100644 --- a/src/google/protobuf/compiler/java/java_lazy_message_field.cc +++ b/src/google/protobuf/compiler/java/java_lazy_message_field.cc @@ -243,9 +243,8 @@ GenerateBuildingCode(io::Printer* printer) const { "}\n"); printer->Print(variables_, - "result.$name$_.setByteString(\n" - " $name$_.toByteString(),\n" - " $name$_.getExtensionRegistry());\n"); + "result.$name$_.set(\n" + " $name$_);\n"); } void ImmutableLazyMessageFieldGenerator:: @@ -425,9 +424,8 @@ GenerateBuildingCode(io::Printer* printer) const { printer->Print(variables_, "result.$oneof_name$_ = new $lazy_type$();\n" - "(($lazy_type$) result.$oneof_name$_).setByteString(\n" - " (($lazy_type$) $oneof_name$_).toByteString(),\n" - " (($lazy_type$) $oneof_name$_).getExtensionRegistry());\n"); + "(($lazy_type$) result.$oneof_name$_).set(\n" + " (($lazy_type$) $oneof_name$_));\n"); printer->Outdent(); printer->Print("}\n"); } diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc index 2986f51f..cf1ef589 100644 --- a/src/google/protobuf/compiler/java/java_map_field.cc +++ b/src/google/protobuf/compiler/java/java_map_field.cc @@ -198,25 +198,38 @@ GenerateInterfaceMembers(io::Printer* printer) const { } void ImmutableMapFieldGenerator:: +GenerateStaticInitializationCode(io::Printer* printer) const { + printer->Print( + variables_, + "$name$DefaultEntry =\n" + " com.google.protobuf.MapEntry$lite$\n" + " .<$type_parameters$>newDefaultInstance(\n" + " $descriptor$\n" + " $key_wire_type$,\n" + " $key_default_value$,\n" + " $value_wire_type$,\n" + " $value_default_value$);\n" + "\n"); +} + +void ImmutableMapFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print( variables_, "private static final com.google.protobuf.MapEntry$lite$<\n" - " $type_parameters$> $name$DefaultEntry =\n" - " com.google.protobuf.MapEntry$lite$\n" - " .<$type_parameters$>newDefaultInstance(\n" - " $descriptor$\n" - " $key_wire_type$,\n" - " $key_default_value$,\n" - " $value_wire_type$,\n" - " $value_default_value$);\n"); + " $type_parameters$> $name$DefaultEntry;\n"); printer->Print( variables_, "private com.google.protobuf.MapField$lite$<\n" - " $type_parameters$> $name$_ =\n" - " com.google.protobuf.MapField$lite$.emptyMapField(\n" - " $map_field_parameter$);\n" - "\n"); + " $type_parameters$> $name$_;\n" + "private com.google.protobuf.MapField$lite$<$type_parameters$>\n" + "internalGet$capitalized_name$() {\n" + " if ($name$_ == null) {\n" + " return com.google.protobuf.MapField$lite$.emptyMapField(\n" + " $map_field_parameter$);\n" + " }\n" + " return $name$_;\n" + "}\n"); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -233,7 +246,7 @@ GenerateMembers(io::Printer* printer) const { "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "get$capitalized_name$Value() {\n" - " return $name$_.getMap();\n" + " return internalGet$capitalized_name$().getMap();\n" "}\n"); } WriteFieldDocComment(printer, descriptor_); @@ -244,7 +257,8 @@ GenerateMembers(io::Printer* printer) const { "get$capitalized_name$() {\n" " return new com.google.protobuf.Internal.MapAdapter<\n" " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" - " $name$_.getMap(), $name$ValueConverter);\n" + " internalGet$capitalized_name$().getMap(),\n" + " $name$ValueConverter);\n" "}\n"); } else { WriteFieldDocComment(printer, descriptor_); @@ -252,7 +266,7 @@ GenerateMembers(io::Printer* printer) const { variables_, "$deprecation$\n" "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" - " return $name$_.getMap();\n" + " return internalGet$capitalized_name$().getMap();\n" "}\n"); } } @@ -262,10 +276,24 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print( variables_, "private com.google.protobuf.MapField$lite$<\n" - " $type_parameters$> $name$_ =\n" - " com.google.protobuf.MapField$lite$.newMapField(\n" - " $map_field_parameter$);\n" - "\n"); + " $type_parameters$> $name$_;\n" + "private com.google.protobuf.MapField$lite$<$type_parameters$>\n" + "internalGet$capitalized_name$() {\n" + " if ($name$_ == null) {\n" + " return com.google.protobuf.MapField$lite$.emptyMapField(\n" + " $map_field_parameter$);\n" + " }\n" + " return $name$_;\n" + "}\n" + "private com.google.protobuf.MapField$lite$<$type_parameters$>\n" + "internalGetMutable$capitalized_name$() {\n" + " $on_changed$;\n" + " if ($name$_ == null) {\n" + " $name$_ = com.google.protobuf.MapField$lite$.newMapField(\n" + " $map_field_parameter$);\n" + " }\n" + " return $name$_;\n" + "}\n"); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { WriteFieldDocComment(printer, descriptor_); printer->Print( @@ -275,7 +303,8 @@ GenerateBuilderMembers(io::Printer* printer) const { "get$capitalized_name$() {\n" " return new com.google.protobuf.Internal.MapAdapter<\n" " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" - " $name$_.getMap(), $name$ValueConverter);\n" + " internalGet$capitalized_name$().getMap(),\n" + " $name$ValueConverter);\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( @@ -283,10 +312,10 @@ GenerateBuilderMembers(io::Printer* printer) const { "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" "getMutable$capitalized_name$() {\n" - " $on_changed$\n" " return new com.google.protobuf.Internal.MapAdapter<\n" " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" - " $name$_.getMutableMap(), $name$ValueConverter);\n" + " internalGetMutable$capitalized_name$().getMutableMap(),\n" + " $name$ValueConverter);\n" "}\n"); if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); @@ -295,7 +324,7 @@ GenerateBuilderMembers(io::Printer* printer) const { "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "get$capitalized_name$Value() {\n" - " return $name$_.getMap();\n" + " return internalGet$capitalized_name$().getMap();\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( @@ -303,8 +332,7 @@ GenerateBuilderMembers(io::Printer* printer) const { "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "getMutable$capitalized_name$Value() {\n" - " $on_changed$\n" - " return $name$_.getMutableMap();\n" + " return internalGetMutable$capitalized_name$().getMutableMap();\n" "}\n"); } } else { @@ -312,15 +340,14 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print( variables_, "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" - " return $name$_.getMap();\n" + " return internalGet$capitalized_name$().getMap();\n" "}\n"); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "public java.util.Map<$type_parameters$>\n" "getMutable$capitalized_name$() {\n" - " $on_changed$\n" - " return $name$_.getMutableMap();\n" + " return internalGetMutable$capitalized_name$().getMutableMap();\n" "}\n"); } } @@ -339,14 +366,15 @@ void ImmutableMapFieldGenerator:: GenerateBuilderClearCode(io::Printer* printer) const { printer->Print( variables_, - "$name$_.clear();\n"); + "internalGetMutable$capitalized_name$().clear();\n"); } void ImmutableMapFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { printer->Print( variables_, - "$name$_.mergeFrom(other.$name$_);\n"); + "internalGetMutable$capitalized_name$().mergeFrom(\n" + " other.internalGet$capitalized_name$());\n"); } void ImmutableMapFieldGenerator:: @@ -356,7 +384,7 @@ GenerateBuildingCode(io::Printer* printer) const { // We do a copy of the map field to ensure that the built result is // immutable. Implementation of this copy() method can do copy-on-write // to defer this copy until further modifications are made on the field. - "result.$name$_ = $name$_.copy();\n"); + "result.$name$_ = internalGet$capitalized_name$().copy();\n"); } void ImmutableMapFieldGenerator:: @@ -402,7 +430,7 @@ GenerateSerializationCode(io::Printer* printer) const { printer->Print( variables_, "for (java.util.Map.Entry<$type_parameters$> entry\n" - " : $name$_.getMap().entrySet()) {\n" + " : internalGet$capitalized_name$().getMap().entrySet()) {\n" " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" " $name$ = $name$DefaultEntry.newBuilderForType()\n" " .setKey(entry.getKey())\n" @@ -417,7 +445,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print( variables_, "for (java.util.Map.Entry<$type_parameters$> entry\n" - " : $name$_.getMap().entrySet()) {\n" + " : internalGet$capitalized_name$().getMap().entrySet()) {\n" " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" " $name$ = $name$DefaultEntry.newBuilderForType()\n" " .setKey(entry.getKey())\n" @@ -432,16 +460,17 @@ void ImmutableMapFieldGenerator:: GenerateEqualsCode(io::Printer* printer) const { printer->Print( variables_, - "result = result && $name$_.equals(other.$name$_);\n"); + "result = result && internalGet$capitalized_name$().equals(\n" + " other.internalGet$capitalized_name$());\n"); } void ImmutableMapFieldGenerator:: GenerateHashCode(io::Printer* printer) const { printer->Print( variables_, - "if (!$name$_.getMap().isEmpty()) {\n" + "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n" " hash = (37 * hash) + $constant_name$;\n" - " hash = (53 * hash) + $name$_.hashCode();\n" + " hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n" "}\n"); } diff --git a/src/google/protobuf/compiler/java/java_map_field.h b/src/google/protobuf/compiler/java/java_map_field.h index 80a94f45..3e6dd973 100644 --- a/src/google/protobuf/compiler/java/java_map_field.h +++ b/src/google/protobuf/compiler/java/java_map_field.h @@ -60,6 +60,7 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator { void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateStaticInitializationCode(io::Printer* printer) const; void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 1171b718..e982a17b 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -234,7 +234,8 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { "public interface $classname$OrBuilder extends \n" " $extra_interfaces$\n" " com.google.protobuf.GeneratedMessageLite.\n" - " ExtendableMessageOrBuilder<$classname$> {\n", + " ExtendableMessageOrBuilder<\n" + " $classname$, $classname$.Builder> {\n", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name()); } @@ -285,22 +286,41 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { // The builder_type stores the super type name of the nested Builder class. string builder_type; if (descriptor_->extension_range_count() > 0) { - printer->Print(variables, - "public $static$final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessage$lite$.ExtendableMessage<\n" - " $classname$> implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n"); + if (HasDescriptorMethods(descriptor_)) { + printer->Print(variables, + "public $static$final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n" + " $classname$> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n"); + } else { + printer->Print(variables, + "public $static$final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" + " $classname$, $classname$.Builder> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n"); + } builder_type = strings::Substitute( - "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>", - name_resolver_->GetImmutableClassName(descriptor_), - variables["lite"]); + "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>", + name_resolver_->GetImmutableClassName(descriptor_), + variables["lite"]); } else { - printer->Print(variables, - "public $static$final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessage$lite$ implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n"); + if (HasDescriptorMethods(descriptor_)) { + printer->Print(variables, + "public $static$final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessage implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n"); + } else { + printer->Print(variables, + "public $static$final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessageLite<\n" + " $classname$, $classname$.Builder> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n"); + } + builder_type = strings::Substitute( "com.google.protobuf.GeneratedMessage$0.Builder", variables["lite"]); @@ -349,7 +369,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { GenerateParsingConstructor(printer); } - GenerateDescriptorMethods(printer); + GenerateDescriptorMethods(printer, false); GenerateParser(printer); // Nested types @@ -481,7 +501,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { // Carefully initialize the default instance in such a way that it doesn't // conflict with other initialization. printer->Print( - "private static final $classname$ defaultInstance;", + "private static final $classname$ defaultInstance;\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); if (HasDescriptorMethods(descriptor_)) { printer->Print( @@ -494,15 +514,11 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { // LITE_RUNTIME only has one constructor. printer->Print( "static {\n" - " try {\n" - " defaultInstance = new $classname$(\n" - " com.google.protobuf.Internal\n" - " .EMPTY_CODED_INPUT_STREAM,\n" - " com.google.protobuf.ExtensionRegistryLite\n" - " .getEmptyRegistry());\n" - " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" - " throw new ExceptionInInitializerError(e);\n" - " }\n" + " defaultInstance = new $classname$(\n" + " com.google.protobuf.Internal\n" + " .EMPTY_CODED_INPUT_STREAM,\n" + " com.google.protobuf.ExtensionRegistryLite\n" + " .getEmptyRegistry());\n" "}\n" "\n", "classname", descriptor_->name()); @@ -511,12 +527,30 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { "public static $classname$ getDefaultInstance() {\n" " return defaultInstance;\n" "}\n" - "\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + if (HasDescriptorMethods(descriptor_)) { + // LITE_RUNTIME implements this at the GeneratedMessageLite level. + printer->Print( "public $classname$ getDefaultInstanceForType() {\n" " return defaultInstance;\n" "}\n" "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); + } else { + // LITE_RUNTIME uses this to implement the *ForType methods at the + // GeneratedMessageLite level. + printer->Print( + "static {" + " com.google.protobuf.GeneratedMessageLite.onLoad(\n" + " $classname$.class, new com.google.protobuf.GeneratedMessageLite\n" + " .PrototypeHolder<$classname$, Builder>(\n" + " defaultInstance, PARSER));" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + } // Extensions must be declared after the defaultInstance is initialized // because the defaultInstance is used by the extension to lazily retrieve @@ -526,6 +560,19 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { .Generate(printer); } + // Some fields also have static members that must be initialized after we + // have the default instance available. + printer->Print( + "static {\n"); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateStaticInitializationCode(printer); + } + printer->Outdent(); + printer->Print( + "}\n"); + printer->Outdent(); printer->Print("}\n\n"); } @@ -542,37 +589,55 @@ GenerateMessageSerializationMethods(io::Printer* printer) { for (int i = 0; i < descriptor_->extension_range_count(); ++i) { sorted_extensions.push_back(descriptor_->extension_range(i)); } - sort(sorted_extensions.begin(), sorted_extensions.end(), - ExtensionRangeOrdering()); + std::sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeOrdering()); printer->Print( "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" " throws java.io.IOException {\n"); printer->Indent(); - // writeTo(CodedOutputStream output) might be invoked without - // getSerializedSize() ever being called, but we need the memoized - // sizes in case this message has packed fields. Rather than emit checks for - // each packed field, just call getSerializedSize() up front for all messages. - // In most cases, getSerializedSize() will have already been called anyway by - // one of the wrapper writeTo() methods, making this call cheap. - printer->Print( - "getSerializedSize();\n"); + if (HasPackedFields(descriptor_)) { + // writeTo(CodedOutputStream output) might be invoked without + // getSerializedSize() ever being called, but we need the memoized + // sizes in case this message has packed fields. Rather than emit checks for + // each packed field, just call getSerializedSize() up front. + // In most cases, getSerializedSize() will have already been called anyway + // by one of the wrapper writeTo() methods, making this call cheap. + printer->Print( + "getSerializedSize();\n"); + } if (descriptor_->extension_range_count() > 0) { if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "com.google.protobuf.GeneratedMessage$lite$\n" - " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n" - " newMessageSetExtensionWriter();\n", - "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "com.google.protobuf.GeneratedMessage\n" + " .ExtendableMessage<$classname$>.ExtensionWriter\n" + " extensionWriter = newMessageSetExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + } else { + printer->Print( + "com.google.protobuf.GeneratedMessageLite\n" + " .ExtendableMessage<$classname$, $classname$.Builder>\n" + " .ExtensionWriter extensionWriter =\n" + " newMessageSetExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + } } else { - printer->Print( - "com.google.protobuf.GeneratedMessage$lite$\n" - " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n" - " newExtensionWriter();\n", - "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "com.google.protobuf.GeneratedMessage\n" + " .ExtendableMessage<$classname$>.ExtensionWriter\n" + " extensionWriter = newExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + } else { + printer->Print( + "com.google.protobuf.GeneratedMessageLite\n" + " .ExtendableMessage<$classname$, $classname$.Builder>\n" + " .ExtensionWriter extensionWriter =\n" + " newExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + } } } @@ -727,13 +792,23 @@ void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange( // =================================================================== void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) { + if (HasDescriptorMethods(descriptor_)) { + // LITE_RUNTIME implements this at the GeneratedMessageLite level. + printer->Print( + "public Builder newBuilderForType() { return newBuilder(); }\n"); + } + printer->Print( - "public static Builder newBuilder() { return new Builder(); }\n" - "public Builder newBuilderForType() { return newBuilder(); }\n" + "public static Builder newBuilder() {\n" + " return defaultInstance.toBuilder();\n" + "}\n" "public static Builder newBuilder($classname$ prototype) {\n" - " return newBuilder().mergeFrom(prototype);\n" + " return defaultInstance.toBuilder().mergeFrom(prototype);\n" + "}\n" + "public Builder toBuilder() {\n" + " return this == defaultInstance\n" + " ? new Builder() : new Builder().mergeFrom(this);\n" "}\n" - "public Builder toBuilder() { return newBuilder(this); }\n" "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); @@ -792,7 +867,7 @@ void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) { } printer->Indent(); - GenerateDescriptorMethods(printer); + GenerateDescriptorMethods(printer, true); GenerateCommonBuilderMethods(printer); if (HasGeneratedMethods(descriptor_)) { @@ -876,7 +951,7 @@ void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) { } void ImmutableMessageGenerator:: -GenerateDescriptorMethods(io::Printer* printer) { +GenerateDescriptorMethods(io::Printer* printer, bool is_builder) { if (HasDescriptorMethods(descriptor_)) { if (!descriptor_->options().no_standard_descriptor_accessor()) { printer->Print( @@ -909,9 +984,9 @@ GenerateDescriptorMethods(io::Printer* printer) { const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); printer->Print( "case $number$:\n" - " return $name$_;\n", + " return internalGet$capitalized_name$();\n", "number", SimpleItoa(field->number()), - "name", info->name); + "capitalized_name", info->capitalized_name); } printer->Print( "default:\n" @@ -922,6 +997,34 @@ GenerateDescriptorMethods(io::Printer* printer) { printer->Print( " }\n" "}\n"); + if (is_builder) { + printer->Print( + "@SuppressWarnings({\"rawtypes\"})\n" + "protected com.google.protobuf.MapField internalGetMutableMapField(\n" + " int number) {\n" + " switch (number) {\n"); + printer->Indent(); + printer->Indent(); + for (int i = 0; i < map_fields.size(); ++i) { + const FieldDescriptor* field = map_fields[i]; + const FieldGeneratorInfo* info = + context_->GetFieldGeneratorInfo(field); + printer->Print( + "case $number$:\n" + " return internalGetMutable$capitalized_name$();\n", + "number", SimpleItoa(field->number()), + "capitalized_name", info->capitalized_name); + } + printer->Print( + "default:\n" + " throw new RuntimeException(\n" + " \"Invalid map field number: \" + number);\n"); + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" + "}\n"); + } } printer->Print( "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n" @@ -959,7 +1062,7 @@ GenerateCommonBuilderMethods(io::Printer* printer) { "classname", name_resolver_->GetImmutableClassName(descriptor_)); } else { // LITE runtime passes along the default instance to implement - // getDefaultInstanceForType() at the GneratedMessageLite level. + // getDefaultInstanceForType() at the GeneratedMessageLite level. printer->Print( "// Construct using $classname$.newBuilder()\n" "private Builder() {\n" @@ -1062,22 +1165,17 @@ GenerateCommonBuilderMethods(io::Printer* printer) { if (HasDescriptorMethods(descriptor_)) { printer->Print( "public $classname$ buildPartial() {\n" - " $classname$ result = new $classname$(this);\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + " $classname$ result = new $classname$(this);\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); } else { // LITE_RUNTIME only provides a single message constructor. printer->Print( "public $classname$ buildPartial() {\n" - " $classname$ result = null;\n" - " try {\n" - " result = new $classname$(\n" - " com.google.protobuf.Internal\n" - " .EMPTY_CODED_INPUT_STREAM,\n" - " com.google.protobuf.ExtensionRegistryLite\n" - " .getEmptyRegistry());\n" - " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" - " throw new RuntimeException(e);\n" - " }\n" + " $classname$ result = new $classname$(\n" + " com.google.protobuf.Internal\n" + " .EMPTY_CODED_INPUT_STREAM,\n" + " com.google.protobuf.ExtensionRegistryLite\n" + " .getEmptyRegistry());\n" " result.unknownFields = this.unknownFields;\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); @@ -1271,6 +1369,12 @@ GenerateBuilderParsingMethods(io::Printer* printer) { void ImmutableMessageGenerator::GenerateIsInitialized( io::Printer* printer, UseMemoization useMemoization) { + // LITE_RUNTIME avoids generating isInitialized if it's not needed. + if (!HasDescriptorMethods(descriptor_) + && !HasRequiredFields(descriptor_)) { + return; + } + bool memoization = useMemoization == MEMOIZE; if (memoization) { // Memoizes whether the protocol buffer is fully initialized (has all @@ -1558,8 +1662,7 @@ GenerateParsingConstructor(io::Printer* printer) { printer->Print( "private $classname$(\n" " com.google.protobuf.CodedInputStream input,\n" - " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" - " throws com.google.protobuf.InvalidProtocolBufferException {\n", + " com.google.protobuf.ExtensionRegistryLite extensionRegistry) {\n", "classname", descriptor_->name()); printer->Indent(); @@ -1695,10 +1798,11 @@ GenerateParsingConstructor(io::Printer* printer) { printer->Outdent(); printer->Print( "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" - " throw e.setUnfinishedMessage(this);\n" + " throw new RuntimeException(e.setUnfinishedMessage(this));\n" "} catch (java.io.IOException e) {\n" - " throw new com.google.protobuf.InvalidProtocolBufferException(\n" - " e.getMessage()).setUnfinishedMessage(this);\n" + " throw new RuntimeException(\n" + " new com.google.protobuf.InvalidProtocolBufferException(\n" + " e.getMessage()).setUnfinishedMessage(this));\n" "} finally {\n"); printer->Indent(); @@ -1747,8 +1851,19 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { " throws com.google.protobuf.InvalidProtocolBufferException {\n", "classname", descriptor_->name()); if (HasGeneratedMethods(descriptor_)) { + // The parsing constructor throws an InvalidProtocolBufferException via a + // RuntimeException to aid in method pruning. We unwrap it here. printer->Print( - " return new $classname$(input, extensionRegistry);\n", + " try {\n" + " return new $classname$(input, extensionRegistry);\n" + " } catch (RuntimeException e) {\n" + " if (e.getCause() instanceof\n" + " com.google.protobuf.InvalidProtocolBufferException) {\n" + " throw (com.google.protobuf.InvalidProtocolBufferException)\n" + " e.getCause();\n" + " }\n" + " throw e;\n" + " }\n", "classname", descriptor_->name()); } else { // When parsing constructor isn't generated, use builder to parse messages. @@ -1775,13 +1890,16 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { "};\n" "\n"); - printer->Print( - "@java.lang.Override\n" - "public com.google.protobuf.Parser<$classname$> getParserForType() {\n" - " return PARSER;\n" - "}\n" - "\n", - "classname", descriptor_->name()); + if (HasDescriptorMethods(descriptor_)) { + // LITE_RUNTIME implements this at the GeneratedMessageLite level. + printer->Print( + "@java.lang.Override\n" + "public com.google.protobuf.Parser<$classname$> getParserForType() {\n" + " return PARSER;\n" + "}\n" + "\n", + "classname", descriptor_->name()); + } } // =================================================================== diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h index 91eb2876..016fdd5d 100644 --- a/src/google/protobuf/compiler/java/java_message.h +++ b/src/google/protobuf/compiler/java/java_message.h @@ -117,7 +117,7 @@ class ImmutableMessageGenerator : public MessageGenerator { void GenerateBuilder(io::Printer* printer); void GenerateCommonBuilderMethods(io::Printer* printer); - void GenerateDescriptorMethods(io::Printer* printer); + void GenerateDescriptorMethods(io::Printer* printer, bool is_builder); void GenerateBuilderParsingMethods(io::Printer* printer); void GenerateIsInitialized(io::Printer* printer, UseMemoization useMemoization); diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index e331d7a4..48757c60 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -772,6 +772,9 @@ GenerateParsingDoneCode(io::Printer* printer) const { void RepeatedImmutablePrimitiveFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { if (descriptor_->options().packed()) { + // We invoke getSerializedSize in writeTo for messages that have packed + // fields in ImmutableMessageGenerator::GenerateMessageSerializationMethods. + // That makes it safe to rely on the memoized size here. printer->Print(variables_, "if (get$capitalized_name$List().size() > 0) {\n" " output.writeRawVarint32($tag$);\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 2e61ea8a..70177367 100644 --- a/src/google/protobuf/compiler/java/java_shared_code_generator.cc +++ b/src/google/protobuf/compiler/java/java_shared_code_generator.cc @@ -171,7 +171,7 @@ void SharedCodeGenerator::GenerateDescriptors(io::Printer* printer) { string classname = FileJavaPackage(file_->dependency(i)) + "." + name_resolver_->GetDescriptorClassName( file_->dependency(i)); - dependencies.push_back(make_pair(filename, classname)); + dependencies.push_back(std::make_pair(filename, classname)); } } diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc index 1c9302af..8aa5699c 100644 --- a/src/google/protobuf/compiler/java/java_string_field.cc +++ b/src/google/protobuf/compiler/java/java_string_field.cc @@ -667,7 +667,7 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "String s = input.readStringRequireUtf8();\n" "$set_oneof_case_message$;\n" - "$oneof_name$_ = s;\n}\n"); + "$oneof_name$_ = s;\n"); } else if (!HasDescriptorMethods(descriptor_->file())) { // Lite runtime should attempt to reduce allocations by attempting to // construct the string directly from the input stream buffer. This avoids diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index e7d5117e..98261431 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -133,10 +133,10 @@ bool MockCodeGenerator::Generate( *error = "Saw message type MockCodeGenerator_Error."; return false; } else if (command == "Exit") { - cerr << "Saw message type MockCodeGenerator_Exit." << endl; + std::cerr << "Saw message type MockCodeGenerator_Exit." << std::endl; exit(123); } else if (command == "Abort") { - cerr << "Saw message type MockCodeGenerator_Abort." << endl; + std::cerr << "Saw message type MockCodeGenerator_Abort." << std::endl; abort(); } else if (command == "HasSourceCodeInfo") { FileDescriptorProto file_descriptor_proto; @@ -144,8 +144,8 @@ bool MockCodeGenerator::Generate( bool has_source_code_info = file_descriptor_proto.has_source_code_info() && file_descriptor_proto.source_code_info().location_size() > 0; - cerr << "Saw message type MockCodeGenerator_HasSourceCodeInfo: " - << has_source_code_info << "." << endl; + std::cerr << "Saw message type MockCodeGenerator_HasSourceCodeInfo: " + << has_source_code_info << "." << std::endl; abort(); } else { GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command; diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index fe697acf..c50cdf54 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -277,27 +277,39 @@ bool Parser::ConsumeString(string* output, const char* error) { } } -bool Parser::TryConsumeEndOfDeclaration(const char* text, - const LocationRecorder* location) { +bool Parser::TryConsumeEndOfDeclaration( + const char* text, const LocationRecorder* location) { if (LookingAt(text)) { string leading, trailing; - input_->NextWithComments(&trailing, NULL, &leading); + vector<string> detached; + input_->NextWithComments(&trailing, &detached, &leading); // Save the leading comments for next time, and recall the leading comments // from last time. leading.swap(upcoming_doc_comments_); if (location != NULL) { - location->AttachComments(&leading, &trailing); + upcoming_detached_comments_.swap(detached); + location->AttachComments(&leading, &trailing, &detached); + } else if (strcmp(text, "}") == 0) { + // If the current location is null and we are finishing the current scope, + // drop pending upcoming detached comments. + upcoming_detached_comments_.swap(detached); + } else { + // Otherwise, append the new detached comments to the existing upcoming + // detached comments. + upcoming_detached_comments_.insert(upcoming_detached_comments_.end(), + detached.begin(), detached.end()); } + return true; } else { return false; } } -bool Parser::ConsumeEndOfDeclaration(const char* text, - const LocationRecorder* location) { +bool Parser::ConsumeEndOfDeclaration( + const char* text, const LocationRecorder* location) { if (TryConsumeEndOfDeclaration(text, location)) { return true; } else { @@ -390,7 +402,8 @@ void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor, } void Parser::LocationRecorder::AttachComments( - string* leading, string* trailing) const { + string* leading, string* trailing, + vector<string>* detached_comments) const { GOOGLE_CHECK(!location_->has_leading_comments()); GOOGLE_CHECK(!location_->has_trailing_comments()); @@ -400,6 +413,11 @@ void Parser::LocationRecorder::AttachComments( if (!trailing->empty()) { location_->mutable_trailing_comments()->swap(*trailing); } + for (int i = 0; i < detached_comments->size(); ++i) { + location_->add_leading_detached_comments()->swap( + (*detached_comments)[i]); + } + detached_comments->clear(); } // ------------------------------------------------------------------- @@ -451,16 +469,18 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { SourceCodeInfo source_code_info; source_code_info_ = &source_code_info; + vector<string> top_doc_comments; if (LookingAtType(io::Tokenizer::TYPE_START)) { // Advance to first token. - input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_); + input_->NextWithComments(NULL, &upcoming_detached_comments_, + &upcoming_doc_comments_); } { LocationRecorder root_location(this); if (require_syntax_identifier_ || LookingAt("syntax")) { - if (!ParseSyntaxIdentifier()) { + if (!ParseSyntaxIdentifier(root_location)) { // Don't attempt to parse the file if we didn't recognize the syntax // identifier. return false; @@ -469,9 +489,9 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { if (file != NULL) file->set_syntax(syntax_identifier_); } else if (!stop_after_syntax_identifier_) { GOOGLE_LOG(WARNING) << "No syntax specified for the proto file. " - << "Please use 'syntax = \"proto2\";' or " - << "'syntax = \"proto3\";' to specify a syntax " - << "version. (Defaulted to proto2 syntax.)"; + << "Please use 'syntax = \"proto2\";' or " + << "'syntax = \"proto3\";' to specify a syntax " + << "version. (Defaulted to proto2 syntax.)"; syntax_identifier_ = "proto2"; } @@ -486,7 +506,8 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { if (LookingAt("}")) { AddError("Unmatched \"}\"."); - input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_); + input_->NextWithComments(NULL, &upcoming_detached_comments_, + &upcoming_doc_comments_); } } } @@ -498,7 +519,9 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { return !had_errors_; } -bool Parser::ParseSyntaxIdentifier() { +bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) { + LocationRecorder syntax_location(parent, + FileDescriptorProto::kSyntaxFieldNumber); DO(Consume( "syntax", "File must begin with a syntax statement, e.g. 'syntax = \"proto2\";'.")); @@ -506,7 +529,7 @@ bool Parser::ParseSyntaxIdentifier() { io::Tokenizer::Token syntax_token = input_->current(); string syntax; DO(ConsumeString(&syntax, "Expected syntax identifier.")); - DO(ConsumeEndOfDeclaration(";", NULL)); + DO(ConsumeEndOfDeclaration(";", &syntax_location)); syntax_identifier_ = syntax; @@ -1271,7 +1294,6 @@ bool Parser::ParseOption(Message* options, DO(ConsumeEndOfDeclaration(";", &location)); } - return true; } @@ -1636,8 +1658,14 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method, // Parse input type. DO(Consume("(")); { - if (TryConsume("stream")) { + if (LookingAt("stream")) { + LocationRecorder location( + method_location, MethodDescriptorProto::kClientStreamingFieldNumber); + location.RecordLegacyLocation( + method, DescriptorPool::ErrorCollector::OTHER); method->set_client_streaming(true); + DO(Consume("stream")); + } LocationRecorder location(method_location, MethodDescriptorProto::kInputTypeFieldNumber); @@ -1651,8 +1679,14 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method, DO(Consume("returns")); DO(Consume("(")); { - if (TryConsume("stream")) { + if (LookingAt("stream")) { + LocationRecorder location( + method_location, MethodDescriptorProto::kServerStreamingFieldNumber); + location.RecordLegacyLocation( + method, DescriptorPool::ErrorCollector::OTHER); + DO(Consume("stream")); method->set_server_streaming(true); + } LocationRecorder location(method_location, MethodDescriptorProto::kOutputTypeFieldNumber); @@ -1664,10 +1698,9 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method, if (LookingAt("{")) { // Options! - DO(ParseOptions(method_location, - containing_file, - MethodDescriptorProto::kOptionsFieldNumber, - method->mutable_options())); + DO(ParseMethodOptions(method_location, containing_file, + MethodDescriptorProto::kOptionsFieldNumber, + method->mutable_options())); } else { DO(ConsumeEndOfDeclaration(";", &method_location)); } @@ -1676,10 +1709,10 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method, } -bool Parser::ParseOptions(const LocationRecorder& parent_location, - const FileDescriptorProto* containing_file, - const int optionsFieldNumber, - Message* mutable_options) { +bool Parser::ParseMethodOptions(const LocationRecorder& parent_location, + const FileDescriptorProto* containing_file, + const int optionsFieldNumber, + Message* mutable_options) { // Options! ConsumeEndOfDeclaration("{", &parent_location); while (!TryConsumeEndOfDeclaration("}", NULL)) { @@ -1693,8 +1726,8 @@ bool Parser::ParseOptions(const LocationRecorder& parent_location, } else { LocationRecorder location(parent_location, optionsFieldNumber); - if (!ParseOption(mutable_options, location, containing_file, - OPTION_STATEMENT)) { + if (!ParseOption(mutable_options, location, + containing_file, OPTION_STATEMENT)) { // This statement failed to parse. Skip it, but keep looping to // parse other statements. SkipStatement(); @@ -1847,7 +1880,7 @@ bool SourceLocationTable::Find( DescriptorPool::ErrorCollector::ErrorLocation location, int* line, int* column) const { const pair<int, int>* result = - FindOrNull(location_map_, make_pair(descriptor, location)); + FindOrNull(location_map_, std::make_pair(descriptor, location)); if (result == NULL) { *line = -1; *column = 0; @@ -1863,7 +1896,8 @@ void SourceLocationTable::Add( const Message* descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, int line, int column) { - location_map_[make_pair(descriptor, location)] = make_pair(line, column); + location_map_[std::make_pair(descriptor, location)] = + std::make_pair(line, column); } void SourceLocationTable::Clear() { diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h index a15cc705..7cb1678a 100644 --- a/src/google/protobuf/compiler/parser.h +++ b/src/google/protobuf/compiler/parser.h @@ -185,10 +185,13 @@ class LIBPROTOBUF_EXPORT Parser { // have been passed around by const reference, for no particularly good // reason. We should probably go through and change them all to mutable // pointer to make this more intuitive. - bool TryConsumeEndOfDeclaration(const char* text, - const LocationRecorder* location); - bool ConsumeEndOfDeclaration(const char* text, - const LocationRecorder* location); + bool TryConsumeEndOfDeclaration( + const char* text, const LocationRecorder* location); + bool TryConsumeEndOfDeclarationFinishScope( + const char* text, const LocationRecorder* location); + + bool ConsumeEndOfDeclaration( + const char* text, const LocationRecorder* location); // ----------------------------------------------------------------- // Error logging helpers @@ -253,9 +256,13 @@ class LIBPROTOBUF_EXPORT Parser { // // TODO(kenton): See comment on TryConsumeEndOfDeclaration(), above, for // why this is const. - void AttachComments(string* leading, string* trailing) const; + void AttachComments(string* leading, string* trailing, + vector<string>* detached_comments) const; private: + // Indexes of parent and current location in the parent + // SourceCodeInfo.location repeated field. For top-level elements, + // parent_index_ is -1. Parser* parser_; SourceCodeInfo::Location* location_; @@ -268,7 +275,7 @@ class LIBPROTOBUF_EXPORT Parser { // Parses the "syntax = \"proto2\";" line at the top of the file. Returns // false if it failed to parse or if the syntax identifier was not // recognized. - bool ParseSyntaxIdentifier(); + bool ParseSyntaxIdentifier(const LocationRecorder& parent); // These methods parse various individual bits of code. They return // false if they completely fail to parse the construct. In this case, @@ -302,9 +309,6 @@ class LIBPROTOBUF_EXPORT Parser { RepeatedField<int32>* weak_dependency, const LocationRecorder& root_location, const FileDescriptorProto* containing_file); - bool ParseOption(Message* options, - const LocationRecorder& options_location, - const FileDescriptorProto* containing_file); // These methods parse the contents of a message, enum, or service type and // add them to the given object. They consume the entire block including @@ -397,10 +401,10 @@ class LIBPROTOBUF_EXPORT Parser { // Parse options of a single method or stream. - bool ParseOptions(const LocationRecorder& parent_location, - const FileDescriptorProto* containing_file, - const int optionsFieldNumber, - Message* mutable_options); + bool ParseMethodOptions(const LocationRecorder& parent_location, + const FileDescriptorProto* containing_file, + const int optionsFieldNumber, + Message* mutable_options); // Parse "required", "optional", or "repeated" and fill in "label" // with the value. Returns true if shuch a label is consumed. @@ -497,6 +501,13 @@ class LIBPROTOBUF_EXPORT Parser { // yet; use ConsumeEndOfDeclaration() to get the complete comments. string upcoming_doc_comments_; + // Detached comments are not connected to any syntax entities. Elements in + // this vector are paragraphs of comments separated by empty lines. The + // detached comments will be put into the leading_detached_comments field for + // the next element (See SourceCodeInfo.Location in descriptor.proto), when + // ConsumeEndOfDeclaration() is called. + vector<string> upcoming_detached_comments_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser); }; diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index fe0719f8..1684bebe 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -1571,7 +1571,7 @@ void SortMessages(DescriptorProto *descriptor_proto) { } DescriptorProto **data = descriptor_proto->mutable_nested_type()->mutable_data(); - sort(data, data + size, CompareDescriptorNames()); + std::sort(data, data + size, CompareDescriptorNames()); } // Sorts DescriptorProtos belonging to a FileDescriptorProto, by name. @@ -1583,7 +1583,7 @@ void SortMessages(FileDescriptorProto *file_descriptor_proto) { } DescriptorProto **data = file_descriptor_proto->mutable_message_type()->mutable_data(); - sort(data, data + size, CompareDescriptorNames()); + std::sort(data, data + size, CompareDescriptorNames()); } // Strips the message and enum field type names for comparison purpose only. @@ -1703,25 +1703,52 @@ TEST_F(ParseDescriptorDebugTest, TestCustomOptions) { // places. TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) { SetupParser( + "// Detached comment before syntax.\n" + "\n" + "// Syntax comment.\n" + "syntax = \"proto2\";\n" + "\n" + "// Detached comment before package.\n" + "\n" + "// Package comment.\n" + "package comment_test;\n" + "\n" + "// Detached comment before TestMessage1.\n" + "\n" "// Message comment.\n" "message TestMessage1 {\n" + "\n" + " // Detached comment before foo.\n" + "\n" " // Field comment.\n" " optional int32 foo = 1;\n" "\n" + " // Detached comment before NestedMessage.\n" + "\n" " // Nested-message comment.\n" " message NestedMessage {\n" " optional int32 bar = 1;\n" " }\n" "}\n" "\n" + "// Detached comment before MyEnumType.\n" + "\n" "// Enum comment.\n" "enum MyEnumType {\n" + "\n" + " // Detached comment before ASDF.\n" + "\n" " // Enum-value comment.\n" " ASDF = 1;\n" "}\n" "\n" + "// Detached comment before MyService.\n" + "\n" "// Service comment.\n" "service MyService {\n" + "\n" + " // Detached comment before MyRPCCall.\n" + "\n" " // RPC comment.\n" " rpc MyRPCCall(TestMessage1) returns (TestMessage1) { }\n" "}\n"); @@ -1745,22 +1772,34 @@ TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) { const string debug_string = descriptor->DebugStringWithOptions(debug_string_options); - // Ensure that each of the comments appears somewhere in the DebugString(), - // and that these comments appear in order. We don't test the exact comment - // placement or formatting, because we do not want to be too fragile here. + // Ensure that each of the comments appears somewhere in the DebugString(). + // We don't test the exact comment placement or formatting, because we do not + // want to be too fragile here. const char* expected_comments[] = { + "Detached comment before syntax.", + "Syntax comment.", + "Detached comment before package.", + "Package comment.", + "Detached comment before TestMessage1.", "Message comment.", + "Detached comment before foo.", "Field comment", + "Detached comment before NestedMessage.", "Nested-message comment", + "Detached comment before MyEnumType.", "Enum comment", + "Detached comment before ASDF.", "Enum-value comment", + "Detached comment before MyService.", "Service comment", + "Detached comment before MyRPCCall.", "RPC comment", }; for (int i = 0; i < GOOGLE_ARRAYSIZE(expected_comments); ++i) { string::size_type found_pos = debug_string.find(expected_comments[i]); - ASSERT_TRUE(found_pos != string::npos); + EXPECT_TRUE(found_pos != string::npos) + << "\"" << expected_comments[i] << "\" not found."; } } @@ -1930,8 +1969,8 @@ class SourceInfoTest : public ParserTest { return false; } - spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index), - &location)); + spans_.insert( + std::make_pair(SpanKey(*descriptor_proto, field, index), &location)); } return true; @@ -1952,16 +1991,18 @@ class SourceInfoTest : public ParserTest { bool HasSpan(char start_marker, char end_marker, const Message& descriptor_proto) { return HasSpanWithComment( - start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL); + start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL, NULL); } bool HasSpanWithComment(char start_marker, char end_marker, const Message& descriptor_proto, const char* expected_leading_comments, - const char* expected_trailing_comments) { + const char* expected_trailing_comments, + const char* expected_leading_detached_comments) { return HasSpanWithComment( start_marker, end_marker, descriptor_proto, NULL, -1, - expected_leading_comments, expected_trailing_comments); + expected_leading_comments, expected_trailing_comments, + expected_leading_detached_comments); } bool HasSpan(char start_marker, char end_marker, @@ -1973,14 +2014,15 @@ class SourceInfoTest : public ParserTest { const Message& descriptor_proto, const string& field_name, int index) { return HasSpan(start_marker, end_marker, descriptor_proto, - field_name, index, NULL, NULL); + field_name, index, NULL, NULL, NULL); } bool HasSpan(char start_marker, char end_marker, const Message& descriptor_proto, const string& field_name, int index, const char* expected_leading_comments, - const char* expected_trailing_comments) { + const char* expected_trailing_comments, + const char* expected_leading_detached_comments) { const FieldDescriptor* field = descriptor_proto.GetDescriptor()->FindFieldByName(field_name); if (field == NULL) { @@ -1991,12 +2033,13 @@ class SourceInfoTest : public ParserTest { return HasSpanWithComment( start_marker, end_marker, descriptor_proto, field, index, - expected_leading_comments, expected_trailing_comments); + expected_leading_comments, expected_trailing_comments, + expected_leading_detached_comments); } bool HasSpan(const Message& descriptor_proto) { return HasSpanWithComment( - '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL); + '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL, NULL); } bool HasSpan(const Message& descriptor_proto, const string& field_name) { @@ -2008,11 +2051,12 @@ class SourceInfoTest : public ParserTest { return HasSpan('\0', '\0', descriptor_proto, field_name, index); } - bool HasSpanWithComment(char start_marker, char end_marker, - const Message& descriptor_proto, - const FieldDescriptor* field, int index, - const char* expected_leading_comments, - const char* expected_trailing_comments) { + bool HasSpanWithComment( + char start_marker, char end_marker, const Message& descriptor_proto, + const FieldDescriptor* field, int index, + const char* expected_leading_comments, + const char* expected_trailing_comments, + const char* expected_leading_detached_comments) { pair<SpanMap::iterator, SpanMap::iterator> range = spans_.equal_range(SpanKey(descriptor_proto, field, index)); @@ -2051,6 +2095,13 @@ class SourceInfoTest : public ParserTest { EXPECT_EQ(expected_trailing_comments, iter->second->trailing_comments()); } + if (expected_leading_detached_comments == NULL) { + EXPECT_EQ(0, iter->second->leading_detached_comments_size()); + } else { + EXPECT_EQ( + expected_leading_detached_comments, + Join(iter->second->leading_detached_comments(), "\n")); + } spans_.erase(iter); return true; @@ -2101,7 +2152,7 @@ class SourceInfoTest : public ParserTest { text_without_markers_ += '$'; ++column; } else { - markers_[*text] = make_pair(line, column); + markers_[*text] = std::make_pair(line, column); ++text; GOOGLE_CHECK_EQ('$', *text); } @@ -2120,7 +2171,7 @@ class SourceInfoTest : public ParserTest { TEST_F(SourceInfoTest, BasicFileDecls) { EXPECT_TRUE(Parse( - "$a$syntax = \"proto2\";\n" + "$a$syntax = \"proto2\";$i$\n" "package $b$foo.bar$c$;\n" "import $d$\"baz.proto\"$e$;\n" "import $f$\"qux.proto\"$g$;$h$\n" @@ -2131,6 +2182,7 @@ TEST_F(SourceInfoTest, BasicFileDecls) { EXPECT_TRUE(HasSpan('b', 'c', file_, "package")); EXPECT_TRUE(HasSpan('d', 'e', file_, "dependency", 0)); EXPECT_TRUE(HasSpan('f', 'g', file_, "dependency", 1)); + EXPECT_TRUE(HasSpan('a', 'i', file_, "syntax")); } TEST_F(SourceInfoTest, Messages) { @@ -2561,6 +2613,9 @@ TEST_F(SourceInfoTest, ScopedOptions) { " rpc M(X) returns(Y) {\n" " $g$option mopt = 1;$h$\n" " }\n" + " rpc MS4($1$stream$2$ X) returns($3$stream$4$ Y) {\n" + " $k$option mopt = 1;$l$\n" + " }\n" "}\n")); EXPECT_TRUE(HasSpan('a', 'b', file_.message_type(0).options())); @@ -2620,6 +2675,26 @@ TEST_F(SourceInfoTest, ScopedOptions) { .uninterpreted_option(0).name(0), "name_part")); EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() .uninterpreted_option(0), "positive_int_value")); + + EXPECT_TRUE(HasSpan('k', 'l', file_.service(0).method(1).options())); + EXPECT_TRUE(HasSpan(file_.service(0).method(1))); + EXPECT_TRUE(HasSpan(file_.service(0).method(1), "name")); + EXPECT_TRUE(HasSpan(file_.service(0).method(1), "input_type")); + EXPECT_TRUE(HasSpan(file_.service(0).method(1), "output_type")); + EXPECT_TRUE(HasSpan(file_.service(0).method(1).options() + .uninterpreted_option(0))); + EXPECT_TRUE(HasSpan(file_.service(0).method(1).options() + .uninterpreted_option(0), "name")); + EXPECT_TRUE(HasSpan(file_.service(0).method(1).options() + .uninterpreted_option(0).name(0))); + EXPECT_TRUE(HasSpan(file_.service(0).method(1).options() + .uninterpreted_option(0).name(0), "name_part")); + EXPECT_TRUE(HasSpan(file_.service(0).method(1).options() + .uninterpreted_option(0), "positive_int_value")); + EXPECT_TRUE(HasSpan('1', '2', file_.service(0).method(1), + "client_streaming")); + EXPECT_TRUE(HasSpan('3', '4', file_.service(0).method(1), + "server_streaming")); } TEST_F(SourceInfoTest, FieldOptions) { @@ -2705,7 +2780,7 @@ TEST_F(SourceInfoTest, DocComments) { " // Foo trailing\n" " // line 2\n" "\n" - " // ignored\n" + " // detached\n" "\n" " // bar leading\n" " $b$optional int32 bar = 1;$c$\n" @@ -2719,10 +2794,12 @@ TEST_F(SourceInfoTest, DocComments) { EXPECT_TRUE(HasSpanWithComment('a', 'd', foo, " Foo leading\n line 2\n", - " Foo trailing\n line 2\n")); + " Foo trailing\n line 2\n", + NULL)); EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, " bar leading\n", - " bar trailing\n")); + " bar trailing\n", + " detached\n")); // Ignore these. EXPECT_TRUE(HasSpan(file_)); @@ -2735,21 +2812,23 @@ TEST_F(SourceInfoTest, DocComments) { TEST_F(SourceInfoTest, DocComments2) { EXPECT_TRUE(Parse( - "// ignored\n" - "syntax = \"proto2\";\n" + "// detached before message.\n" + "\n" "// Foo leading\n" "// line 2\n" "$a$message Foo {\n" " /* Foo trailing\n" " * line 2 */\n" - " // ignored\n" + " // detached\n" " /* bar leading\n" " */" " $b$optional int32 bar = 1;$c$ // bar trailing\n" - " // ignored\n" + " // ignored detached\n" "}$d$\n" "// ignored\n" "\n" + "// detached before option\n" + "\n" "// option leading\n" "$e$option baz = 123;$f$\n" "// option trailing\n" @@ -2761,13 +2840,16 @@ TEST_F(SourceInfoTest, DocComments2) { EXPECT_TRUE(HasSpanWithComment('a', 'd', foo, " Foo leading\n line 2\n", - " Foo trailing\n line 2 ")); + " Foo trailing\n line 2 ", + " detached before message.\n")); EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, " bar leading\n", - " bar trailing\n")); + " bar trailing\n", + " detached\n")); EXPECT_TRUE(HasSpanWithComment('e', 'f', baz, " option leading\n", - " option trailing\n")); + " option trailing\n", + " detached before option\n")); // Ignore these. EXPECT_TRUE(HasSpan(file_)); @@ -2798,7 +2880,8 @@ TEST_F(SourceInfoTest, DocComments3) { EXPECT_TRUE(HasSpanWithComment('b', 'c', bar, " bar leading\n", - " bar trailing\n")); + " bar trailing\n", + NULL)); // Ignore these. EXPECT_TRUE(HasSpan(file_)); @@ -2818,25 +2901,63 @@ TEST_F(SourceInfoTest, DocComments3) { bar.options().uninterpreted_option(0), "aggregate_value")); } +TEST_F(SourceInfoTest, DocCommentsTopLevel) { + EXPECT_TRUE(Parse( + "// detached before syntax paragraph 1\n" + "\n" + "// detached before syntax paragraph 2\n" + "\n" + "// syntax leading\n" + "$a$syntax = \"proto2\";$b$\n" + "// syntax trailing\n" + "\n" + "// syntax-package detached comments\n" + "\n" + ";\n" + "\n" + "// detached after empty before package\n" + "\n" + "// package leading\n" + "package $c$foo$d$;\n" + "// package trailing\n" + "\n" + "// ignored detach\n" + "\n")); + + EXPECT_TRUE(HasSpan('a', 'b', file_, "syntax", -1, + " syntax leading\n", + " syntax trailing\n", + " detached before syntax paragraph 1\n" + "\n" + " detached before syntax paragraph 2\n")); + EXPECT_TRUE(HasSpan('c', 'd', file_, "package", -1, + " package leading\n", + " package trailing\n", + " syntax-package detached comments\n" + "\n" + " detached after empty before package\n")); + + // ignore these. + EXPECT_TRUE(HasSpan(file_)); +} + TEST_F(SourceInfoTest, DocCommentsOneof) { EXPECT_TRUE(Parse( - "// ignored\n" - "syntax = \"proto2\";\n" "// Foo leading\n" "$a$message Foo {\n" " /* Foo trailing\n" " */\n" - " // ignored\n" + " // detached before oneof\n" " /* bar leading\n" " * line 2 */\n" " $b$oneof bar {\n" " /* bar trailing\n" " * line 2 */\n" - " // ignored\n" + " // detached before bar_int\n" " /* bar_int leading\n" " */\n" " $c$int32 bar_int = 1;$d$ // bar_int trailing\n" - " // ignored\n" + " // detach comment ignored\n" " }$e$\n" "}$f$\n")); @@ -2846,13 +2967,16 @@ TEST_F(SourceInfoTest, DocCommentsOneof) { EXPECT_TRUE(HasSpanWithComment('a', 'f', foo, " Foo leading\n", - " Foo trailing\n")); + " Foo trailing\n", + NULL)); EXPECT_TRUE(HasSpanWithComment('b', 'e', bar, " bar leading\n line 2 ", - " bar trailing\n line 2 ")); + " bar trailing\n line 2 ", + " detached before oneof\n")); EXPECT_TRUE(HasSpanWithComment('c', 'd', bar_int, " bar_int leading\n", - " bar_int trailing\n")); + " bar_int trailing\n", + " detached before bar_int\n")); // Ignore these. EXPECT_TRUE(HasSpan(file_)); diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index 9011a6bd..ad501acf 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -95,7 +95,7 @@ class GeneratorResponseContext : public GeneratorContext { int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { if (argc > 1) { - cerr << argv[0] << ": Unknown option: " << argv[1] << endl; + std::cerr << argv[0] << ": Unknown option: " << argv[1] << std::endl; return 1; } @@ -106,7 +106,8 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { CodeGeneratorRequest request; if (!request.ParseFromFileDescriptor(STDIN_FILENO)) { - cerr << argv[0] << ": protoc sent unparseable request to plugin." << endl; + std::cerr << argv[0] << ": protoc sent unparseable request to plugin." + << std::endl; return 1; } @@ -123,9 +124,9 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { for (int i = 0; i < request.file_to_generate_size(); i++) { parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i))); if (parsed_files.back() == NULL) { - cerr << argv[0] << ": protoc asked plugin to generate a file but " - "did not provide a descriptor for the file: " - << request.file_to_generate(i) << endl; + std::cerr << argv[0] << ": protoc asked plugin to generate a file but " + "did not provide a descriptor for the file: " + << request.file_to_generate(i) << std::endl; return 1; } } @@ -151,7 +152,7 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { } if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) { - cerr << argv[0] << ": Error writing to stdout." << endl; + std::cerr << argv[0] << ": Error writing to stdout." << std::endl; return 1; } diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 5118de15..fed1726a 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -140,8 +140,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { "\01324.google.protobuf.compiler.CodeGenerat" "orResponse.File\032>\n\004File\022\014\n\004name\030\001 \001(\t\022\027\n" "\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\tB" - ",\n\034com.google.protobuf.compilerB\014PluginP" - "rotos", 445); + "7\n\034com.google.protobuf.compilerB\014PluginP" + "rotosZ\tplugin_go", 456); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes); CodeGeneratorRequest::default_instance_ = new CodeGeneratorRequest(); @@ -509,6 +509,147 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { return metadata; } +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// CodeGeneratorRequest + +// repeated string file_to_generate = 1; + int CodeGeneratorRequest::file_to_generate_size() const { + return file_to_generate_.size(); +} + void CodeGeneratorRequest::clear_file_to_generate() { + file_to_generate_.Clear(); +} + const ::std::string& CodeGeneratorRequest::file_to_generate(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + return file_to_generate_.Get(index); +} + ::std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + return file_to_generate_.Mutable(index); +} + void CodeGeneratorRequest::set_file_to_generate(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + file_to_generate_.Mutable(index)->assign(value); +} + void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) { + file_to_generate_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) +} + void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) { + file_to_generate_.Mutable(index)->assign( + reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) +} + ::std::string* CodeGeneratorRequest::add_file_to_generate() { + return file_to_generate_.Add(); +} + void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) { + file_to_generate_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) +} + void CodeGeneratorRequest::add_file_to_generate(const char* value) { + file_to_generate_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) +} + void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) { + file_to_generate_.Add()->assign(reinterpret_cast<const char*>(value), size); + // @@protoc_insertion_point(field_add_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) +} + const ::google::protobuf::RepeatedPtrField< ::std::string>& +CodeGeneratorRequest::file_to_generate() const { + // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + return file_to_generate_; +} + ::google::protobuf::RepeatedPtrField< ::std::string>* +CodeGeneratorRequest::mutable_file_to_generate() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) + return &file_to_generate_; +} + +// optional string parameter = 2; + bool CodeGeneratorRequest::has_parameter() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} + void CodeGeneratorRequest::set_has_parameter() { + _has_bits_[0] |= 0x00000002u; +} + void CodeGeneratorRequest::clear_has_parameter() { + _has_bits_[0] &= ~0x00000002u; +} + void CodeGeneratorRequest::clear_parameter() { + parameter_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_parameter(); +} + const ::std::string& CodeGeneratorRequest::parameter() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter) + return parameter_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CodeGeneratorRequest::set_parameter(const ::std::string& value) { + set_has_parameter(); + parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter) +} + void CodeGeneratorRequest::set_parameter(const char* value) { + set_has_parameter(); + parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter) +} + void CodeGeneratorRequest::set_parameter(const char* value, size_t size) { + set_has_parameter(); + parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.parameter) +} + ::std::string* CodeGeneratorRequest::mutable_parameter() { + set_has_parameter(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.parameter) + return parameter_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* CodeGeneratorRequest::release_parameter() { + clear_has_parameter(); + return parameter_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CodeGeneratorRequest::set_allocated_parameter(::std::string* parameter) { + if (parameter != NULL) { + set_has_parameter(); + } else { + clear_has_parameter(); + } + parameter_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), parameter); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter) +} + +// repeated .google.protobuf.FileDescriptorProto proto_file = 15; + int CodeGeneratorRequest::proto_file_size() const { + return proto_file_.size(); +} + void CodeGeneratorRequest::clear_proto_file() { + proto_file_.Clear(); +} + const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return proto_file_.Get(index); +} + ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return proto_file_.Mutable(index); +} + ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() { + // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return proto_file_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& +CodeGeneratorRequest::proto_file() const { + // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return proto_file_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* +CodeGeneratorRequest::mutable_proto_file() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return &proto_file_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS // =================================================================== @@ -1162,6 +1303,256 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { return metadata; } +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// CodeGeneratorResponse_File + +// optional string name = 1; + bool CodeGeneratorResponse_File::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} + void CodeGeneratorResponse_File::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} + void CodeGeneratorResponse_File::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} + void CodeGeneratorResponse_File::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} + const ::std::string& CodeGeneratorResponse_File::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CodeGeneratorResponse_File::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name) +} + void CodeGeneratorResponse_File::set_name(const char* value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name) +} + void CodeGeneratorResponse_File::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.name) +} + ::std::string* CodeGeneratorResponse_File::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* CodeGeneratorResponse_File::release_name() { + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CodeGeneratorResponse_File::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name) +} + +// optional string insertion_point = 2; + bool CodeGeneratorResponse_File::has_insertion_point() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} + void CodeGeneratorResponse_File::set_has_insertion_point() { + _has_bits_[0] |= 0x00000002u; +} + void CodeGeneratorResponse_File::clear_has_insertion_point() { + _has_bits_[0] &= ~0x00000002u; +} + void CodeGeneratorResponse_File::clear_insertion_point() { + insertion_point_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_insertion_point(); +} + const ::std::string& CodeGeneratorResponse_File::insertion_point() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) + return insertion_point_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) { + set_has_insertion_point(); + insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) +} + void CodeGeneratorResponse_File::set_insertion_point(const char* value) { + set_has_insertion_point(); + insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) +} + void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) { + set_has_insertion_point(); + insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) +} + ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() { + set_has_insertion_point(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) + return insertion_point_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* CodeGeneratorResponse_File::release_insertion_point() { + clear_has_insertion_point(); + return insertion_point_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::string* insertion_point) { + if (insertion_point != NULL) { + set_has_insertion_point(); + } else { + clear_has_insertion_point(); + } + insertion_point_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), insertion_point); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) +} + +// optional string content = 15; + bool CodeGeneratorResponse_File::has_content() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} + void CodeGeneratorResponse_File::set_has_content() { + _has_bits_[0] |= 0x00000004u; +} + void CodeGeneratorResponse_File::clear_has_content() { + _has_bits_[0] &= ~0x00000004u; +} + void CodeGeneratorResponse_File::clear_content() { + content_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_content(); +} + const ::std::string& CodeGeneratorResponse_File::content() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content) + return content_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CodeGeneratorResponse_File::set_content(const ::std::string& value) { + set_has_content(); + content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content) +} + void CodeGeneratorResponse_File::set_content(const char* value) { + set_has_content(); + content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content) +} + void CodeGeneratorResponse_File::set_content(const char* value, size_t size) { + set_has_content(); + content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.content) +} + ::std::string* CodeGeneratorResponse_File::mutable_content() { + set_has_content(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.content) + return content_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* CodeGeneratorResponse_File::release_content() { + clear_has_content(); + return content_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CodeGeneratorResponse_File::set_allocated_content(::std::string* content) { + if (content != NULL) { + set_has_content(); + } else { + clear_has_content(); + } + content_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), content); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content) +} + +// ------------------------------------------------------------------- + +// CodeGeneratorResponse + +// optional string error = 1; + bool CodeGeneratorResponse::has_error() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} + void CodeGeneratorResponse::set_has_error() { + _has_bits_[0] |= 0x00000001u; +} + void CodeGeneratorResponse::clear_has_error() { + _has_bits_[0] &= ~0x00000001u; +} + void CodeGeneratorResponse::clear_error() { + error_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_error(); +} + const ::std::string& CodeGeneratorResponse::error() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error) + return error_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CodeGeneratorResponse::set_error(const ::std::string& value) { + set_has_error(); + error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error) +} + void CodeGeneratorResponse::set_error(const char* value) { + set_has_error(); + error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error) +} + void CodeGeneratorResponse::set_error(const char* value, size_t size) { + set_has_error(); + error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.error) +} + ::std::string* CodeGeneratorResponse::mutable_error() { + set_has_error(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.error) + return error_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* CodeGeneratorResponse::release_error() { + clear_has_error(); + return error_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CodeGeneratorResponse::set_allocated_error(::std::string* error) { + if (error != NULL) { + set_has_error(); + } else { + clear_has_error(); + } + error_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error) +} + +// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; + int CodeGeneratorResponse::file_size() const { + return file_.size(); +} + void CodeGeneratorResponse::clear_file() { + file_.Clear(); +} + const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.file) + return file_.Get(index); +} + ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file) + return file_.Mutable(index); +} + ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() { + // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file) + return file_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& +CodeGeneratorResponse::file() const { + // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file) + return file_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* +CodeGeneratorResponse::mutable_file() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file) + return &file_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS // @@protoc_insertion_point(namespace_scope) diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index ad017005..ea48b8b5 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -110,43 +110,43 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message // accessors ------------------------------------------------------- // repeated string file_to_generate = 1; - inline int file_to_generate_size() const; - inline void clear_file_to_generate(); + int file_to_generate_size() const; + void clear_file_to_generate(); static const int kFileToGenerateFieldNumber = 1; - inline const ::std::string& file_to_generate(int index) const; - inline ::std::string* mutable_file_to_generate(int index); - inline void set_file_to_generate(int index, const ::std::string& value); - inline void set_file_to_generate(int index, const char* value); - inline void set_file_to_generate(int index, const char* value, size_t size); - inline ::std::string* add_file_to_generate(); - inline void add_file_to_generate(const ::std::string& value); - inline void add_file_to_generate(const char* value); - inline void add_file_to_generate(const char* value, size_t size); - inline const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const; - inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate(); + const ::std::string& file_to_generate(int index) const; + ::std::string* mutable_file_to_generate(int index); + void set_file_to_generate(int index, const ::std::string& value); + void set_file_to_generate(int index, const char* value); + void set_file_to_generate(int index, const char* value, size_t size); + ::std::string* add_file_to_generate(); + void add_file_to_generate(const ::std::string& value); + void add_file_to_generate(const char* value); + void add_file_to_generate(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate(); // optional string parameter = 2; - inline bool has_parameter() const; - inline void clear_parameter(); + bool has_parameter() const; + void clear_parameter(); static const int kParameterFieldNumber = 2; - inline const ::std::string& parameter() const; - inline void set_parameter(const ::std::string& value); - inline void set_parameter(const char* value); - inline void set_parameter(const char* value, size_t size); - inline ::std::string* mutable_parameter(); - inline ::std::string* release_parameter(); - inline void set_allocated_parameter(::std::string* parameter); + const ::std::string& parameter() const; + void set_parameter(const ::std::string& value); + void set_parameter(const char* value); + void set_parameter(const char* value, size_t size); + ::std::string* mutable_parameter(); + ::std::string* release_parameter(); + void set_allocated_parameter(::std::string* parameter); // repeated .google.protobuf.FileDescriptorProto proto_file = 15; - inline int proto_file_size() const; - inline void clear_proto_file(); + int proto_file_size() const; + void clear_proto_file(); static const int kProtoFileFieldNumber = 15; - inline const ::google::protobuf::FileDescriptorProto& proto_file(int index) const; - inline ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index); - inline ::google::protobuf::FileDescriptorProto* add_proto_file(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& + const ::google::protobuf::FileDescriptorProto& proto_file(int index) const; + ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index); + ::google::protobuf::FileDescriptorProto* add_proto_file(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& proto_file() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* mutable_proto_file(); // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) @@ -234,40 +234,40 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M // accessors ------------------------------------------------------- // optional string name = 1; - inline bool has_name() const; - inline void clear_name(); + bool has_name() const; + void clear_name(); static const int kNameFieldNumber = 1; - inline const ::std::string& name() const; - inline void set_name(const ::std::string& value); - inline void set_name(const char* value); - inline void set_name(const char* value, size_t size); - inline ::std::string* mutable_name(); - inline ::std::string* release_name(); - inline void set_allocated_name(::std::string* name); + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); // optional string insertion_point = 2; - inline bool has_insertion_point() const; - inline void clear_insertion_point(); + bool has_insertion_point() const; + void clear_insertion_point(); static const int kInsertionPointFieldNumber = 2; - inline const ::std::string& insertion_point() const; - inline void set_insertion_point(const ::std::string& value); - inline void set_insertion_point(const char* value); - inline void set_insertion_point(const char* value, size_t size); - inline ::std::string* mutable_insertion_point(); - inline ::std::string* release_insertion_point(); - inline void set_allocated_insertion_point(::std::string* insertion_point); + const ::std::string& insertion_point() const; + void set_insertion_point(const ::std::string& value); + void set_insertion_point(const char* value); + void set_insertion_point(const char* value, size_t size); + ::std::string* mutable_insertion_point(); + ::std::string* release_insertion_point(); + void set_allocated_insertion_point(::std::string* insertion_point); // optional string content = 15; - inline bool has_content() const; - inline void clear_content(); + bool has_content() const; + void clear_content(); static const int kContentFieldNumber = 15; - inline const ::std::string& content() const; - inline void set_content(const ::std::string& value); - inline void set_content(const char* value); - inline void set_content(const char* value, size_t size); - inline ::std::string* mutable_content(); - inline ::std::string* release_content(); - inline void set_allocated_content(::std::string* content); + const ::std::string& content() const; + void set_content(const ::std::string& value); + void set_content(const char* value); + void set_content(const char* value, size_t size); + ::std::string* mutable_content(); + ::std::string* release_content(); + void set_allocated_content(::std::string* content); // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) private: @@ -360,27 +360,27 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag // accessors ------------------------------------------------------- // optional string error = 1; - inline bool has_error() const; - inline void clear_error(); + bool has_error() const; + void clear_error(); static const int kErrorFieldNumber = 1; - inline const ::std::string& error() const; - inline void set_error(const ::std::string& value); - inline void set_error(const char* value); - inline void set_error(const char* value, size_t size); - inline ::std::string* mutable_error(); - inline ::std::string* release_error(); - inline void set_allocated_error(::std::string* error); + const ::std::string& error() const; + void set_error(const ::std::string& value); + void set_error(const char* value); + void set_error(const char* value, size_t size); + ::std::string* mutable_error(); + ::std::string* release_error(); + void set_allocated_error(::std::string* error); // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; - inline int file_size() const; - inline void clear_file(); + int file_size() const; + void clear_file(); static const int kFileFieldNumber = 15; - inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const; - inline ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index); - inline ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file(); - inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& + const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const; + ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index); + ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& file() const; - inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* + ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* mutable_file(); // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) @@ -405,6 +405,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag // =================================================================== +#if !PROTOBUF_INLINE_NOT_IN_HEADERS // CodeGeneratorRequest // repeated string file_to_generate = 1; @@ -794,6 +795,7 @@ CodeGeneratorResponse::mutable_file() { return &file_; } +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS // @@protoc_insertion_point(namespace_scope) @@ -801,15 +803,6 @@ CodeGeneratorResponse::mutable_file() { } // namespace protobuf } // namespace google -#ifndef SWIG -namespace google { -namespace protobuf { - - -} // namespace protobuf -} // namespace google -#endif // SWIG - // @@protoc_insertion_point(global_scope) #endif // PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto index e627289b..acaee1f4 100644 --- a/src/google/protobuf/compiler/plugin.proto +++ b/src/google/protobuf/compiler/plugin.proto @@ -49,6 +49,8 @@ package google.protobuf.compiler; option java_package = "com.google.protobuf.compiler"; option java_outer_classname = "PluginProtos"; +option go_package = "plugin_go"; + import "google/protobuf/descriptor.proto"; // An encoded CodeGeneratorRequest is written to the plugin's stdin. |