diff options
Diffstat (limited to 'src/google/protobuf/compiler')
144 files changed, 8572 insertions, 7861 deletions
diff --git a/src/google/protobuf/compiler/annotation_test_util.cc b/src/google/protobuf/compiler/annotation_test_util.cc new file mode 100644 index 00000000..cc8534cc --- /dev/null +++ b/src/google/protobuf/compiler/annotation_test_util.cc @@ -0,0 +1,169 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/compiler/annotation_test_util.h> + +#include <memory> +#ifndef _SHARED_PTR_H +#include <google/protobuf/stubs/shared_ptr.h> +#endif +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/command_line_interface.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/descriptor.pb.h> + +#include <google/protobuf/testing/file.h> +#include <google/protobuf/testing/file.h> +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace annotation_test_util { +namespace { + +// A CodeGenerator that captures the FileDescriptor it's passed as a +// FileDescriptorProto. +class DescriptorCapturingGenerator : public CodeGenerator { + public: + // Does not own file; file must outlive the Generator. + explicit DescriptorCapturingGenerator(FileDescriptorProto* file) + : file_(file) {} + + virtual bool Generate(const FileDescriptor* file, const string& parameter, + GeneratorContext* context, string* error) const { + file->CopyTo(file_); + return true; + } + + private: + FileDescriptorProto* file_; +}; +} // namespace + +void AddFile(const string& filename, const string& data) { + GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/" + filename, data, + true)); +} + +bool RunProtoCompiler(const string& filename, + const string& plugin_specific_args, + CommandLineInterface* cli, FileDescriptorProto* file) { + cli->SetInputsAreProtoPathRelative(true); + + DescriptorCapturingGenerator capturing_generator(file); + cli->RegisterGenerator("--capture_out", &capturing_generator, ""); + + string proto_path = "-I" + TestTempDir(); + string capture_out = "--capture_out=" + TestTempDir(); + + const char* argv[] = {"protoc", proto_path.c_str(), + plugin_specific_args.c_str(), capture_out.c_str(), + filename.c_str()}; + + return cli->Run(5, argv) == 0; +} + +bool DecodeMetadata(const string& path, GeneratedCodeInfo* info) { + string data; + GOOGLE_CHECK_OK(File::GetContents(path, &data, true)); + io::ArrayInputStream input(data.data(), data.size()); + return info->ParseFromZeroCopyStream(&input); +} + +void FindAnnotationsOnPath( + const GeneratedCodeInfo& info, const string& source_file, + const std::vector<int>& path, + std::vector<const GeneratedCodeInfo::Annotation*>* annotations) { + for (int i = 0; i < info.annotation_size(); ++i) { + const GeneratedCodeInfo::Annotation* annotation = &info.annotation(i); + if (annotation->source_file() != source_file || + annotation->path_size() != path.size()) { + continue; + } + int node = 0; + for (; node < path.size(); ++node) { + if (annotation->path(node) != path[node]) { + break; + } + } + if (node == path.size()) { + annotations->push_back(annotation); + } + } +} + +const GeneratedCodeInfo::Annotation* FindAnnotationOnPath( + const GeneratedCodeInfo& info, const string& source_file, + const std::vector<int>& path) { + std::vector<const GeneratedCodeInfo::Annotation*> annotations; + FindAnnotationsOnPath(info, source_file, path, &annotations); + if (annotations.empty()) { + return NULL; + } + return annotations[0]; +} + +bool AtLeastOneAnnotationMatchesSubstring( + const string& file_content, + const std::vector<const GeneratedCodeInfo::Annotation*>& annotations, + const string& expected_text) { + for (std::vector<const GeneratedCodeInfo::Annotation*>::const_iterator + i = annotations.begin(), + e = annotations.end(); + i != e; ++i) { + const GeneratedCodeInfo::Annotation* annotation = *i; + uint32 begin = annotation->begin(); + uint32 end = annotation->end(); + if (end < begin || end > file_content.size()) { + return false; + } + if (file_content.substr(begin, end - begin) == expected_text) { + return true; + } + } + return false; +} + +bool AnnotationMatchesSubstring(const string& file_content, + const GeneratedCodeInfo::Annotation* annotation, + const string& expected_text) { + std::vector<const GeneratedCodeInfo::Annotation*> annotations; + annotations.push_back(annotation); + return AtLeastOneAnnotationMatchesSubstring(file_content, annotations, + expected_text); +} +} // namespace annotation_test_util +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/annotation_test_util.h b/src/google/protobuf/compiler/annotation_test_util.h new file mode 100644 index 00000000..90bd88b3 --- /dev/null +++ b/src/google/protobuf/compiler/annotation_test_util.h @@ -0,0 +1,114 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__ +#define GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__ + +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> + +// Utilities that assist in writing tests for generator annotations. +// See java/internal/annotation_unittest.cc for an example. +namespace google { +namespace protobuf { +namespace compiler { +namespace annotation_test_util { + +// Struct that contains the file generated from a .proto file and its +// GeneratedCodeInfo. For example, the Java generator will fill this struct +// (for some 'foo.proto') with: +// file_path = "Foo.java" +// file_content = content of Foo.java +// file_info = parsed content of Foo.java.pb.meta +struct ExpectedOutput { + string file_path; + string file_content; + GeneratedCodeInfo file_info; + explicit ExpectedOutput(const string& file_path) : file_path(file_path) {} +}; + +// Creates a file with name `filename` and content `data` in temp test +// directory. +void AddFile(const string& filename, const string& data); + +// Runs proto compiler. Captures proto file structrue in FileDescriptorProto. +// Files will be generated in TestTempDir() folder. Callers of this +// function must read generated files themselves. +// +// filename: source .proto file used to generate code. +// plugin_specific_args: command line arguments specific to current generator. +// For Java, this value might be "--java_out=annotate_code:test_temp_dir" +// cli: instance of command line interface to run generator. See Java's +// annotation_unittest.cc for an example of how to initialize it. +// file: output parameter, will be set to the descriptor of the proto file +// specified in filename. +bool RunProtoCompiler(const string& filename, + const string& plugin_specific_args, + CommandLineInterface* cli, FileDescriptorProto* file); + +bool DecodeMetadata(const string& path, GeneratedCodeInfo* info); + +// Finds all of the Annotations for a given source file and path. +// See Location.path in http://google/protobuf/descriptor.proto for +// explanation of what path vector is. +void FindAnnotationsOnPath( + const GeneratedCodeInfo& info, const string& source_file, + const std::vector<int>& path, + std::vector<const GeneratedCodeInfo::Annotation*>* annotations); + +// Finds the Annotation for a given source file and path (or returns null if it +// couldn't). If there are several annotations for given path, returns the first +// one. See Location.path in +// http://google/protobuf/descriptor.proto for explanation of what path +// vector is. +const GeneratedCodeInfo::Annotation* FindAnnotationOnPath( + const GeneratedCodeInfo& info, const string& source_file, + const std::vector<int>& path); + +// Returns true if at least one of the provided annotations covers a given +// substring in file_content. +bool AtLeastOneAnnotationMatchesSubstring( + const string& file_content, + const std::vector<const GeneratedCodeInfo::Annotation*>& annotations, + const string& expected_text); + +// Returns true if the provided annotation covers a given substring in +// file_content. +bool AnnotationMatchesSubstring(const string& file_content, + const GeneratedCodeInfo::Annotation* annotation, + const string& expected_text); + +} // namespace annotation_test_util +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__ diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index b917d373..4c2b3ee1 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -50,6 +50,8 @@ namespace io { class ZeroCopyOutputStream; } class FileDescriptor; namespace compiler { +class AccessInfoMap; + class Version; // Defined in this file. @@ -112,7 +114,8 @@ class LIBPROTOC_EXPORT CodeGenerator { // runs. class LIBPROTOC_EXPORT GeneratorContext { public: - inline GeneratorContext() {} + inline GeneratorContext() { + } virtual ~GeneratorContext(); // Opens the given file, truncating it if it exists, and returns a @@ -148,6 +151,7 @@ class LIBPROTOC_EXPORT GeneratorContext { // this GeneratorContext. virtual void GetCompilerVersion(Version* version) const; + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext); }; @@ -162,8 +166,8 @@ typedef GeneratorContext OutputDirectory; // "foo=bar,baz,qux=corge" // parses to the pairs: // ("foo", "bar"), ("baz", ""), ("qux", "corge") -extern void ParseGeneratorParameter(const string&, - std::vector<std::pair<string, string> >*); +LIBPROTOC_EXPORT void ParseGeneratorParameter( + const string&, std::vector<std::pair<string, string> >*); } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index df03907d..7c45fe75 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -33,6 +33,8 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include <google/protobuf/compiler/command_line_interface.h> + + #include <google/protobuf/stubs/platform_macros.h> #include <stdio.h> @@ -45,10 +47,7 @@ #endif #include <sys/stat.h> #include <fcntl.h> -#ifdef _MSC_VER -#include <io.h> -#include <direct.h> -#else +#ifndef _MSC_VER #include <unistd.h> #endif #include <errno.h> @@ -68,45 +67,30 @@ #endif #include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/stringprintf.h> -#include <google/protobuf/compiler/importer.h> -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/compiler/plugin.pb.h> #include <google/protobuf/compiler/subprocess.h> #include <google/protobuf/compiler/zip_writer.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/text_format.h> -#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/compiler/plugin.pb.h> +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/importer.h> #include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/logging.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/text_format.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> #include <google/protobuf/stubs/map_util.h> #include <google/protobuf/stubs/stl_util.h> +#include <google/protobuf/stubs/io_win32.h> namespace google { namespace protobuf { namespace compiler { -#if defined(_WIN32) -#define mkdir(name, mode) mkdir(name) -#ifndef W_OK -#define W_OK 02 // not defined by MSVC for whatever reason -#endif -#ifndef F_OK -#define F_OK 00 // not defined by MSVC for whatever reason -#endif -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif -#endif - #ifndef O_BINARY #ifdef _O_BINARY #define O_BINARY _O_BINARY @@ -116,10 +100,15 @@ namespace compiler { #endif namespace { -#if defined(_WIN32) && !defined(__CYGWIN__) -static const char* kPathSeparator = ";"; -#else -static const char* kPathSeparator = ":"; +#if defined(_WIN32) +// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import +// them like we do below. +using google::protobuf::internal::win32::access; +using google::protobuf::internal::win32::close; +using google::protobuf::internal::win32::mkdir; +using google::protobuf::internal::win32::open; +using google::protobuf::internal::win32::setmode; +using google::protobuf::internal::win32::write; #endif static const char* kDefaultDirectDependenciesViolationMsg = @@ -141,9 +130,9 @@ static bool IsWindowsAbsolutePath(const string& text) { void SetFdToTextMode(int fd) { #ifdef _WIN32 - if (_setmode(fd, _O_TEXT) == -1) { + if (setmode(fd, _O_TEXT) == -1) { // This should never happen, I think. - GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_TEXT): " << strerror(errno); + GOOGLE_LOG(WARNING) << "setmode(" << fd << ", _O_TEXT): " << strerror(errno); } #endif // (Text and binary are the same on non-Windows platforms.) @@ -151,9 +140,9 @@ void SetFdToTextMode(int fd) { void SetFdToBinaryMode(int fd) { #ifdef _WIN32 - if (_setmode(fd, _O_BINARY) == -1) { + if (setmode(fd, _O_BINARY) == -1) { // This should never happen, I think. - GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_BINARY): " << strerror(errno); + GOOGLE_LOG(WARNING) << "setmode(" << fd << ", _O_BINARY): " << strerror(errno); } #endif // (Text and binary are the same on non-Windows platforms.) @@ -235,9 +224,9 @@ bool IsInstalledProtoPath(const string& path) { return access(file_path.c_str(), F_OK) != -1; } -// Add the paths where google/protobuf/descritor.proto and other well-known +// Add the paths where google/protobuf/descriptor.proto and other well-known // type protos are installed. -void AddDefaultProtoPaths(vector<pair<string, string> >* paths) { +void AddDefaultProtoPaths(std::vector<std::pair<string, string> >* paths) { // TODO(xiaofeng): The code currently only checks relative paths of where // the protoc binary is installed. We probably should make it handle more // cases than that. @@ -253,12 +242,12 @@ void AddDefaultProtoPaths(vector<pair<string, string> >* paths) { path = path.substr(0, pos); // Check the binary's directory. if (IsInstalledProtoPath(path)) { - paths->push_back(pair<string, string>("", path)); + paths->push_back(std::pair<string, string>("", path)); return; } // Check if there is an include subdirectory. if (IsInstalledProtoPath(path + "/include")) { - paths->push_back(pair<string, string>("", path + "/include")); + paths->push_back(std::pair<string, string>("", path + "/include")); return; } // Check if the upper level directory has an "include" subdirectory. @@ -268,7 +257,7 @@ void AddDefaultProtoPaths(vector<pair<string, string> >* paths) { } path = path.substr(0, pos); if (IsInstalledProtoPath(path + "/include")) { - paths->push_back(pair<string, string>("", path + "/include")); + paths->push_back(std::pair<string, string>("", path + "/include")); return; } } @@ -278,11 +267,14 @@ string PluginName(const string& plugin_prefix, const string& directive) { // strip the "--" and "_out/_opt" and add the plugin prefix. return plugin_prefix + "gen-" + directive.substr(2, directive.size() - 6); } + } // namespace // A MultiFileErrorCollector that prints errors to stderr. -class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, - public io::ErrorCollector { +class CommandLineInterface::ErrorPrinter + : public MultiFileErrorCollector, + public io::ErrorCollector, + public DescriptorPool::ErrorCollector { public: ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL) : format_(format), tree_(tree), found_errors_(false) {} @@ -309,6 +301,25 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, AddErrorOrWarning("input", line, column, message, "warning", std::clog); } + // implements DescriptorPool::ErrorCollector------------------------- + void AddError( + const string& filename, + const string& element_name, + const Message* descriptor, + ErrorLocation location, + const string& message) { + AddErrorOrWarning(filename, -1, -1, message, "error", std::cerr); + } + + void AddWarning( + const string& filename, + const string& element_name, + const Message* descriptor, + ErrorLocation location, + const string& message) { + AddErrorOrWarning(filename, -1, -1, message, "warning", std::clog); + } + bool FoundErrors() const { return found_errors_; } private: @@ -410,6 +421,13 @@ class CommandLineInterface::MemoryOutputStream virtual int64 ByteCount() const { return inner_->ByteCount(); } private: + // Checks to see if "filename_.meta" exists in directory_; if so, fixes the + // offsets in that GeneratedCodeInfo record to reflect bytes inserted in + // filename_ at original offset insertion_offset with length insertion_length. + // We assume that insertions will not occur within any given annotated span + // of text. + void UpdateMetadata(size_t insertion_offset, size_t insertion_length); + // Where to insert the string when it's done. GeneratorContextImpl* directory_; string filename_; @@ -430,8 +448,7 @@ class CommandLineInterface::MemoryOutputStream CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl( const std::vector<const FileDescriptor*>& parsed_files) : parsed_files_(parsed_files), - had_error_(false) { -} + had_error_(false) {} CommandLineInterface::GeneratorContextImpl::~GeneratorContextImpl() { STLDeleteValues(&files_); @@ -607,6 +624,44 @@ CommandLineInterface::MemoryOutputStream::MemoryOutputStream( inner_(new io::StringOutputStream(&data_)) { } +void CommandLineInterface::MemoryOutputStream::UpdateMetadata( + size_t insertion_offset, size_t insertion_length) { + std::map<string, string*>::iterator meta_file = + directory_->files_.find(filename_ + ".meta"); + if (meta_file == directory_->files_.end() || !meta_file->second) { + // No metadata was recorded for this file. + return; + } + string* encoded_data = meta_file->second; + GeneratedCodeInfo metadata; + bool is_text_format = false; + if (!metadata.ParseFromString(*encoded_data)) { + if (!TextFormat::ParseFromString(*encoded_data, &metadata)) { + // The metadata is invalid. + std::cerr << filename_ + << ".meta: Could not parse metadata as wire or text format." + << std::endl; + return; + } + // Generators that use the public plugin interface emit text-format + // metadata (because in the public plugin protocol, file content must be + // UTF8-encoded strings). + is_text_format = true; + } + for (int i = 0; i < metadata.annotation_size(); ++i) { + GeneratedCodeInfo::Annotation* annotation = metadata.mutable_annotation(i); + if (annotation->begin() >= insertion_offset) { + annotation->set_begin(annotation->begin() + insertion_length); + annotation->set_end(annotation->end() + insertion_length); + } + } + if (is_text_format) { + TextFormat::PrintToString(metadata, encoded_data); + } else { + metadata.SerializeToString(encoded_data); + } +} + CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { // Make sure all data has been written. inner_.reset(); @@ -684,6 +739,7 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { if (indent_.empty()) { // No indent. This makes things easier. target->insert(pos, data_); + UpdateMetadata(pos, data_.size()); } else { // Calculate how much space we need. int indent_size = 0; @@ -693,6 +749,7 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { // Make a hole for it. target->insert(pos, data_.size() + indent_size, '\0'); + UpdateMetadata(pos, data_.size() + indent_size); // Now copy in the data. string::size_type data_pos = 0; @@ -720,6 +777,12 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { // =================================================================== +#if defined(_WIN32) && !defined(__CYGWIN__) +const char* const CommandLineInterface::kPathSeparator = ";"; +#else +const char* const CommandLineInterface::kPathSeparator = ":"; +#endif + CommandLineInterface::CommandLineInterface() : mode_(MODE_COMPILE), print_mode_(PRINT_NONE), @@ -729,9 +792,7 @@ CommandLineInterface::CommandLineInterface() kDefaultDirectDependenciesViolationMsg), imports_in_descriptor_set_(false), source_info_in_descriptor_set_(false), - disallow_services_(false), - inputs_are_proto_path_relative_(false) { -} + disallow_services_(false) {} CommandLineInterface::~CommandLineInterface() {} void CommandLineInterface::RegisterGenerator(const string& flag_name, @@ -772,63 +833,42 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { break; } - AddDefaultProtoPaths(&proto_path_); - - // Set up the source tree. - DiskSourceTree source_tree; - for (int i = 0; i < proto_path_.size(); i++) { - source_tree.MapPath(proto_path_[i].first, proto_path_[i].second); - } - - // Map input files to virtual paths if necessary. - if (!inputs_are_proto_path_relative_) { - if (!MakeInputsBeProtoPathRelative(&source_tree)) { + std::vector<const FileDescriptor*> parsed_files; + // null unless descriptor_set_in_names_.empty() + google::protobuf::scoped_ptr<DiskSourceTree> disk_source_tree; + google::protobuf::scoped_ptr<ErrorPrinter> error_collector; + google::protobuf::scoped_ptr<DescriptorPool> descriptor_pool; + google::protobuf::scoped_ptr<DescriptorDatabase> descriptor_database; + if (descriptor_set_in_names_.empty()) { + disk_source_tree.reset(new DiskSourceTree()); + if (!InitializeDiskSourceTree(disk_source_tree.get())) { return 1; } - } - - // Allocate the Importer. - ErrorPrinter error_collector(error_format_, &source_tree); - Importer importer(&source_tree, &error_collector); - - std::vector<const FileDescriptor*> parsed_files; + error_collector.reset( + new ErrorPrinter(error_format_, disk_source_tree.get())); - // Parse each file. - for (int i = 0; i < input_files_.size(); i++) { - // Import the file. - importer.AddUnusedImportTrackFile(input_files_[i]); - const FileDescriptor* parsed_file = importer.Import(input_files_[i]); - importer.ClearUnusedImportTrackFiles(); - if (parsed_file == NULL) return 1; - parsed_files.push_back(parsed_file); + SourceTreeDescriptorDatabase* database = + new SourceTreeDescriptorDatabase(disk_source_tree.get()); + database->RecordErrorsTo(error_collector.get()); + descriptor_database.reset(database); + descriptor_pool.reset(new DescriptorPool( + descriptor_database.get(), database->GetValidationErrorCollector())); + } else { + error_collector.reset(new ErrorPrinter(error_format_)); - // Enforce --disallow_services. - if (disallow_services_ && parsed_file->service_count() > 0) { - std::cerr << parsed_file->name() << ": This file contains services, but " - "--disallow_services was used." << std::endl; + SimpleDescriptorDatabase* database = new SimpleDescriptorDatabase(); + descriptor_database.reset(database); + if (!PopulateSimpleDescriptorDatabase(database)) { return 1; } - - // Enforce --direct_dependencies - if (direct_dependencies_explicitly_set_) { - bool indirect_imports = false; - for (int i = 0; i < parsed_file->dependency_count(); i++) { - if (direct_dependencies_.find(parsed_file->dependency(i)->name()) == - direct_dependencies_.end()) { - indirect_imports = true; - std::cerr << parsed_file->name() << ": " - << StringReplace(direct_dependencies_violation_msg_, "%s", - parsed_file->dependency(i)->name(), - true /* replace_all */) - << std::endl; - } - } - if (indirect_imports) { - return 1; - } - } + descriptor_pool.reset(new DescriptorPool(database, error_collector.get())); + } + descriptor_pool->EnforceWeakDependencies(true); + if (!ParseInputFiles(descriptor_pool.get(), &parsed_files)) { + return 1; } + // We construct a separate GeneratorContext for each output location. Note // that two code generators may output to the same location, in which case // they should share a single GeneratorContext so that OpenForInsert() works. @@ -879,15 +919,16 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { } if (!dependency_out_name_.empty()) { + GOOGLE_DCHECK(disk_source_tree.get()); if (!GenerateDependencyManifestFile(parsed_files, output_directories, - &source_tree)) { + disk_source_tree.get())) { return 1; } } STLDeleteValues(&output_directories); - if (!descriptor_set_name_.empty()) { + if (!descriptor_set_out_name_.empty()) { if (!WriteDescriptorSet(parsed_files)) { return 1; } @@ -906,13 +947,13 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { return 1; } } else { - if (!EncodeOrDecode(importer.pool())) { + if (!EncodeOrDecode(descriptor_pool.get())) { return 1; } } } - if (error_collector.FoundErrors()) { + if (error_collector->FoundErrors()) { return 1; } @@ -928,7 +969,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { break; case PRINT_NONE: GOOGLE_LOG(ERROR) << "If the code reaches here, it usually means a bug of " - "flag parsing in the CommonadLineInterface."; + "flag parsing in the CommandLineInterface."; return 1; // Do not add a default case. @@ -938,6 +979,113 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { return 0; } +bool CommandLineInterface::InitializeDiskSourceTree( + DiskSourceTree* source_tree) { + AddDefaultProtoPaths(&proto_path_); + + // Set up the source tree. + for (int i = 0; i < proto_path_.size(); i++) { + source_tree->MapPath(proto_path_[i].first, proto_path_[i].second); + } + + // Map input files to virtual paths if possible. + if (!MakeInputsBeProtoPathRelative(source_tree)) { + return false; + } + return true; +} + +bool CommandLineInterface::PopulateSimpleDescriptorDatabase( + SimpleDescriptorDatabase* database) { + for (int i = 0; i < descriptor_set_in_names_.size(); i++) { + int fd; + do { + fd = open(descriptor_set_in_names_[i].c_str(), O_RDONLY | O_BINARY); + } while (fd < 0 && errno == EINTR); + if (fd < 0) { + std::cerr << descriptor_set_in_names_[i] << ": " + << strerror(ENOENT) << std::endl; + return false; + } + + FileDescriptorSet file_descriptor_set; + bool parsed = file_descriptor_set.ParseFromFileDescriptor(fd); + if (close(fd) != 0) { + std::cerr << descriptor_set_in_names_[i] << ": close: " + << strerror(errno) + << std::endl; + return false; + } + + if (!parsed) { + std::cerr << descriptor_set_in_names_[i] << ": Unable to parse." + << std::endl; + return false; + } + + for (int j = 0; j < file_descriptor_set.file_size(); j++) { + FileDescriptorProto previously_added_file_descriptor_proto; + if (database->FindFileByName(file_descriptor_set.file(j).name(), + &previously_added_file_descriptor_proto)) { + // already present - skip + continue; + } + if (!database->Add(file_descriptor_set.file(j))) { + return false; + } + } + } + return true; +} + +bool CommandLineInterface::ParseInputFiles( + DescriptorPool* descriptor_pool, + std::vector<const FileDescriptor*>* parsed_files) { + + // Parse each file. + for (int i = 0; i < input_files_.size(); i++) { + // Import the file. + descriptor_pool->AddUnusedImportTrackFile(input_files_[i]); + const FileDescriptor* parsed_file = + descriptor_pool->FindFileByName(input_files_[i]); + descriptor_pool->ClearUnusedImportTrackFiles(); + if (parsed_file == NULL) { + if (!descriptor_set_in_names_.empty()) { + std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl; + } + return false; + } + parsed_files->push_back(parsed_file); + + // Enforce --disallow_services. + if (disallow_services_ && parsed_file->service_count() > 0) { + std::cerr << parsed_file->name() << ": This file contains services, but " + "--disallow_services was used." << std::endl; + return false; + } + + // Enforce --direct_dependencies + if (direct_dependencies_explicitly_set_) { + bool indirect_imports = false; + for (int i = 0; i < parsed_file->dependency_count(); i++) { + if (direct_dependencies_.find(parsed_file->dependency(i)->name()) == + direct_dependencies_.end()) { + indirect_imports = true; + std::cerr << parsed_file->name() << ": " + << StringReplace(direct_dependencies_violation_msg_, "%s", + parsed_file->dependency(i)->name(), + true /* replace_all */) + << std::endl; + } + } + if (indirect_imports) { + return false; + } + } + } + return true; +} + void CommandLineInterface::Clear() { // Clear all members that are set by Run(). Note that we must not clear // members which are set by other methods before Run() is called. @@ -948,7 +1096,8 @@ void CommandLineInterface::Clear() { direct_dependencies_violation_msg_ = kDefaultDirectDependenciesViolationMsg; output_directives_.clear(); codec_type_.clear(); - descriptor_set_name_.clear(); + descriptor_set_in_names_.clear(); + descriptor_set_out_name_.clear(); dependency_out_name_.clear(); mode_ = MODE_COMPILE; @@ -962,6 +1111,17 @@ void CommandLineInterface::Clear() { bool CommandLineInterface::MakeInputsBeProtoPathRelative( DiskSourceTree* source_tree) { for (int i = 0; i < input_files_.size(); i++) { + // If the input file path is not a physical file path, it must be a virtual + // path. + if (access(input_files_[i].c_str(), F_OK) < 0) { + string disk_file; + if (source_tree->VirtualFileToDiskFile(input_files_[i], &disk_file)) { + return true; + } else { + std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl; + return false; + } + } string virtual_file, shadowing_disk_file; switch (source_tree->DiskFileToVirtualFile( input_files_[i], &virtual_file, &shadowing_disk_file)) { @@ -979,12 +1139,14 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative( case DiskSourceTree::CANNOT_OPEN: 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. - std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl; + case DiskSourceTree::NO_MAPPING: { + // Try to interpret the path as a virtual path. + string disk_file; + if (source_tree->VirtualFileToDiskFile(input_files_[i], &disk_file)) { + return true; } else { + // The input file path can't be mapped to any --proto_path and it also + // can't be interpreted as a virtual path. std::cerr << input_files_[i] << ": File does not reside within any path " @@ -993,15 +1155,32 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative( "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; + "than you think)." + << std::endl; + return false; } - return false; + } } } return true; } +bool CommandLineInterface::ExpandArgumentFile(const string& file, + std::vector<string>* arguments) { + // The argument file is searched in the working directory only. We don't + // use the proto import path here. + std::ifstream file_stream(file.c_str()); + if (!file_stream.is_open()) { + return false; + } + string argument; + // We don't support any kind of shell expansion right now. + while (std::getline(file_stream, argument)) { + arguments->push_back(argument); + } + return true; +} CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { @@ -1009,11 +1188,19 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { std::vector<string> arguments; for (int i = 1; i < argc; ++i) { + if (argv[i][0] == '@') { + if (!ExpandArgumentFile(argv[i] + 1, &arguments)) { + std::cerr << "Failed to open argument file: " << (argv[i] + 1) + << std::endl; + return PARSE_ARGUMENT_FAIL; + } + continue; + } arguments.push_back(argv[i]); } // if no arguments are given, show help - if(arguments.empty()) { + if (arguments.empty()) { PrintHelpText(); return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler. } @@ -1091,7 +1278,7 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { return PARSE_ARGUMENT_FAIL; } if (mode_ == MODE_COMPILE && output_directives_.empty() && - descriptor_set_name_.empty()) { + descriptor_set_out_name_.empty()) { std::cerr << "Missing output directives." << std::endl; return PARSE_ARGUMENT_FAIL; } @@ -1106,11 +1293,11 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { << std::endl; return PARSE_ARGUMENT_FAIL; } - if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) { + if (imports_in_descriptor_set_ && descriptor_set_out_name_.empty()) { 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()) { + if (source_info_in_descriptor_set_ && descriptor_set_out_name_.empty()) { std::cerr << "--include_source_info only makes sense when combined with " "--descriptor_set_out." << std::endl; } @@ -1197,11 +1384,20 @@ CommandLineInterface::InterpretArgument(const string& name, input_files_.push_back(value); } else if (name == "-I" || name == "--proto_path") { + if (!descriptor_set_in_names_.empty()) { + std::cerr << "Only one of " << name + << " and --descriptor_set_in can be specified." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } + // Java's -classpath (and some other languages) delimits path components // with colons. Let's accept that syntax too just to make things more // intuitive. std::vector<string> parts = Split( - value, kPathSeparator, true); + value, + CommandLineInterface::kPathSeparator, + true); for (int i = 0; i < parts.size(); i++) { string virtual_path; @@ -1259,8 +1455,38 @@ CommandLineInterface::InterpretArgument(const string& name, } else if (name == "--direct_dependencies_violation_msg") { direct_dependencies_violation_msg_ = value; + } else if (name == "--descriptor_set_in") { + if (!descriptor_set_in_names_.empty()) { + std::cerr << name << " may only be passed once. To specify multiple " + "descriptor sets, pass them all as a single " + "parameter separated by '" + << CommandLineInterface::kPathSeparator << "'." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } + if (value.empty()) { + std::cerr << name << " requires a non-empty value." << std::endl; + return PARSE_ARGUMENT_FAIL; + } + if (!proto_path_.empty()) { + std::cerr << "Only one of " << name + << " and --proto_path can be specified." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } + if (!dependency_out_name_.empty()) { + std::cerr << name << " cannot be used with --dependency_out." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } + + descriptor_set_in_names_ = Split( + value, + CommandLineInterface::kPathSeparator, + true); + } else if (name == "-o" || name == "--descriptor_set_out") { - if (!descriptor_set_name_.empty()) { + if (!descriptor_set_out_name_.empty()) { std::cerr << name << " may only be passed once." << std::endl; return PARSE_ARGUMENT_FAIL; } @@ -1274,7 +1500,7 @@ CommandLineInterface::InterpretArgument(const string& name, "same time." << std::endl; return PARSE_ARGUMENT_FAIL; } - descriptor_set_name_ = value; + descriptor_set_out_name_ = value; } else if (name == "--dependency_out") { if (!dependency_out_name_.empty()) { @@ -1285,6 +1511,11 @@ CommandLineInterface::InterpretArgument(const string& name, std::cerr << name << " requires a non-empty value." << std::endl; return PARSE_ARGUMENT_FAIL; } + if (!descriptor_set_in_names_.empty()) { + std::cerr << name << " cannot be used with --descriptor_set_in." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } dependency_out_name_ = value; } else if (name == "--include_imports") { @@ -1324,7 +1555,7 @@ CommandLineInterface::InterpretArgument(const string& name, << std::endl; return PARSE_ARGUMENT_FAIL; } - if (!output_directives_.empty() || !descriptor_set_name_.empty()) { + if (!output_directives_.empty() || !descriptor_set_out_name_.empty()) { std::cerr << "Cannot use " << name << " and generate code or descriptors at the same time." << std::endl; @@ -1390,7 +1621,7 @@ CommandLineInterface::InterpretArgument(const string& name, << "other info at the same time." << std::endl; return PARSE_ARGUMENT_FAIL; } - if (!output_directives_.empty() || !descriptor_set_name_.empty()) { + if (!output_directives_.empty() || !descriptor_set_out_name_.empty()) { std::cerr << "Cannot use " << name << " and generate code or descriptors at the same time." << std::endl; @@ -1482,6 +1713,14 @@ void CommandLineInterface::PrintHelpText() { " pairs in text format to standard output. No\n" " PROTO_FILES should be given when using this\n" " flag.\n" +" --descriptor_set_in=FILES Specifies a delimited list of FILES\n" +" each containing a FileDescriptorSet (a\n" +" protocol buffer defined in descriptor.proto).\n" +" The FileDescriptor for each of the PROTO_FILES\n" +" provided will be loaded from these\n" +" FileDescriptorSets. If a FileDescriptor\n" +" appears multiple times, the first occurrence\n" +" will be used.\n" " -oFILE, Writes a FileDescriptorSet (a protocol buffer,\n" " --descriptor_set_out=FILE defined in descriptor.proto) containing all of\n" " the input files to FILE.\n" @@ -1527,6 +1766,20 @@ void CommandLineInterface::PrintHelpText() { << string(19 - iter->first.size(), ' ') // Spaces for alignment. << iter->second.help_text << std::endl; } + std::cerr << +" @<filename> Read options and filenames from file. If a\n" +" relative file path is specified, the file\n" +" will be searched in the working directory.\n" +" The --proto_path option will not affect how\n" +" this argument file is searched. Content of\n" +" the file will be expanded in the position of\n" +" @<filename> as in the argument list. Note\n" +" that shell expansion is not applied to the\n" +" content of the file (i.e., you cannot use\n" +" quotes, wildcards, escapes, commands, etc.).\n" +" Each line corresponds to a single argument,\n" +" even if it contains spaces." + << std::endl; } bool CommandLineInterface::GenerateOutput( @@ -1661,6 +1914,7 @@ bool CommandLineInterface::GeneratePluginOutput( request.set_parameter(parameter); } + std::set<const FileDescriptor*> already_seen; for (int i = 0; i < parsed_files.size(); i++) { request.add_file_to_generate(parsed_files[i]->name()); @@ -1829,24 +2083,24 @@ bool CommandLineInterface::WriteDescriptorSet( int fd; do { - fd = open(descriptor_set_name_.c_str(), + fd = open(descriptor_set_out_name_.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); } while (fd < 0 && errno == EINTR); if (fd < 0) { - perror(descriptor_set_name_.c_str()); + perror(descriptor_set_out_name_.c_str()); return false; } io::FileOutputStream out(fd); if (!file_set.SerializeToZeroCopyStream(&out)) { - std::cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) + std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno()) << std::endl; out.Close(); return false; } if (!out.Close()) { - std::cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) + std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno()) << std::endl; return false; } diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index 997c1748..d5d85f2d 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -52,17 +52,16 @@ namespace protobuf { class Descriptor; // descriptor.h class DescriptorPool; // descriptor.h class FileDescriptor; // descriptor.h +class FileDescriptorSet; // descriptor.h class FileDescriptorProto; // descriptor.pb.h template<typename T> class RepeatedPtrField; // repeated_field.h +class SimpleDescriptorDatabase; // descriptor_database.h -} // namespace protobuf - -namespace protobuf { namespace compiler { -class CodeGenerator; // code_generator.h -class GeneratorContext; // code_generator.h -class DiskSourceTree; // importer.h +class CodeGenerator; // code_generator.h +class GeneratorContext; // code_generator.h +class DiskSourceTree; // importer.h // This class implements the command-line interface to the protocol compiler. // It is designed to make it very easy to create a custom protocol compiler @@ -91,9 +90,21 @@ class DiskSourceTree; // importer.h // The compiler is invoked with syntax like: // protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto // +// The .proto file to compile can be specified on the command line using either +// its physical file path, or a virtual path relative to a diretory specified +// in --proto_path. For example, for src/foo.proto, the following two protoc +// invocations work the same way: +// 1. protoc --proto_path=src src/foo.proto (physical file path) +// 2. protoc --proto_path=src foo.proto (virtual path relative to src) +// +// If a file path can be interpreted both as a physical file path and as a +// relative virtual path, the physical file path takes precendence. +// // For a full description of the command-line syntax, invoke it with --help. class LIBPROTOC_EXPORT CommandLineInterface { public: + static const char* const kPathSeparator; + CommandLineInterface(); ~CommandLineInterface(); @@ -175,17 +186,11 @@ class LIBPROTOC_EXPORT CommandLineInterface { // it calls strerror(). I'm not sure why you'd want to do this anyway. int Run(int argc, const char* const argv[]); - // Call SetInputsAreCwdRelative(true) if the input files given on the command - // line should be interpreted relative to the proto import path specified - // using --proto_path or -I flags. Otherwise, input file names will be - // interpreted relative to the current working directory (or as absolute - // paths if they start with '/'), though they must still reside inside - // a directory given by --proto_path or the compiler will fail. The latter - // mode is generally more intuitive and easier to use, especially e.g. when - // defining implicit rules in Makefiles. - void SetInputsAreProtoPathRelative(bool enable) { - inputs_are_proto_path_relative_ = enable; - } + // DEPRECATED. Calling this method has no effect. Protocol compiler now + // always try to find the .proto file relative to the current directory + // first and if the file is not found, it will then treat the input path + // as a virutal path. + void SetInputsAreProtoPathRelative(bool /* enable */) {} // Provides some text which will be printed when the --version flag is // used. The version of libprotoc will also be printed on the next line @@ -222,6 +227,9 @@ class LIBPROTOC_EXPORT CommandLineInterface { // Parse all command-line arguments. ParseArgumentStatus ParseArguments(int argc, const char* const argv[]); + // Read an argument file and append the file's content to the list of + // arguments. Return false if the file cannot be read. + bool ExpandArgumentFile(const string& file, std::vector<string>* arguments); // Parses a command-line argument into a name/value pair. Returns // true if the next argument in the argv should be used as the value, @@ -243,6 +251,16 @@ class LIBPROTOC_EXPORT CommandLineInterface { // Print the --help text to stderr. void PrintHelpText(); + // Loads proto_path_ into the provided source_tree. + bool InitializeDiskSourceTree(DiskSourceTree* source_tree); + + // Loads descriptor_set_in into the provided database + bool PopulateSimpleDescriptorDatabase(SimpleDescriptorDatabase* database); + + // Parses input_files_ into parsed_files + bool ParseInputFiles(DescriptorPool* descriptor_pool, + std::vector<const FileDescriptor*>* parsed_files); + // Generate the given output file from the given input. struct OutputDirective; // see below bool GenerateOutput(const std::vector<const FileDescriptor*>& parsed_files, @@ -383,9 +401,13 @@ class LIBPROTOC_EXPORT CommandLineInterface { // decoding. (Empty string indicates --decode_raw.) string codec_type_; + // If --descriptor_set_in was given, these are filenames containing + // parsed FileDescriptorSets to be used for loading protos. Otherwise, empty. + std::vector<string> descriptor_set_in_names_; + // If --descriptor_set_out was given, this is the filename to which the // FileDescriptorSet should be written. Otherwise, empty. - string descriptor_set_name_; + string descriptor_set_out_name_; // If --dependency_out was given, this is the path to the file where the // dependency file will be written. Otherwise, empty. @@ -408,9 +430,6 @@ class LIBPROTOC_EXPORT CommandLineInterface { // Was the --disallow_services flag used? bool disallow_services_; - // See SetInputsAreProtoPathRelative(). - bool inputs_are_proto_path_relative_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface); }; diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 366e623f..ef7579a2 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -35,9 +35,8 @@ #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> -#ifdef _MSC_VER -#include <io.h> -#else + +#ifndef _MSC_VER #include <unistd.h> #endif #include <memory> @@ -65,26 +64,27 @@ #include <gtest/gtest.h> #include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/io_win32.h> namespace google { namespace protobuf { namespace compiler { +#if defined(_WIN32) +// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import +// them like we do below. +using google::protobuf::internal::win32::access; +using google::protobuf::internal::win32::dup; +using google::protobuf::internal::win32::dup2; +using google::protobuf::internal::win32::close; +using google::protobuf::internal::win32::open; +using google::protobuf::internal::win32::write; +#endif + // 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 -#if defined(_WIN32) -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif -#ifndef F_OK -#define F_OK 00 // not defined by MSVC for whatever reason -#endif -#endif namespace { @@ -129,10 +129,6 @@ class CommandLineInterfaceTest : public testing::Test { // google3. #endif // !PROTOBUF_OPENSOURCE - void SetInputsAreProtoPathRelative(bool enable) { - cli_.SetInputsAreProtoPathRelative(enable); - } - // ----------------------------------------------------------------- // Methods to check the test results (called after Run()). @@ -192,12 +188,17 @@ class CommandLineInterfaceTest : public testing::Test { const string& insertions, const string& proto_name, const string& message_name); + void CheckGeneratedAnnotations(const string& name, const string& file); void ExpectNullCodeGeneratorCalled(const string& parameter); + void ReadDescriptorSet(const string& filename, FileDescriptorSet* descriptor_set); + void WriteDescriptorSet(const string& filename, + const FileDescriptorSet* descriptor_set); + void ExpectFileContent(const string& filename, const string& content); @@ -251,11 +252,6 @@ class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { // =================================================================== void CommandLineInterfaceTest::SetUp() { - // Most of these tests were written before this option was added, so we - // run with the option on (which used to be the only way) except in certain - // tests where we turn it off. - cli_.SetInputsAreProtoPathRelative(true); - temp_directory_ = TestTempDir() + "/proto2_cli_test_temp"; // If the temp directory already exists, it must be left over from a @@ -281,6 +277,7 @@ void CommandLineInterfaceTest::SetUp() { mock_generators_to_delete_.push_back(generator); cli_.RegisterGenerator("--null_out", generator, "Null output."); + disallow_plugins_ = false; } @@ -471,12 +468,18 @@ void CommandLineInterfaceTest::ExpectGeneratedWithInsertions( proto_name, temp_directory_); } +void CommandLineInterfaceTest::CheckGeneratedAnnotations(const string& name, + const string& file) { + MockCodeGenerator::CheckGeneratedAnnotations(name, file, temp_directory_); +} + void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled( const string& parameter) { EXPECT_TRUE(null_generator_->called_); EXPECT_EQ(parameter, null_generator_->parameter_); } + void CommandLineInterfaceTest::ReadDescriptorSet( const string& filename, FileDescriptorSet* descriptor_set) { string path = temp_directory_ + "/" + filename; @@ -488,6 +491,13 @@ void CommandLineInterfaceTest::ReadDescriptorSet( } } +void CommandLineInterfaceTest::WriteDescriptorSet( + const string& filename, const FileDescriptorSet* descriptor_set) { + string binary_proto; + GOOGLE_CHECK(descriptor_set->SerializeToString(&binary_proto)); + CreateTempFile(filename, binary_proto); +} + void CommandLineInterfaceTest::ExpectCapturedStdout( const string& expected_text) { EXPECT_EQ(expected_text, captured_stdout_); @@ -496,7 +506,8 @@ void CommandLineInterfaceTest::ExpectCapturedStdout( void CommandLineInterfaceTest::ExpectCapturedStdoutSubstringWithZeroReturnCode( const string& expected_substring) { EXPECT_EQ(0, return_code_); - EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, captured_stdout_); + EXPECT_PRED_FORMAT2( + testing::IsSubstring, expected_substring, captured_stdout_); } void CommandLineInterfaceTest::ExpectFileContent( @@ -525,6 +536,22 @@ TEST_F(CommandLineInterfaceTest, BasicOutput) { ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } +TEST_F(CommandLineInterfaceTest, BasicOutput_DescriptorSetIn) { + // Test that the common case works. + FileDescriptorSet file_descriptor_set; + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + WriteDescriptorSet("foo.bin", &file_descriptor_set); + + Run("protocol_compiler --test_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); +} + TEST_F(CommandLineInterfaceTest, BasicPlugin) { // Test that basic plugins work. @@ -539,6 +566,23 @@ TEST_F(CommandLineInterfaceTest, BasicPlugin) { ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); } +TEST_F(CommandLineInterfaceTest, BasicPlugin_DescriptorSetIn) { + // Test that basic plugins work. + + FileDescriptorSet file_descriptor_set; + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + WriteDescriptorSet("foo.bin", &file_descriptor_set); + + Run("protocol_compiler --plug_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); +} + TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) { // Invoke a generator and a plugin at the same time. @@ -554,6 +598,24 @@ TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) { ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); } +TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin_DescriptorSetIn) { + // Invoke a generator and a plugin at the same time. + + FileDescriptorSet file_descriptor_set; + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + WriteDescriptorSet("foo.bin", &file_descriptor_set); + + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "foo.proto", "Foo"); + ExpectGenerated("test_plugin", "", "foo.proto", "Foo"); +} + TEST_F(CommandLineInterfaceTest, MultipleInputs) { // Test parsing multiple input files. @@ -578,6 +640,34 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs) { "bar.proto", "Bar"); } +TEST_F(CommandLineInterfaceTest, MultipleInputs_DescriptorSetIn) { + // Test parsing multiple input files. + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bar.proto"); + file_descriptor_proto->add_message_type()->set_name("Bar"); + + WriteDescriptorSet("foo.bin", &file_descriptor_set); + + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto bar.proto"); + + ExpectNoErrors(); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "bar.proto", "Bar"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "bar.proto", "Bar"); +} + TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) { // Test parsing multiple input files with an import of a separate file. @@ -608,6 +698,165 @@ TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) { "bar.proto", "Bar"); } +TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport_DescriptorSetIn) { + // Test parsing multiple input files with an import of a separate file. + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bar.proto"); + file_descriptor_proto->add_dependency("baz.proto"); + DescriptorProto* message = file_descriptor_proto->add_message_type(); + message->set_name("Bar"); + FieldDescriptorProto* field = message->add_field(); + field->set_type_name("Baz"); + field->set_name("a"); + field->set_number(1); + + WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set); + + file_descriptor_set.clear_file(); + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("baz.proto"); + file_descriptor_proto->add_message_type()->set_name("Baz"); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bat.proto"); + file_descriptor_proto->add_dependency("baz.proto"); + message = file_descriptor_proto->add_message_type(); + message->set_name("Bat"); + field = message->add_field(); + field->set_type_name("Baz"); + field->set_name("a"); + field->set_number(1); + + WriteDescriptorSet("baz_and_bat.bin", &file_descriptor_set); + Run(strings::Substitute( + "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir " + "--descriptor_set_in=$0 foo.proto bar.proto", + string("$tmpdir/foo_and_bar.bin") + + CommandLineInterface::kPathSeparator + + "$tmpdir/baz_and_bat.bin")); + + ExpectNoErrors(); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "bar.proto", "Bar"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "bar.proto", "Bar"); + + Run(strings::Substitute( + "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir " + "--descriptor_set_in=$0 baz.proto bat.proto", + string("$tmpdir/foo_and_bar.bin") + + CommandLineInterface::kPathSeparator + + "$tmpdir/baz_and_bat.bin")); + + ExpectNoErrors(); + ExpectGeneratedWithMultipleInputs("test_generator", "baz.proto,bat.proto", + "baz.proto", "Baz"); + ExpectGeneratedWithMultipleInputs("test_generator", "baz.proto,bat.proto", + "bat.proto", "Bat"); + ExpectGeneratedWithMultipleInputs("test_plugin", "baz.proto,bat.proto", + "baz.proto", "Baz"); + ExpectGeneratedWithMultipleInputs("test_plugin", "baz.proto,bat.proto", + "bat.proto", "Bat"); +} + +TEST_F(CommandLineInterfaceTest, + MultipleInputsWithImport_DescriptorSetIn_DuplicateFileDescriptor) { + // Test parsing multiple input files with an import of a separate file. + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto foo_file_descriptor_proto; + foo_file_descriptor_proto.set_name("foo.proto"); + foo_file_descriptor_proto.add_message_type()->set_name("Foo"); + + file_descriptor_set.add_file()->CopyFrom(foo_file_descriptor_proto); + + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bar.proto"); + file_descriptor_proto->add_dependency("baz.proto"); + file_descriptor_proto->add_dependency("foo.proto"); + DescriptorProto* message = file_descriptor_proto->add_message_type(); + message->set_name("Bar"); + FieldDescriptorProto* field = message->add_field(); + field->set_type_name("Baz"); + field->set_name("a"); + field->set_number(1); + field = message->add_field(); + field->set_type_name("Foo"); + field->set_name("f"); + field->set_number(2); + WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set); + + file_descriptor_set.clear_file(); + file_descriptor_set.add_file()->CopyFrom(foo_file_descriptor_proto); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("baz.proto"); + file_descriptor_proto->add_dependency("foo.proto"); + message = file_descriptor_proto->add_message_type(); + message->set_name("Baz"); + field = message->add_field(); + field->set_type_name("Foo"); + field->set_name("f"); + field->set_number(1); + WriteDescriptorSet("foo_and_baz.bin", &file_descriptor_set); + + Run(strings::Substitute( + "protocol_compiler --test_out=$$tmpdir --plug_out=$$tmpdir " + "--descriptor_set_in=$0 bar.proto", + string("$tmpdir/foo_and_bar.bin") + + CommandLineInterface::kPathSeparator + + "$tmpdir/foo_and_baz.bin")); + + ExpectNoErrors(); + ExpectGenerated("test_generator", "", "bar.proto", "Bar"); + ExpectGenerated("test_plugin", "", "bar.proto", "Bar"); +} + +TEST_F(CommandLineInterfaceTest, + MultipleInputsWithImport_DescriptorSetIn_MissingImport) { + // Test parsing multiple input files with an import of a separate file. + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("foo.proto"); + file_descriptor_proto->add_message_type()->set_name("Foo"); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bar.proto"); + file_descriptor_proto->add_dependency("baz.proto"); + DescriptorProto* message = file_descriptor_proto->add_message_type(); + message->set_name("Bar"); + FieldDescriptorProto* field = message->add_field(); + field->set_type_name("Baz"); + field->set_name("a"); + field->set_number(1); + + WriteDescriptorSet("foo_and_bar.bin", &file_descriptor_set); + + file_descriptor_set.clear_file(); + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("baz.proto"); + file_descriptor_proto->add_message_type()->set_name("Baz"); + + WriteDescriptorSet("baz.bin", &file_descriptor_set); + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo_and_bar.bin " + "foo.proto bar.proto"); + ExpectErrorSubstring( + "bar.proto: Import \"baz.proto\" was not found or had errors."); + ExpectErrorSubstring("bar.proto: \"Baz\" is not defined."); +} + TEST_F(CommandLineInterfaceTest, CreateDirectory) { // Test that when we output to a sub-directory, it is created. @@ -754,6 +1003,25 @@ TEST_F(CommandLineInterfaceTest, Insert) { "foo.proto", "Foo"); } +TEST_F(CommandLineInterfaceTest, InsertWithAnnotationFixup) { + // Check that annotation spans are updated after insertions. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message MockCodeGenerator_Annotate {}\n"); + + Run("protocol_compiler " + "--test_out=TestParameter:$tmpdir " + "--plug_out=TestPluginParameter:$tmpdir " + "--test_out=insert=test_generator,test_plugin:$tmpdir " + "--plug_out=insert=test_generator,test_plugin:$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + CheckGeneratedAnnotations("test_generator", "foo.proto"); + CheckGeneratedAnnotations("test_plugin", "foo.proto"); +} + #if defined(_WIN32) TEST_F(CommandLineInterfaceTest, WindowsOutputPath) { @@ -839,17 +1107,11 @@ TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) { "}\n"); CreateTempFile("b/foo.proto", "this should not be parsed\n"); -#undef PATH_SEPARATOR -#if defined(_WIN32) -#define PATH_SEPARATOR ";" -#else -#define PATH_SEPARATOR ":" -#endif - - Run("protocol_compiler --test_out=$tmpdir " - "--proto_path=$tmpdir/a" PATH_SEPARATOR "$tmpdir/b foo.proto"); - -#undef PATH_SEPARATOR + Run(strings::Substitute( + "protocol_compiler --test_out=$$tmpdir --proto_path=$0 foo.proto", + string("$tmpdir/a") + + CommandLineInterface::kPathSeparator + + "$tmpdir/b")); ExpectNoErrors(); ExpectGenerated("test_generator", "", "foo.proto", "Foo"); @@ -1059,8 +1321,6 @@ TEST_F(CommandLineInterfaceTest, DirectDependencies_CustomErrorMessage) { TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) { // Test that we can accept working-directory-relative input files. - SetInputsAreProtoPathRelative(false); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1301,6 +1561,36 @@ TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFileForAbsolutePath) { } #endif // !_WIN32 +TEST_F(CommandLineInterfaceTest, TestArgumentFile) { + // Test parsing multiple input files using an argument file. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempFile("bar.proto", + "syntax = \"proto2\";\n" + "message Bar {}\n"); + CreateTempFile("arguments.txt", + "--test_out=$tmpdir\n" + "--plug_out=$tmpdir\n" + "--proto_path=$tmpdir\n" + "--direct_dependencies_violation_msg=%s is not imported\n" + "foo.proto\n" + "bar.proto"); + + Run("protocol_compiler @$tmpdir/arguments.txt"); + + ExpectNoErrors(); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "bar.proto", "Bar"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "bar.proto", "Bar"); +} + // ------------------------------------------------------------------- @@ -1318,6 +1608,17 @@ TEST_F(CommandLineInterfaceTest, ParseErrors) { "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n"); } +TEST_F(CommandLineInterfaceTest, ParseErrors_DescriptorSetIn) { + // Test that parse errors are reported. + CreateTempFile("foo.bin", "not a FileDescriptorSet"); + + Run("protocol_compiler --test_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + + ExpectErrorText( + "$tmpdir/foo.bin: Unable to parse.\n"); +} + TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) { // Test that parse errors are reported from multiple files. @@ -1364,16 +1665,23 @@ TEST_F(CommandLineInterfaceTest, InputNotFoundError) { Run("protocol_compiler --test_out=$tmpdir " "--proto_path=$tmpdir foo.proto"); + ExpectErrorText("foo.proto: No such file or directory\n"); +} + +TEST_F(CommandLineInterfaceTest, InputNotFoundError_DescriptorSetIn) { + // Test what happens if the input file is not found. + + Run("protocol_compiler --test_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + ExpectErrorText( - "foo.proto: File not found.\n"); + "$tmpdir/foo.bin: No such file or directory\n"); } TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) { // Test what happens when a working-directory-relative input file is not // found. - SetInputsAreProtoPathRelative(false); - Run("protocol_compiler --test_out=$tmpdir " "--proto_path=$tmpdir $tmpdir/foo.proto"); @@ -1385,8 +1693,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) { // Test what happens when a working-directory-relative input file is not // mapped to a virtual path. - SetInputsAreProtoPathRelative(false); - CreateTempFile("foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1411,8 +1717,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) { // Check what happens if the input file is not found *and* is not mapped // in the proto_path. - SetInputsAreProtoPathRelative(false); - // Create a directory called "bar" so that we can point --proto_path at it. CreateTempFile("bar/dummy", ""); @@ -1427,8 +1731,6 @@ TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) { // Test what happens when a working-directory-relative input file is shadowed // by another file in the virtual path. - SetInputsAreProtoPathRelative(false); - CreateTempFile("foo/foo.proto", "syntax = \"proto2\";\n" "message Foo {}\n"); @@ -1454,8 +1756,34 @@ TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) { "--proto_path=$tmpdir/foo foo.proto"); ExpectErrorText( - "$tmpdir/foo: warning: directory does not exist.\n" - "foo.proto: File not found.\n"); + "$tmpdir/foo: warning: directory does not exist.\n" + "foo.proto: No such file or directory\n"); +} + +TEST_F(CommandLineInterfaceTest, ProtoPathAndDescriptorSetIn) { + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir --descriptor_set_in=$tmpdir/foo.bin foo.proto"); + ExpectErrorText( + "Only one of --descriptor_set_in and --proto_path can be specified.\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin --proto_path=$tmpdir foo.proto"); + ExpectErrorText( + "Only one of --proto_path and --descriptor_set_in can be specified.\n"); +} + +TEST_F(CommandLineInterfaceTest, ProtoPathAndDependencyOut) { + Run("protocol_compiler --test_out=$tmpdir " + "--dependency_out=$tmpdir/manifest " + "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); + ExpectErrorText( + "--descriptor_set_in cannot be used with --dependency_out.\n"); + + Run("protocol_compiler --test_out=$tmpdir " + "--descriptor_set_in=$tmpdir/foo.bin " + "--dependency_out=$tmpdir/manifest foo.proto"); + ExpectErrorText( + "--dependency_out cannot be used with --descriptor_set_in.\n"); } TEST_F(CommandLineInterfaceTest, MissingInputError) { @@ -1905,9 +2233,16 @@ TEST_F(CommandLineInterfaceTest, PrintFreeFieldNumbers) { // test as a shell script, but we'd like to be able to run the test on // platforms that don't have a Bourne-compatible shell available (especially // Windows/MSVC). -class EncodeDecodeTest : public testing::Test { + +enum EncodeDecodeTestMode { + PROTO_PATH, + DESCRIPTOR_SET_IN +}; + +class EncodeDecodeTest : public testing::TestWithParam<EncodeDecodeTestMode> { protected: virtual void SetUp() { + WriteUnittestProtoDescriptorSet(); duped_stdin_ = dup(STDIN_FILENO); } @@ -1950,7 +2285,18 @@ class EncodeDecodeTest : public testing::Test { std::vector<string> args; args.push_back("protoc"); SplitStringUsing(command, " ", &args); - args.push_back("--proto_path=" + TestSourceDir()); + switch (GetParam()) { + case PROTO_PATH: + args.push_back("--proto_path=" + TestSourceDir()); + break; + case DESCRIPTOR_SET_IN: + args.push_back(StrCat( + "--descriptor_set_in=", + unittest_proto_descriptor_set_filename_)); + break; + default: + ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam(); + } google::protobuf::scoped_array<const char * > argv(new const char* [args.size()]); for (int i = 0; i < args.size(); i++) { @@ -1958,7 +2304,6 @@ class EncodeDecodeTest : public testing::Test { } CommandLineInterface cli; - cli.SetInputsAreProtoPathRelative(true); CaptureTestStdout(); CaptureTestStderr(); @@ -1996,12 +2341,37 @@ class EncodeDecodeTest : public testing::Test { } private: + void WriteUnittestProtoDescriptorSet() { + unittest_proto_descriptor_set_filename_ = + TestTempDir() + "/unittest_proto_descriptor_set.bin"; + FileDescriptorSet file_descriptor_set; + protobuf_unittest::TestAllTypes test_all_types; + test_all_types.descriptor()->file()->CopyTo(file_descriptor_set.add_file()); + + protobuf_unittest_import::ImportMessage import_message; + import_message.descriptor()->file()->CopyTo(file_descriptor_set.add_file()); + + + protobuf_unittest_import::PublicImportMessage public_import_message; + public_import_message.descriptor()->file()->CopyTo( + file_descriptor_set.add_file()); + GOOGLE_DCHECK(file_descriptor_set.IsInitialized()); + + string binary_proto; + GOOGLE_CHECK(file_descriptor_set.SerializeToString(&binary_proto)); + GOOGLE_CHECK_OK(File::SetContents( + unittest_proto_descriptor_set_filename_, + binary_proto, + true)); + } + int duped_stdin_; string captured_stdout_; string captured_stderr_; + string unittest_proto_descriptor_set_filename_; }; -TEST_F(EncodeDecodeTest, Encode) { +TEST_P(EncodeDecodeTest, Encode) { RedirectStdinFromFile(TestSourceDir() + "/google/protobuf/" "testdata/text_format_unittest_data_oneof_implemented.txt"); EXPECT_TRUE(Run("google/protobuf/unittest.proto " @@ -2011,7 +2381,7 @@ TEST_F(EncodeDecodeTest, Encode) { ExpectStderrMatchesText(""); } -TEST_F(EncodeDecodeTest, Decode) { +TEST_P(EncodeDecodeTest, Decode) { RedirectStdinFromFile(TestSourceDir() + "/google/protobuf/testdata/golden_message_oneof_implemented"); EXPECT_TRUE(Run("google/protobuf/unittest.proto " @@ -2022,7 +2392,7 @@ TEST_F(EncodeDecodeTest, Decode) { ExpectStderrMatchesText(""); } -TEST_F(EncodeDecodeTest, Partial) { +TEST_P(EncodeDecodeTest, Partial) { RedirectStdinFromText(""); EXPECT_TRUE(Run("google/protobuf/unittest.proto " "--encode=protobuf_unittest.TestRequired")); @@ -2031,7 +2401,7 @@ TEST_F(EncodeDecodeTest, Partial) { "warning: Input message is missing required fields: a, b, c\n"); } -TEST_F(EncodeDecodeTest, DecodeRaw) { +TEST_P(EncodeDecodeTest, DecodeRaw) { protobuf_unittest::TestAllTypes message; message.set_optional_int32(123); message.set_optional_string("foo"); @@ -2045,21 +2415,24 @@ TEST_F(EncodeDecodeTest, DecodeRaw) { ExpectStderrMatchesText(""); } -TEST_F(EncodeDecodeTest, UnknownType) { +TEST_P(EncodeDecodeTest, UnknownType) { EXPECT_FALSE(Run("google/protobuf/unittest.proto " "--encode=NoSuchType")); ExpectStdoutMatchesText(""); ExpectStderrMatchesText("Type not defined: NoSuchType\n"); } -TEST_F(EncodeDecodeTest, ProtoParseError) { +TEST_P(EncodeDecodeTest, ProtoParseError) { EXPECT_FALSE(Run("google/protobuf/no_such_file.proto " "--encode=NoSuchType")); ExpectStdoutMatchesText(""); ExpectStderrMatchesText( - "google/protobuf/no_such_file.proto: File not found.\n"); + "google/protobuf/no_such_file.proto: No such file or directory\n"); } +INSTANTIATE_TEST_CASE_P(FileDescriptorSetSource, + EncodeDecodeTest, + testing::Values(PROTO_PATH, DESCRIPTOR_SET_IN)); } // anonymous namespace #endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc index fce58c02..f99159f5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -125,12 +125,9 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) { importer.Import("google/protobuf/descriptor.proto"); const FileDescriptor* plugin_proto_file = importer.Import("google/protobuf/compiler/plugin.proto"); - const FileDescriptor* profile_proto_file = - importer.Import("google/protobuf/compiler/profile.proto"); EXPECT_EQ("", error_collector.text_); ASSERT_TRUE(proto_file != NULL); ASSERT_TRUE(plugin_proto_file != NULL); - ASSERT_TRUE(profile_proto_file != NULL); CppGenerator generator; MockGeneratorContext context; @@ -141,8 +138,6 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) { parameter = "dllexport_decl=LIBPROTOC_EXPORT"; ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter, &context, &error)); - ASSERT_TRUE(generator.Generate(profile_proto_file, parameter, - &context, &error)); context.ExpectFileMatches("google/protobuf/descriptor.pb.h", "google/protobuf/descriptor.pb.h"); @@ -152,10 +147,6 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) { "google/protobuf/compiler/plugin.pb.h"); context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc", "google/protobuf/compiler/plugin.pb.cc"); - context.ExpectFileMatches("google/protobuf/compiler/profile.pb.h", - "google/protobuf/compiler/profile.pb.h"); - context.ExpectFileMatches("google/protobuf/compiler/profile.pb.cc", - "google/protobuf/compiler/profile.pb.cc"); } } // namespace diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc index 6a8a83d1..8adee0f5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc @@ -81,10 +81,16 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { std::map<string, string> vars; vars["classname"] = classname_; vars["short_name"] = descriptor_->name(); - vars["enumbase"] = classname_ + (options_.proto_h ? " : int" : ""); - - printer->Print(vars, "enum $enumbase$ {\n"); - printer->Annotate("enumbase", descriptor_); + vars["enumbase"] = options_.proto_h ? " : int" : ""; + // These variables are placeholders to pick out the beginning and ends of + // identifiers for annotations (when doing so with existing variables would + // be ambiguous or impossible). They should never be set to anything but the + // empty string. + vars["{"] = ""; + vars["}"] = ""; + + printer->Print(vars, "enum $classname$$enumbase$ {\n"); + printer->Annotate("classname", descriptor_); printer->Indent(); const EnumValueDescriptor* min_value = descriptor_->value(0); @@ -102,7 +108,8 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { " PROTOBUF_DEPRECATED" : ""; if (i > 0) printer->Print(",\n"); - printer->Print(vars, "$prefix$$name$$deprecation$ = $number$"); + printer->Print(vars, "${$$prefix$$name$$}$$deprecation$ = $number$"); + printer->Annotate("{", "}", descriptor_->value(i)); if (descriptor_->value(i)->number() < min_value->number()) { min_value = descriptor_->value(i); @@ -134,14 +141,20 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { } printer->Print(vars, - "$dllexport$bool $classname$_IsValid(int value);\n" - "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n" - "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"); + "$dllexport$bool $classname$_IsValid(int value);\n" + "const $classname$ ${$$prefix$$short_name$_MIN$}$ = " + "$prefix$$min_name$;\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(vars, + "const $classname$ ${$$prefix$$short_name$_MAX$}$ = " + "$prefix$$max_name$;\n"); + printer->Annotate("{", "}", descriptor_); if (generate_array_size_) { printer->Print(vars, - "const int $prefix$$short_name$_ARRAYSIZE = " - "$prefix$$short_name$_MAX + 1;\n\n"); + "const int ${$$prefix$$short_name$_ARRAYSIZE$}$ = " + "$prefix$$short_name$_MAX + 1;\n\n"); + printer->Annotate("{", "}", descriptor_); } if (HasDescriptorMethods(descriptor_->file(), options_)) { @@ -184,6 +197,8 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) { vars["nested_name"] = descriptor_->name(); vars["classname"] = classname_; vars["constexpr"] = options_.proto_h ? "constexpr " : ""; + vars["{"] = ""; + vars["}"] = ""; printer->Print(vars, "typedef $classname$ $nested_name$;\n"); for (int j = 0; j < descriptor_->value_count(); j++) { @@ -191,22 +206,27 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) { vars["deprecated_attr"] = descriptor_->value(j)->options().deprecated() ? "GOOGLE_PROTOBUF_DEPRECATED_ATTR " : ""; printer->Print(vars, - "$deprecated_attr$static $constexpr$const $nested_name$ $tag$ =\n" + "$deprecated_attr$static $constexpr$const $nested_name$ ${$$tag$$}$ =\n" " $classname$_$tag$;\n"); + printer->Annotate("{", "}", descriptor_->value(j)); } printer->Print(vars, "static inline bool $nested_name$_IsValid(int value) {\n" " return $classname$_IsValid(value);\n" "}\n" - "static const $nested_name$ $nested_name$_MIN =\n" - " $classname$_$nested_name$_MIN;\n" - "static const $nested_name$ $nested_name$_MAX =\n" + "static const $nested_name$ ${$$nested_name$_MIN$}$ =\n" + " $classname$_$nested_name$_MIN;\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(vars, + "static const $nested_name$ ${$$nested_name$_MAX$}$ =\n" " $classname$_$nested_name$_MAX;\n"); + printer->Annotate("{", "}", descriptor_); if (generate_array_size_) { printer->Print(vars, - "static const int $nested_name$_ARRAYSIZE =\n" + "static const int ${$$nested_name$_ARRAYSIZE$}$ =\n" " $classname$_$nested_name$_ARRAYSIZE;\n"); + printer->Annotate("{", "}", descriptor_); } if (HasDescriptorMethods(descriptor_->file(), options_)) { @@ -229,27 +249,10 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) { } } -void EnumGenerator::GenerateDescriptorInitializer(io::Printer* printer) { - std::map<string, string> vars; - vars["index"] = SimpleItoa(descriptor_->index()); - vars["index_in_metadata"] = SimpleItoa(index_in_metadata_); - - if (descriptor_->containing_type() == NULL) { - printer->Print(vars, - "file_level_enum_descriptors[$index_in_metadata$] = " - "file->enum_type($index$);\n"); - } else { - vars["parent"] = ClassName(descriptor_->containing_type(), false); - printer->Print(vars, - "file_level_enum_descriptors[$index_in_metadata$] = " - "$parent$_descriptor->enum_type($index$);\n"); - } -} - -void EnumGenerator::GenerateMethods(io::Printer* printer) { +void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) { std::map<string, string> vars; vars["classname"] = classname_; - vars["index_in_metadata"] = SimpleItoa(index_in_metadata_); + vars["index_in_metadata"] = SimpleItoa(idx); vars["constexpr"] = options_.proto_h ? "constexpr " : ""; vars["file_namespace"] = FileLevelNamespace(descriptor_->file()->name()); diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h index 0b568c57..0d2488a9 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.h +++ b/src/google/protobuf/compiler/cpp/cpp_enum.h @@ -86,13 +86,10 @@ class EnumGenerator { // Source file stuff. - // Generate code that initializes the global variable storing the enum's - // descriptor. - void GenerateDescriptorInitializer(io::Printer* printer); - // Generate non-inline methods related to the enum, such as IsValidValue(). - // Goes in the .cc file. - void GenerateMethods(io::Printer* printer); + // Goes in the .cc file. EnumDescriptors are stored in an array, idx is + // the index in this array that corresponds with this enum. + void GenerateMethods(int idx, io::Printer* printer); private: const EnumDescriptor* descriptor_; @@ -101,8 +98,6 @@ class EnumGenerator { // whether to generate the *_ARRAYSIZE constant. const bool generate_array_size_; - int index_in_metadata_; - friend class FileGenerator; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); }; diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index c15be942..50c7b5f3 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -74,27 +74,26 @@ GeneratePrivateMembers(io::Printer* printer) const { void EnumFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { + printer->Print(variables_, "$deprecated_attr$$type$ $name$() const;\n"); + printer->Annotate("name", descriptor_); printer->Print(variables_, - "$deprecated_attr$$type$ $name$() const;\n" - "$deprecated_attr$void set_$name$($type$ value);\n"); + "$deprecated_attr$void ${$set_$name$$}$($type$ value);\n"); + printer->Annotate("{", "}", descriptor_); } void EnumFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const { - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; - printer->Print(variables, - "$inline$$type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + 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" @@ -113,7 +112,7 @@ GenerateMergingCode(io::Printer* printer) const { void EnumFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); + printer->Print(variables_, "swap($name$_, other->$name$_);\n"); } void EnumFieldGenerator:: @@ -143,12 +142,14 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { if (UseUnknownFieldSet(descriptor_->file(), options_)) { printer->Print(variables_, "} else {\n" - " mutable_unknown_fields()->AddVarint($number$, value);\n"); + " mutable_unknown_fields()->AddVarint(\n" + " $number$, static_cast< ::google::protobuf::uint64>(value));\n"); } else { printer->Print( "} else {\n" " unknown_fields_stream.WriteVarint32($tag$u);\n" - " unknown_fields_stream.WriteVarint32(value);\n", + " unknown_fields_stream.WriteVarint32(\n" + " static_cast< ::google::protobuf::uint32>(value));\n", "tag", SimpleItoa(internal::WireFormat::MakeTag(descriptor_))); } printer->Print(variables_, @@ -189,36 +190,33 @@ EnumOneofFieldGenerator(const FieldDescriptor* descriptor, EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {} void EnumOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const { - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; - printer->Print(variables, - "$inline$$type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + 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" + " return static_cast< $type$ >($field_member$);\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" " }\n" - " $oneof_prefix$$name$_ = value;\n" + " $field_member$ = value;\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n"); } void EnumOneofFieldGenerator:: GenerateClearingCode(io::Printer* printer) const { - printer->Print(variables_, "$oneof_prefix$$name$_ = $default$;\n"); + printer->Print(variables_, "$field_member$ = $default$;\n"); } void EnumOneofFieldGenerator:: @@ -228,9 +226,8 @@ GenerateSwappingCode(io::Printer* printer) const { void EnumOneofFieldGenerator:: GenerateConstructorCode(io::Printer* printer) const { - printer->Print( - variables_, - "_$classname$_default_instance_.$name$_ = $default$;\n"); + printer->Print(variables_, + "$ns$::_$classname$_default_instance_.$name$_ = $default$;\n"); } // =================================================================== @@ -257,49 +254,56 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "$deprecated_attr$$type$ $name$(int index) const;\n" - "$deprecated_attr$void set_$name$(int index, $type$ value);\n" - "$deprecated_attr$void add_$name$($type$ value);\n"); + "$deprecated_attr$$type$ $name$(int index) const;\n"); + printer->Annotate("name", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$set_$name$$}$(int index, $type$ value);\n"); + printer->Annotate("{", "}", descriptor_); printer->Print(variables_, - "$deprecated_attr$const ::google::protobuf::RepeatedField<int>& $name$() const;\n" - "$deprecated_attr$::google::protobuf::RepeatedField<int>* mutable_$name$();\n"); + "$deprecated_attr$void ${$add_$name$$}$($type$ value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$const ::google::protobuf::RepeatedField<int>& $name$() const;\n"); + printer->Annotate("name", descriptor_); + printer->Print(variables_, + "$deprecated_attr$::google::protobuf::RepeatedField<int>* " + "${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedEnumFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const { - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; - printer->Print(variables, - "$inline$$type$ $classname$::$name$(int index) const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + 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" + "}\n" + "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,12 +348,14 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { if (UseUnknownFieldSet(descriptor_->file(), options_)) { printer->Print(variables_, "} else {\n" - " mutable_unknown_fields()->AddVarint($number$, value);\n"); + " mutable_unknown_fields()->AddVarint(\n" + " $number$, static_cast< ::google::protobuf::uint64>(value));\n"); } else { printer->Print( "} else {\n" " unknown_fields_stream.WriteVarint32(tag);\n" - " unknown_fields_stream.WriteVarint32(value);\n"); + " unknown_fields_stream.WriteVarint32(\n" + " static_cast< ::google::protobuf::uint32>(value));\n"); } printer->Print("}\n"); } @@ -391,7 +397,7 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { "::google::protobuf::uint32 length;\n" "DO_(input->ReadVarint32(&length));\n" "::google::protobuf::io::CodedInputStream::Limit limit = " - "input->PushLimit(length);\n" + "input->PushLimit(static_cast<int>(length));\n" "while (input->BytesUntilLimit() > 0) {\n" " int value;\n" " DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" @@ -407,11 +413,13 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { " } else {\n"); if (UseUnknownFieldSet(descriptor_->file(), options_)) { printer->Print(variables_, - " mutable_unknown_fields()->AddVarint($number$, value);\n"); + " mutable_unknown_fields()->AddVarint(\n" + " $number$, static_cast< ::google::protobuf::uint64>(value));\n"); } else { printer->Print(variables_, " unknown_fields_stream.WriteVarint32(tag);\n" - " unknown_fields_stream.WriteVarint32(value);\n"); + " unknown_fields_stream.WriteVarint32(\n" + " static_cast< ::google::protobuf::uint32>(value));\n"); } printer->Print( " }\n"); @@ -432,7 +440,8 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { " $number$,\n" " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n" " output);\n" - " output->WriteVarint32(_$name$_cached_byte_size_);\n" + " output->WriteVarint32(\n" + " static_cast< ::google::protobuf::uint32>(_$name$_cached_byte_size_));\n" "}\n"); } printer->Print(variables_, @@ -460,7 +469,8 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n" " target);\n" " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(" - " _$name$_cached_byte_size_, target);\n" + " static_cast< ::google::protobuf::uint32>(\n" + " _$name$_cached_byte_size_), target);\n" " target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n" " this->$name$_, target);\n" "}\n"); @@ -476,19 +486,20 @@ GenerateByteSize(io::Printer* printer) const { printer->Print(variables_, "{\n" " size_t data_size = 0;\n" - " unsigned int count = this->$name$_size();"); + " unsigned int count = static_cast<unsigned int>(this->$name$_size());"); printer->Indent(); printer->Print(variables_, "for (unsigned int i = 0; i < count; i++) {\n" " data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(\n" - " this->$name$(i));\n" + " this->$name$(static_cast<int>(i)));\n" "}\n"); if (descriptor_->is_packed()) { printer->Print(variables_, "if (data_size > 0) {\n" " total_size += $tag_size$ +\n" - " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n" + " ::google::protobuf::internal::WireFormatLite::Int32Size(\n" + " static_cast< ::google::protobuf::int32>(data_size));\n" "}\n" "int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);\n" "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h index 3ecd7ba8..d0e87b79 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h @@ -52,8 +52,7 @@ class EnumFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; @@ -79,8 +78,7 @@ class EnumOneofFieldGenerator : public EnumFieldGenerator { ~EnumOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; @@ -98,8 +96,7 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) 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_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc index e4fce461..0a4e0bb9 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc @@ -35,9 +35,10 @@ #include <google/protobuf/compiler/cpp/cpp_extension.h> #include <map> #include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/strutil.h> + namespace google { namespace protobuf { @@ -166,46 +167,6 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { " $name$($constant_name$, $default$);\n"); } -void ExtensionGenerator::GenerateRegistration(io::Printer* printer) { - std::map<string, string> vars; - vars["extendee" ] = ExtendeeClassName(descriptor_); - vars["number" ] = SimpleItoa(descriptor_->number()); - vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type())); - vars["is_repeated"] = descriptor_->is_repeated() ? "true" : "false"; - vars["is_packed" ] = (descriptor_->is_repeated() && - descriptor_->options().packed()) - ? "true" : "false"; - - switch (descriptor_->cpp_type()) { - case FieldDescriptor::CPPTYPE_ENUM: - printer->Print( - vars, - "::google::protobuf::internal::ExtensionSet::RegisterEnumExtension(\n" - " $extendee$::internal_default_instance(),\n" - " $number$, $field_type$, $is_repeated$, $is_packed$,\n"); - printer->Print( - " &$type$_IsValid);\n", - "type", ClassName(descriptor_->enum_type(), true)); - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - printer->Print( - vars, - "::google::protobuf::internal::ExtensionSet::RegisterMessageExtension(\n" - " $extendee$::internal_default_instance(),\n" - " $number$, $field_type$, $is_repeated$, $is_packed$,\n"); - printer->Print(" $type$::internal_default_instance());\n", "type", - ClassName(descriptor_->message_type(), true)); - break; - default: - printer->Print( - vars, - "::google::protobuf::internal::ExtensionSet::RegisterExtension(\n" - " $extendee$::internal_default_instance(),\n" - " $number$, $field_type$, $is_repeated$, $is_packed$);\n"); - break; - } -} - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.h b/src/google/protobuf/compiler/cpp/cpp_extension.h index 1c1caf1f..30236d71 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.h +++ b/src/google/protobuf/compiler/cpp/cpp_extension.h @@ -67,9 +67,6 @@ class ExtensionGenerator { // Source file stuff. void GenerateDefinition(io::Printer* printer); - // Generate code to register the extension. - void GenerateRegistration(io::Printer* printer); - private: const FieldDescriptor* descriptor_; string type_traits_; diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index 4480a9d2..0cf25b33 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -61,17 +61,13 @@ using internal::WireFormat; void SetCommonFieldVariables(const FieldDescriptor* descriptor, std::map<string, string>* variables, const Options& options) { + (*variables)["ns"] = Namespace(descriptor); (*variables)["name"] = FieldName(descriptor); (*variables)["index"] = SimpleItoa(descriptor->index()); (*variables)["number"] = SimpleItoa(descriptor->number()); (*variables)["classname"] = ClassName(FieldScope(descriptor), false); (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type()); - - // non_null_ptr_to_name is usable only if has_$name$ is true. It yields a - // pointer that will not be NULL. Subclasses of FieldGenerator may set - // (*variables)["non_null_ptr_to_name"] differently. - (*variables)["non_null_ptr_to_name"] = - StrCat("&this->", FieldName(descriptor), "()"); + (*variables)["field_member"] = FieldName(descriptor) + "_"; (*variables)["tag_size"] = SimpleItoa( WireFormat::TagSize(descriptor->number(), descriptor->type())); @@ -80,8 +76,6 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["deprecated_attr"] = descriptor->options().deprecated() ? "GOOGLE_PROTOBUF_DEPRECATED_ATTR " : ""; - (*variables)["cppget"] = "Get"; - if (HasFieldPresence(descriptor->file())) { (*variables)["set_hasbit"] = "set_has_" + FieldName(descriptor) + "();"; @@ -92,18 +86,19 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["clear_hasbit"] = ""; } - // By default, empty string, so that generic code used for both oneofs and - // singular fields can be written. - (*variables)["oneof_prefix"] = ""; + // These variables are placeholders to pick out the beginning and ends of + // identifiers for annotations (when doing so with existing variables would + // be ambiguous or impossible). They should never be set to anything but the + // empty string. + (*variables)["{"] = ""; + (*variables)["}"] = ""; } void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor, std::map<string, string>* variables) { const string prefix = descriptor->containing_oneof()->name() + "_."; - (*variables)["oneof_prefix"] = prefix; (*variables)["oneof_name"] = descriptor->containing_oneof()->name(); - (*variables)["non_null_ptr_to_name"] = - StrCat(prefix, (*variables)["name"], "_"); + (*variables)["field_member"] = StrCat(prefix, (*variables)["name"], "_"); } FieldGenerator::~FieldGenerator() {} @@ -194,7 +189,6 @@ const FieldGenerator& FieldGeneratorMap::get( return *field_generators_[field->index()]; } - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index 00dc25d4..bccfcb9a 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -109,19 +109,19 @@ class FieldGenerator { // Generate inline definitions of depenent accessor functions for this field. // These are placed inside the header after all class definitions. virtual void GenerateDependentInlineAccessorDefinitions( - io::Printer* printer) const {} + io::Printer* printer) const {} // Generate inline definitions of accessor functions for this field. // These are placed inside the header after all class definitions. // In non-.proto.h mode, this generates dependent accessor functions as well. virtual void GenerateInlineAccessorDefinitions( - io::Printer* printer, bool is_inline) const = 0; + io::Printer* printer) const = 0; // Generate definitions of accessors that aren't inlined. These are // placed somewhere in the .cc file. // Most field types don't need this, so the default implementation is empty. virtual void GenerateNonInlineAccessorDefinitions( - io::Printer* /*printer*/) const {} + io::Printer* /*printer*/) const {} // Generate lines of code (statements, not declarations) which clear the // field. This is used to define the clear_$name$() method @@ -180,14 +180,14 @@ class FieldGenerator { virtual void GenerateDefaultInstanceAllocator(io::Printer* /*printer*/) const {} - // Generate code that should be run when ShutdownProtobufLibrary() is called, - // to delete all dynamically-allocated objects. - virtual void GenerateShutdownCode(io::Printer* /*printer*/) const {} - // Generate lines to decode this field, which will be placed inside the // message's MergeFromCodedStream() method. virtual void GenerateMergeFromCodedStream(io::Printer* printer) const = 0; + // Returns true if this field's "MergeFromCodedStream" code needs the arena + // to be defined as a variable. + virtual bool MergeFromCodedStreamNeedsArena() const { return false; } + // Generate lines to decode this field from a packed value, which will be // placed inside the message's MergeFromCodedStream() method. virtual void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) @@ -233,7 +233,6 @@ class FieldGeneratorMap { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); }; - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index e0542ae8..a922ee97 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -55,70 +55,24 @@ namespace google { namespace protobuf { namespace compiler { namespace cpp { -namespace { -// The list of names that are defined as macros on some platforms. We need to -// #undef them for the generated code to compile. -const char* kMacroNames[] = {"major", "minor"}; - -bool IsMacroName(const string& name) { - // Just do a linear search as the number of elements is very small. - for (int i = 0; i < GOOGLE_ARRAYSIZE(kMacroNames); ++i) { - if (name == kMacroNames[i]) return true; - } - return false; -} - -void CollectMacroNames(const Descriptor* message, std::vector<string>* names) { - for (int i = 0; i < message->field_count(); ++i) { - const FieldDescriptor* field = message->field(i); - if (IsMacroName(field->name())) { - names->push_back(field->name()); - } - } - for (int i = 0; i < message->nested_type_count(); ++i) { - CollectMacroNames(message->nested_type(i), names); - } -} - -void CollectMacroNames(const FileDescriptor* file, std::vector<string>* names) { - // Only do this for protobuf's own types. There are some google3 protos using - // macros as field names and the generated code compiles after the macro - // expansion. Undefing these macros actually breaks such code. - if (file->name() != "google/protobuf/compiler/plugin.proto") { - return; - } - for (int i = 0; i < file->message_type_count(); ++i) { - CollectMacroNames(file->message_type(i), names); - } -} - - -} // namespace - -// =================================================================== FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) : file_(file), options_(options), scc_analyzer_(options), - message_generators_owner_( - new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]), enum_generators_owner_( new google::protobuf::scoped_ptr<EnumGenerator>[file->enum_type_count()]), service_generators_owner_( new google::protobuf::scoped_ptr<ServiceGenerator>[file->service_count()]), extension_generators_owner_( new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]) { - - for (int i = 0; i < file->message_type_count(); i++) { - message_generators_owner_[i].reset( - new MessageGenerator(file->message_type(i), options, &scc_analyzer_)); - message_generators_owner_[i]->Flatten(&message_generators_); - } - - for (int i = 0; i < message_generators_.size(); i++) { - message_generators_[i]->AddGenerators(&enum_generators_, - &extension_generators_); + std::vector<const Descriptor*> msgs = FlattenMessagesInFile(file); + for (int i = 0; i < msgs.size(); i++) { + // Deleted in destructor + MessageGenerator* msg_gen = + new MessageGenerator(msgs[i], i, options, &scc_analyzer_); + message_generators_.push_back(msg_gen); + msg_gen->AddGenerators(&enum_generators_, &extension_generators_); } for (int i = 0; i < file->enum_type_count(); i++) { @@ -132,6 +86,11 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) new ServiceGenerator(file->service(i), options)); service_generators_.push_back(service_generators_owner_[i].get()); } + if (HasGenericServices(file_, options_)) { + for (int i = 0; i < service_generators_.size(); i++) { + service_generators_[i]->index_in_metadata_ = i; + } + } for (int i = 0; i < file->extension_count(); i++) { extension_generators_owner_[i].reset( @@ -139,14 +98,36 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) extension_generators_.push_back(extension_generators_owner_[i].get()); } + package_parts_ = Split(file_->package(), ".", true); } -FileGenerator::~FileGenerator() {} +FileGenerator::~FileGenerator() { + for (int i = 0; i < message_generators_.size(); i++) { + delete message_generators_[i]; + } +} void FileGenerator::GenerateMacroUndefs(io::Printer* printer) { + // Only do this for protobuf's own types. There are some google3 protos using + // macros as field names and the generated code compiles after the macro + // expansion. Undefing these macros actually breaks such code. + if (file_->name() != "google/protobuf/compiler/plugin.proto") { + return; + } std::vector<string> names_to_undef; - CollectMacroNames(file_, &names_to_undef); + std::vector<const FieldDescriptor*> fields; + ListAllFields(file_, &fields); + for (int i = 0; i < fields.size(); i++) { + const string& name = fields[i]->name(); + static const char* kMacroNames[] = {"major", "minor"}; + for (int i = 0; i < GOOGLE_ARRAYSIZE(kMacroNames); ++i) { + if (name == kMacroNames[i]) { + names_to_undef.push_back(name); + break; + } + } + } for (int i = 0; i < names_to_undef.size(); ++i) { printer->Print( "#ifdef $name$\n" @@ -162,43 +143,41 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { GenerateMacroUndefs(printer); - GenerateForwardDeclarations(printer); - - // Open namespace. - GenerateNamespaceOpeners(printer); - GenerateGlobalStateFunctionDeclarations(printer); - printer->Print("\n"); + GenerateForwardDeclarations(printer); - GenerateEnumDefinitions(printer); + { + NamespaceOpener ns(Namespace(file_), printer); - printer->Print(kThickSeparator); - printer->Print("\n"); + printer->Print("\n"); - GenerateMessageDefinitions(printer); + GenerateEnumDefinitions(printer); - printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); - GenerateServiceDefinitions(printer); + GenerateMessageDefinitions(printer); - GenerateExtensionIdentifiers(printer); + printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); - printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); + GenerateServiceDefinitions(printer); - GenerateInlineFunctionDefinitions(printer); + GenerateExtensionIdentifiers(printer); - printer->Print( - "\n" - "// @@protoc_insertion_point(namespace_scope)\n" - "\n"); + printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); - // Close up namespace. - GenerateNamespaceClosers(printer); + GenerateInlineFunctionDefinitions(printer); + + printer->Print( + "\n" + "// @@protoc_insertion_point(namespace_scope)\n" + "\n"); + } // We need to specialize some templates in the ::google::protobuf namespace: GenerateProto2NamespaceEnumSpecializations(printer); @@ -261,15 +240,12 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer, // TODO(gerbens) remove this. printer->Print( "// @@protoc_insertion_point(includes)\n"); - - // Open namespace. - GenerateNamespaceOpeners(printer); - printer->Print( - "\n" - "// @@protoc_insertion_point(namespace_scope)\n"); - // Close up namespace. - GenerateNamespaceClosers(printer); - + { + NamespaceOpener ns(Namespace(file_), printer); + printer->Print( + "\n" + "// @@protoc_insertion_point(namespace_scope)\n"); + } printer->Print( "\n" "// @@protoc_insertion_point(global_scope)\n" @@ -279,7 +255,7 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer, GenerateBottomHeaderGuard(printer, filename_identifier); } -void FileGenerator::GenerateSource(io::Printer* printer) { +void FileGenerator::GenerateSourceIncludes(io::Printer* printer) { const bool use_system_include = IsWellKnownMessage(file_); string header = StripProto(file_->name()) + (options_.proto_h ? ".proto.h" : ".pb.h"); @@ -287,9 +263,6 @@ void FileGenerator::GenerateSource(io::Printer* printer) { "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" "// source: $filename$\n" "\n" - // The generated code calls accessors that might be deprecated. We don't - // want the compiler to warn in generated code. - "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n" "#include $left$$header$$right$\n" "\n" "#include <algorithm>\n" // for swap() @@ -330,102 +303,154 @@ void FileGenerator::GenerateSource(io::Printer* printer) { } } + // TODO(gerbens) Remove this when all code in google is using the same + // proto library. This is a temporary hack to force build errors if + // the proto library is compiled with GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + // and is also linking internal proto2. This is to prevent regressions while + // we work cleaning up the code base. After this is completed and we have + // one proto lib all code uses this should be removed. + printer->Print( + "// This is a temporary google only hack\n" + "#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n" + "#include \"third_party/protobuf/version.h\"\n" + "#endif\n"); + printer->Print( "// @@protoc_insertion_point(includes)\n"); +} - GenerateNamespaceOpeners(printer); +void FileGenerator::GenerateSourceDefaultInstance(int idx, + io::Printer* printer) { + printer->Print( + "class $classname$DefaultTypeInternal {\n" + " public:\n" + " ::google::protobuf::internal::ExplicitlyConstructed<$classname$>\n" + " _instance;\n", + "classname", message_generators_[idx]->classname_); + printer->Indent(); + message_generators_[idx]->GenerateExtraDefaultFields(printer); + printer->Outdent(); + printer->Print("} _$classname$_default_instance_;\n", "classname", + message_generators_[idx]->classname_); +} - for (int i = 0; i < message_generators_.size(); i++) { - string parent; - if (IsMapEntryMessage(message_generators_[i]->descriptor_)) { - parent = ClassName(message_generators_[i]->descriptor_->containing_type(), - false) + - "::"; +namespace { + +// Generates weak symbol declarations for types that are to be considered weakly +// referenced. +void GenerateWeakDeclarations( + const FileDescriptor* file, const Options& options, + SCCAnalyzer* scc_analyzer, + io::Printer* printer) { + std::vector<const FieldDescriptor*> fields; + ListAllFields(file, &fields); + + // To ensure determinism and minimize the number of namespace statements, + // we output the forward declarations sorted on namespace and type / function + // name. + std::set<std::pair<string, string> > messages; + std::set<std::pair<string, string> > inits; + for (int i = 0; i < fields.size(); ++i) { + const FieldDescriptor* field = fields[i]; + bool is_weak = IsImplicitWeakField(field, options); + if (is_weak) { + const Descriptor* msg = field->message_type(); + string flns = FileLevelNamespace(msg); + string repr = ClassName(scc_analyzer->GetSCC(msg)->GetRepresentative()); + inits.insert(std::make_pair(flns, "InitDefaults" + repr)); + inits.insert(std::make_pair(flns, "AddDescriptors")); + messages.insert(std::make_pair(Namespace(msg), ClassName(msg))); } - printer->Print( - "class $classname$DefaultTypeInternal : " - "public ::google::protobuf::internal::ExplicitlyConstructed<$parent$$classname$> " - "{\n", - "parent", parent, "classname", message_generators_[i]->classname_); - printer->Indent(); - message_generators_[i]->GenerateExtraDefaultFields(printer); - printer->Outdent(); - printer->Print( - "} _$classname$_default_instance_;\n", - "classname", message_generators_[i]->classname_); } - for (int i = 0; i < enum_generators_.size(); i++) { - enum_generators_[i]->index_in_metadata_ = i; + if (messages.empty()) { + return; } - if (HasGenericServices(file_, options_)) { - for (int i = 0; i < service_generators_.size(); i++) { - service_generators_[i]->index_in_metadata_ = i; - } + + printer->Print("\n"); + NamespaceOpener ns(printer); + for (std::set<std::pair<string, string> >::const_iterator it = + messages.begin(); + it != messages.end(); ++it) { + ns.ChangeTo(it->first); + printer->Print( + "extern __attribute__((weak)) $classname$DefaultTypeInternal " + "_$classname$_default_instance_;\n", + "classname", it->second); + } + for (std::set<std::pair<string, string> >::const_iterator it = inits.begin(); + it != inits.end(); ++it) { + ns.ChangeTo(it->first); + printer->Print("void $name$() __attribute__((weak));\n", + "name", it->second); } +} - printer->Print( - "\n" - "namespace $file_namespace$ {\n" - "\n", - "file_namespace", FileLevelNamespace(file_->name())); +} // namespace - if (HasDescriptorMethods(file_, options_)) { - printer->Print( - "\n" - "namespace {\n" - "\n"); +void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) { + GenerateSourceIncludes(printer); + GenerateWeakDeclarations(file_, options_, &scc_analyzer_, printer); - if (!message_generators_.empty()) { - printer->Print("::google::protobuf::Metadata file_level_metadata[$size$];\n", - "size", SimpleItoa(message_generators_.size())); - } - if (!enum_generators_.empty()) { - printer->Print( - "const ::google::protobuf::EnumDescriptor* " - "file_level_enum_descriptors[$size$];\n", - "size", SimpleItoa(enum_generators_.size())); - } - if (HasGenericServices(file_, options_) && file_->service_count() > 0) { - printer->Print( - "const ::google::protobuf::ServiceDescriptor* " - "file_level_service_descriptors[$size$];\n", - "size", SimpleItoa(file_->service_count())); + { // package namespace + NamespaceOpener ns(Namespace(file_), printer); + + // Define default instances + GenerateSourceDefaultInstance(idx, printer); + if (options_.lite_implicit_weak_fields) { + printer->Print("void $classname$_ReferenceStrong() {}\n", "classname", + message_generators_[idx]->classname_); } + // Generate classes. + printer->Print("\n"); + message_generators_[idx]->GenerateClassMethods(printer); + printer->Print( - "\n" - "} // namespace\n" - "\n"); + "\n" + "// @@protoc_insertion_point(namespace_scope)\n"); + } // end package namespace + + if (IsSCCRepresentative(message_generators_[idx]->descriptor_)) { + NamespaceOpener ns(FileLevelNamespace(file_), printer); + GenerateInitForSCC(GetSCC(message_generators_[idx]->descriptor_), printer); } - // Define our externally-visible BuildDescriptors() function. (For the lite - // library, all this does is initialize default instances.) - GenerateBuildDescriptors(printer); + + printer->Print( + "namespace google {\nnamespace protobuf {\n"); + message_generators_[idx]->GenerateSourceInProto2Namespace(printer); + printer->Print( + "} // namespace protobuf\n} // namespace google\n"); printer->Print( "\n" - "} // namespace $file_namespace$\n" - "\n", - "file_namespace", FileLevelNamespace(file_->name())); + "// @@protoc_insertion_point(global_scope)\n"); +} + +void FileGenerator::GenerateGlobalSource(io::Printer* printer) { + GenerateSourceIncludes(printer); + GenerateWeakDeclarations(file_, options_, &scc_analyzer_, printer); + + // TODO(gerbens) Generate tables here + + // Define the code to initialize reflection. This code uses a global + // constructor to register reflection data with the runtime pre-main. + if (HasDescriptorMethods(file_, options_)) { + NamespaceOpener ns(FileLevelNamespace(file_), printer); + GenerateReflectionInitializationCode(printer); + } + + NamespaceOpener ns(Namespace(file_), printer); // Generate enums. for (int i = 0; i < enum_generators_.size(); i++) { - enum_generators_[i]->GenerateMethods(printer); + enum_generators_[i]->GenerateMethods(i, printer); } - // Generate classes. - for (int i = 0; i < message_generators_.size(); i++) { - printer->Print("\n"); - 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"); + // Define extensions. + for (int i = 0; i < extension_generators_.size(); i++) { + extension_generators_[i]->GenerateDefinition(printer); } if (HasGenericServices(file_, options_)) { @@ -437,17 +462,84 @@ void FileGenerator::GenerateSource(io::Printer* printer) { service_generators_[i]->GenerateImplementation(printer); } } +} - // Define extensions. - for (int i = 0; i < extension_generators_.size(); i++) { - extension_generators_[i]->GenerateDefinition(printer); +void FileGenerator::GenerateSource(io::Printer* printer) { + GenerateSourceIncludes(printer); + GenerateWeakDeclarations(file_, options_, &scc_analyzer_, printer); + + { + NamespaceOpener ns(Namespace(file_), printer); + + // Define default instances + for (int i = 0; i < message_generators_.size(); i++) { + GenerateSourceDefaultInstance(i, printer); + if (options_.lite_implicit_weak_fields) { + printer->Print("void $classname$_ReferenceStrong() {}\n", "classname", + message_generators_[i]->classname_); + } + } + } + + { + NamespaceOpener ns(FileLevelNamespace(file_), printer); + // Define the initialization code to initialize the default instances. + // This code doesn't use a global constructor. + GenerateInitializationCode(printer); + + // Define the code to initialize reflection. This code uses a global + // constructor to register reflection data with the runtime pre-main. + if (HasDescriptorMethods(file_, options_)) { + GenerateReflectionInitializationCode(printer); + } } - printer->Print( - "\n" - "// @@protoc_insertion_point(namespace_scope)\n"); - GenerateNamespaceClosers(printer); + { + NamespaceOpener ns(Namespace(file_), printer); + + // Actually implement the protos + + // Generate enums. + for (int i = 0; i < enum_generators_.size(); i++) { + enum_generators_[i]->GenerateMethods(i, printer); + } + + // Generate classes. + for (int i = 0; i < message_generators_.size(); i++) { + printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); + message_generators_[i]->GenerateClassMethods(printer); + } + + if (HasGenericServices(file_, options_)) { + // Generate services. + for (int i = 0; i < service_generators_.size(); i++) { + if (i == 0) printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); + service_generators_[i]->GenerateImplementation(printer); + } + } + + // Define extensions. + for (int i = 0; i < extension_generators_.size(); i++) { + extension_generators_[i]->GenerateDefinition(printer); + } + + printer->Print( + "\n" + "// @@protoc_insertion_point(namespace_scope)\n"); + } + + printer->Print( + "namespace google {\nnamespace protobuf {\n"); + for (int i = 0; i < message_generators_.size(); i++) { + message_generators_[i]->GenerateSourceInProto2Namespace(printer); + } + printer->Print( + "} // namespace protobuf\n} // namespace google\n"); printer->Print( "\n" @@ -477,7 +569,42 @@ class FileGenerator::ForwardDeclarations { std::map<string, const Descriptor*>& classes() { return classes_; } std::map<string, const EnumDescriptor*>& enums() { return enums_; } - void Print(io::Printer* printer, const Options& options) const { + void PrintForwardDeclarations(io::Printer* printer, + const Options& options) const { + PrintNestedDeclarations(printer, options); + PrintTopLevelDeclarations(printer, options); + } + + + private: + void PrintNestedDeclarations(io::Printer* printer, + const Options& options) const { + PrintDeclarationsInsideNamespace(printer, options); + for (std::map<string, ForwardDeclarations *>::const_iterator + it = namespaces_.begin(), + end = namespaces_.end(); + it != end; ++it) { + printer->Print("namespace $nsname$ {\n", + "nsname", it->first); + it->second->PrintNestedDeclarations(printer, options); + printer->Print("} // namespace $nsname$\n", + "nsname", it->first); + } + } + + void PrintTopLevelDeclarations(io::Printer* printer, + const Options& options) const { + PrintDeclarationsOutsideNamespace(printer, options); + for (std::map<string, ForwardDeclarations *>::const_iterator + it = namespaces_.begin(), + end = namespaces_.end(); + it != end; ++it) { + it->second->PrintTopLevelDeclarations(printer, options); + } + } + + void PrintDeclarationsInsideNamespace(io::Printer* printer, + const Options& options) const { for (std::map<string, const EnumDescriptor *>::const_iterator it = enums_.begin(), end = enums_.end(); @@ -503,34 +630,51 @@ class FileGenerator::ForwardDeclarations { options.dllexport_decl.empty() ? "" : options.dllexport_decl + " ", "classname", it->first); + if (options.lite_implicit_weak_fields) { + printer->Print("void $classname$_ReferenceStrong();\n", + "classname", it->first); + } } - for (std::map<string, ForwardDeclarations *>::const_iterator - it = namespaces_.begin(), - end = namespaces_.end(); + } + + void PrintDeclarationsOutsideNamespace(io::Printer* printer, + const Options& options) const { + if (classes_.size() == 0) return; + + printer->Print( + "namespace google {\nnamespace protobuf {\n"); + for (std::map<string, const Descriptor*>::const_iterator + it = classes_.begin(), + end = classes_.end(); it != end; ++it) { - printer->Print("namespace $nsname$ {\n", - "nsname", it->first); - it->second->Print(printer, options); - printer->Print("} // namespace $nsname$\n", - "nsname", it->first); + const Descriptor* d = it->second; + string extra_class_qualifier; + // "class" is to disambiguate in case there is also a function with this + // name. There is code out there that does this! + printer->Print( + "template<> " + "$dllexport_decl$" + "$class$$classname$* Arena::$func$< $class$$classname$>(Arena*);\n", + "classname", QualifiedClassName(d), + "func", MessageCreateFunction(d), + "class", extra_class_qualifier, + "dllexport_decl", + options.dllexport_decl.empty() ? "" : options.dllexport_decl + " "); } + printer->Print( + "} // namespace protobuf\n} // namespace google\n"); } - - private: std::map<string, ForwardDeclarations*> namespaces_; std::map<string, const Descriptor*> classes_; std::map<string, const EnumDescriptor*> enums_; }; -void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { +void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // AddDescriptors() is a file-level procedure which adds the encoded // FileDescriptorProto for this .proto file to the global DescriptorPool for - // generated files (DescriptorPool::generated_pool()). It either runs at - // static initialization time (by default) or when default_instance() is - // called for the first time (in LITE_RUNTIME mode with - // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also - // constructs default instances and registers extensions. + // generated files (DescriptorPool::generated_pool()). It ordinarily runs at + // static initialization time, but is not used at all in LITE_RUNTIME mode. // // Its sibling, AssignDescriptors(), actually pulls the compiled // FileDescriptor from the DescriptorPool and uses it to populate all of @@ -539,131 +683,83 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { // anyone calls descriptor() or GetReflection() on one of the types defined // in the file. - // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors() - // and we only use AddDescriptors() to allocate default instances. - - // TODO(ckennelly): Gate this with the same options flag to enable - // table-driven parsing. - - printer->Print("PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField\n" - " const TableStruct::entries[] = {\n"); - printer->Indent(); - - std::vector<size_t> entries; - size_t count = 0; - for (int i = 0; i < message_generators_.size(); i++) { - size_t value = message_generators_[i]->GenerateParseOffsets(printer); - entries.push_back(value); - count += value; - } - - // We need these arrays to exist, and MSVC does not like empty arrays. - if (count == 0) { - printer->Print("{0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},\n"); - } - - printer->Outdent(); - printer->Print( - "};\n" - "\n" - "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField\n" - " const TableStruct::aux[] = {\n"); - printer->Indent(); - - std::vector<size_t> aux_entries; - count = 0; - for (int i = 0; i < message_generators_.size(); i++) { - size_t value = message_generators_[i]->GenerateParseAuxTable(printer); - aux_entries.push_back(value); - count += value; - } - - if (count == 0) { - printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n"); + if (!message_generators_.empty()) { + printer->Print("::google::protobuf::Metadata file_level_metadata[$size$];\n", "size", + SimpleItoa(message_generators_.size())); } - - printer->Outdent(); - printer->Print( - "};\n" - "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const\n" - " TableStruct::schema[] = {\n"); - printer->Indent(); - - size_t offset = 0; - size_t aux_offset = 0; - for (int i = 0; i < message_generators_.size(); i++) { - message_generators_[i]->GenerateParseTable(printer, offset, aux_offset); - offset += entries[i]; - aux_offset += aux_entries[i]; + if (!enum_generators_.empty()) { + printer->Print( + "const ::google::protobuf::EnumDescriptor* " + "file_level_enum_descriptors[$size$];\n", + "size", SimpleItoa(enum_generators_.size())); } - - if (message_generators_.empty()) { - printer->Print("{ NULL, NULL, 0, -1, -1, false },\n"); + if (HasGenericServices(file_, options_) && file_->service_count() > 0) { + printer->Print( + "const ::google::protobuf::ServiceDescriptor* " + "file_level_service_descriptors[$size$];\n", + "size", SimpleItoa(file_->service_count())); } - printer->Outdent(); - printer->Print( - "};\n" - "\n"); - - if (HasDescriptorMethods(file_, options_)) { - if (!message_generators_.empty()) { - printer->Print("const ::google::protobuf::uint32 TableStruct::offsets[] = {\n"); - printer->Indent(); - std::vector<std::pair<size_t, size_t> > pairs; - for (int i = 0; i < message_generators_.size(); i++) { - pairs.push_back(message_generators_[i]->GenerateOffsets(printer)); - } - printer->Outdent(); - printer->Print( - "};\n" - "\n" - "static const ::google::protobuf::internal::MigrationSchema schemas[] = {\n"); - printer->Indent(); - { - int offset = 0; - for (int i = 0; i < message_generators_.size(); i++) { - message_generators_[i]->GenerateSchema(printer, offset, - pairs[i].second); - offset += pairs[i].first; - } - } - printer->Outdent(); - printer->Print( - "};\n" - "\nstatic " - "::google::protobuf::Message const * const file_default_instances[] = {\n"); - printer->Indent(); + if (!message_generators_.empty()) { + printer->Print( + "\n" + "const ::google::protobuf::uint32 TableStruct::offsets[] " + "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); + printer->Indent(); + std::vector<std::pair<size_t, size_t> > pairs; + pairs.reserve(message_generators_.size()); + for (int i = 0; i < message_generators_.size(); i++) { + pairs.push_back(message_generators_[i]->GenerateOffsets(printer)); + } + printer->Outdent(); + printer->Print( + "};\n" + "static const ::google::protobuf::internal::MigrationSchema schemas[] " + "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); + printer->Indent(); + { + int offset = 0; for (int i = 0; i < message_generators_.size(); i++) { - const Descriptor* descriptor = message_generators_[i]->descriptor_; - printer->Print( - "reinterpret_cast<const " - "::google::protobuf::Message*>(&_$classname$_default_instance_),\n", - "classname", ClassName(descriptor, false)); + message_generators_[i]->GenerateSchema(printer, offset, + pairs[i].second); + offset += pairs[i].first; } - printer->Outdent(); - printer->Print( - "};\n" - "\n"); - } else { - // we still need these symbols to exist + } + printer->Outdent(); + printer->Print( + "};\n" + "\nstatic " + "::google::protobuf::Message const * const file_default_instances[] = {\n"); + printer->Indent(); + for (int i = 0; i < message_generators_.size(); i++) { + const Descriptor* descriptor = message_generators_[i]->descriptor_; printer->Print( - // MSVC doesn't like empty arrays, so we add a dummy. - "const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u };\n" - "static const ::google::protobuf::internal::MigrationSchema* schemas = NULL;\n" - "static const ::google::protobuf::Message* const* " - "file_default_instances = NULL;\n"); + "reinterpret_cast<const " + "::google::protobuf::Message*>(&$ns$::_$classname$_default_instance_),\n", + "classname", ClassName(descriptor), "ns", Namespace(descriptor)); } + printer->Outdent(); + printer->Print( + "};\n" + "\n"); + } else { + // we still need these symbols to exist + printer->Print( + // MSVC doesn't like empty arrays, so we add a dummy. + "const ::google::protobuf::uint32 TableStruct::offsets[1] = {};\n" + "static const ::google::protobuf::internal::MigrationSchema* schemas = NULL;\n" + "static const ::google::protobuf::Message* const* " + "file_default_instances = NULL;\n" + "\n"); + } - // --------------------------------------------------------------- + // --------------------------------------------------------------- - // protobuf_AssignDescriptorsOnce(): The first time it is called, calls - // AssignDescriptors(). All later times, waits for the first call to - // complete and then returns. - string message_factory = "NULL"; + // protobuf_AssignDescriptorsOnce(): The first time it is called, calls + // AssignDescriptors(). All later times, waits for the first call to + // complete and then returns. + string message_factory = "NULL"; printer->Print( - "namespace {\n" - "\n" "void protobuf_AssignDescriptors() {\n" // Make sure the file has found its way into the pool. If a descriptor // is requested *during* static init then AddDescriptors() may not have @@ -684,20 +780,6 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { ? "file_level_service_descriptors" : "NULL", "factory", message_factory); - // TODO(gerbens) have the compiler include the schemas for map types - // so that this can go away, and we can potentially use table driven - // serialization for map types as well. - for (int i = 0; i < message_generators_.size(); i++) { - if (!IsMapEntryMessage(message_generators_[i]->descriptor_)) continue; - printer->Print( - "file_level_metadata[$index$].reflection = " - "$parent$::$classname$::CreateReflection(file_level_metadata[$index$]" - ".descriptor, _$classname$_default_instance_.get_mutable());\n", - "index", SimpleItoa(i), "parent", - ClassName(message_generators_[i]->descriptor_->containing_type(), - false), - "classname", ClassName(message_generators_[i]->descriptor_, false)); - } printer->Print( "}\n" "\n" @@ -720,7 +802,8 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { // protobuf_AssignDescriptorsOnce, because that is called from all the // GetMetadata member methods. printer->Print( - "void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;\n" + "void protobuf_RegisterTypes(const ::std::string&) " + "GOOGLE_PROTOBUF_ATTRIBUTE_COLD;\n" "void protobuf_RegisterTypes(const ::std::string&) {\n" " protobuf_AssignDescriptorsOnce();\n"); printer->Indent(); @@ -734,89 +817,15 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { printer->Outdent(); printer->Print( - "}\n" - "\n" - "} // namespace\n"); - } - - // ----------------------------------------------------------------- - - // ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown. - printer->Print( - "\n" - "void TableStruct::Shutdown() {\n"); - printer->Indent(); - - for (int i = 0; i < message_generators_.size(); i++) { - message_generators_[i]->GenerateShutdownCode(printer); - } - - if (HasDescriptorMethods(file_, options_)) { - for (int i = 0; i < message_generators_.size(); i++) { - if (!IsMapEntryMessage(message_generators_[i]->descriptor_)) continue; - printer->Print( - "delete file_level_metadata[$index$].reflection;\n", - "index", SimpleItoa(i)); - } - } - - printer->Outdent(); - printer->Print( - "}\n\n"); - - // ----------------------------------------------------------------- - - // Now generate the InitDefaultsImpl() function. - printer->Print( - "void TableStruct::InitDefaultsImpl() {\n" - " GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n" - // Force initialization of primitive values we depend on. - " ::google::protobuf::internal::InitProtobufDefaults();\n"); - - printer->Indent(); - - // Call the InitDefaults() methods for all of our dependencies, to make - // sure they get added first. - for (int i = 0; i < file_->dependency_count(); i++) { - const FileDescriptor* dependency = file_->dependency(i); - // Print the namespace prefix for the dependency. - string file_namespace = QualifiedFileLevelSymbol( - dependency->package(), FileLevelNamespace(dependency->name())); - // Call its AddDescriptors function. - printer->Print("$file_namespace$::InitDefaults();\n", "file_namespace", - file_namespace); - } - - // Allocate and initialize default instances. This can't be done lazily - // since default instances are returned by simple accessors and are used with - // extensions. Speaking of which, we also register extensions at this time. - for (int i = 0; i < message_generators_.size(); i++) { - message_generators_[i]->GenerateDefaultInstanceAllocator(printer); - } - for (int i = 0; i < extension_generators_.size(); i++) { - extension_generators_[i]->GenerateRegistration(printer); - } - for (int i = 0; i < message_generators_.size(); i++) { - message_generators_[i]->GenerateDefaultInstanceInitializer(printer); - } - printer->Outdent(); - printer->Print( - "}\n" - "\n" - "void InitDefaults() {\n" - " static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n" - " ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl);\n" - "}\n"); - - // ----------------------------------------------------------------- + "}\n" + "\n"); - // Now generate the AddDescriptors() function. - printer->Print( - "void AddDescriptorsImpl() {\n" - " InitDefaults();\n"); + // Now generate the AddDescriptors() function. + printer->Print( + "void AddDescriptorsImpl() {\n" + " InitDefaults();\n"); + printer->Indent(); - printer->Indent(); - if (HasDescriptorMethods(file_, options_)) { // Embed the descriptor. We simply serialize the entire // FileDescriptorProto // and embed it as a string literal, which is parsed and built into real @@ -826,10 +835,12 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { string file_data; file_proto.SerializeToString(&file_data); - printer->Print("static const char descriptor[] = {\n"); + printer->Print("static const char descriptor[] " + "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) " + "= {\n"); printer->Indent(); - if (file_data.size() > 66535) { + if (file_data.size() > 65535) { // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535 // bytes in length". Declare a static array of characters rather than use // a string literal. Only write 25 bytes per line. @@ -863,23 +874,18 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n" " \"$filename$\", &protobuf_RegisterTypes);\n", "filename", file_->name()); - } // Call the AddDescriptors() methods for all of our dependencies, to make // sure they get added first. for (int i = 0; i < file_->dependency_count(); i++) { const FileDescriptor* dependency = file_->dependency(i); // Print the namespace prefix for the dependency. - string file_namespace = QualifiedFileLevelSymbol( - dependency->package(), FileLevelNamespace(dependency->name())); + string file_namespace = FileLevelNamespace(dependency); // Call its AddDescriptors function. - printer->Print("$file_namespace$::AddDescriptors();\n", "file_namespace", + printer->Print("::$file_namespace$::AddDescriptors();\n", "file_namespace", file_namespace); } - printer->Print( - "::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown);\n"); - printer->Outdent(); printer->Print( "}\n" @@ -889,55 +895,235 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { " ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl);\n" "}\n"); - if (!StaticInitializersForced(file_, options_)) { - printer->Print("#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"); - } + printer->Print( + "// Force AddDescriptors() to be called at dynamic initialization " + "time.\n" + "struct StaticDescriptorInitializer {\n" + " StaticDescriptorInitializer() {\n" + " AddDescriptors();\n" + " }\n" + "} static_descriptor_initializer;\n"); +} + +void FileGenerator::GenerateInitForSCC(const SCC* scc, io::Printer* printer) { + const string scc_name = ClassName(scc->GetRepresentative()); printer->Print( - // With static initializers. - "// Force AddDescriptors() to be called at static initialization time.\n" - "struct StaticDescriptorInitializer {\n" - " StaticDescriptorInitializer() {\n" - " AddDescriptors();\n" - " }\n" - "} static_descriptor_initializer;\n"); - if (!StaticInitializersForced(file_, options_)) { - printer->Print("#endif // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"); + "void InitDefaults$scc_name$Impl() {\n" + " GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n" + "#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n" + " ::google::protobuf::internal::InitProtobufDefaultsForceUnique();\n" + "#else\n" + " ::google::protobuf::internal::InitProtobufDefaults();\n" + "#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n", + // Force initialization of primitive values we depend on. + "scc_name", scc_name); + + printer->Indent(); + + // Call the InitDefaults() methods for all of our dependencies, to make + // sure they get added first. + for (int i = 0; i < scc->children.size(); i++) { + const SCC* child_scc = scc->children[i]; + const FileDescriptor* dependency = child_scc->GetRepresentative()->file(); + // Print the namespace prefix for the dependency. + string file_namespace = FileLevelNamespace(dependency); + std::map<string, string> variables; + variables["file_namespace"] = file_namespace; + variables["scc_name"] = ClassName(child_scc->GetRepresentative(), false); + bool using_weak_fields = UsingImplicitWeakFields(file_, options_); + if (using_weak_fields) { + // We're building for lite with implicit weak fields, so we need to handle + // the possibility that this InitDefaults function is not linked into the + // binary. Some of these might actually be guaranteed to be non-null since + // we might have a strong reference to the dependency (via a required + // field, for example), but it's simplest to just assume that any of them + // could be null. + printer->Print( + variables, + "if (&$file_namespace$::InitDefaults$scc_name$ != NULL) {\n" + " $file_namespace$::InitDefaults$scc_name$();\n" + "}\n"); + } else { + printer->Print(variables, + "$file_namespace$::InitDefaults$scc_name$();\n"); + } } -} -void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) { - if (package_parts_.size() > 0) printer->Print("\n"); + // First construct all the necessary default instances. + for (int i = 0; i < message_generators_.size(); i++) { + if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) { + continue; + } + // TODO(gerbens) This requires this function to be friend. Remove + // the need for this. + message_generators_[i]->GenerateFieldDefaultInstances(printer); + printer->Print( + "{\n" + " void* ptr = &$ns$::_$classname$_default_instance_;\n" + " new (ptr) $ns$::$classname$();\n", + "ns", Namespace(message_generators_[i]->descriptor_), + "classname", ClassName(message_generators_[i]->descriptor_)); + if (!IsMapEntryMessage(message_generators_[i]->descriptor_)) { + printer->Print( + " ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);\n"); + } + printer->Print("}\n"); + } - for (int i = 0; i < package_parts_.size(); i++) { - printer->Print("namespace $part$ {\n", - "part", package_parts_[i]); + // TODO(gerbens) make default instances be the same as normal instances. + // Default instances differ from normal instances because they have cross + // linked message fields. + for (int i = 0; i < message_generators_.size(); i++) { + if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) { + continue; + } + printer->Print("$classname$::InitAsDefaultInstance();\n", "classname", + QualifiedClassName(message_generators_[i]->descriptor_)); } + printer->Outdent(); + printer->Print("}\n\n"); + printer->Print( + "void InitDefaults$scc_name$() {\n" + " static GOOGLE_PROTOBUF_DECLARE_ONCE(once);\n" + " ::google::protobuf::GoogleOnceInit(&once, " + "&InitDefaults$scc_name$Impl);\n" + "}\n\n", + "scc_name", scc_name); } -void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) { - if (package_parts_.size() > 0) printer->Print("\n"); +void FileGenerator::GenerateInitializationCode(io::Printer* printer) { + // Messages depend on the existence of a default instance, which has to + // initialized properly. The default instances are allocated in the data + // segment, but we can't quite allocate the type directly. The destructors + // cannot run at program exit as this could lead to segfaults in a threaded + // environment. Hence these instances must be inplace constructed at first + // use. + + if (options_.table_driven_parsing) { + // TODO(ckennelly): Gate this with the same options flag to enable + // table-driven parsing. + printer->Print( + "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField\n" + " const TableStruct::entries[] " + "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); + printer->Indent(); - for (int i = package_parts_.size() - 1; i >= 0; i--) { - printer->Print("} // namespace $part$\n", - "part", package_parts_[i]); + std::vector<size_t> entries; + size_t count = 0; + for (int i = 0; i < message_generators_.size(); i++) { + size_t value = message_generators_[i]->GenerateParseOffsets(printer); + entries.push_back(value); + count += value; + } + + // We need these arrays to exist, and MSVC does not like empty arrays. + if (count == 0) { + printer->Print("{0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},\n"); + } + + printer->Outdent(); + printer->Print( + "};\n" + "\n" + "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField\n" + " const TableStruct::aux[] " + "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); + printer->Indent(); + + std::vector<size_t> aux_entries; + count = 0; + for (int i = 0; i < message_generators_.size(); i++) { + size_t value = message_generators_[i]->GenerateParseAuxTable(printer); + aux_entries.push_back(value); + count += value; + } + + if (count == 0) { + printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n"); + } + + printer->Outdent(); + printer->Print( + "};\n" + "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const\n" + " TableStruct::schema[] " + "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n"); + printer->Indent(); + + size_t offset = 0; + size_t aux_offset = 0; + for (int i = 0; i < message_generators_.size(); i++) { + message_generators_[i]->GenerateParseTable(printer, offset, aux_offset); + offset += entries[i]; + aux_offset += aux_entries[i]; + } + + if (message_generators_.empty()) { + printer->Print("{ NULL, NULL, 0, -1, -1, false },\n"); + } + + printer->Outdent(); + printer->Print( + "};\n" + "\n"); + } + + if (!message_generators_.empty() && options_.table_driven_serialization) { + printer->Print( + "const ::google::protobuf::internal::FieldMetadata TableStruct::field_metadata[] " + "= {\n"); + printer->Indent(); + std::vector<int> field_metadata_offsets; + int idx = 0; + for (int i = 0; i < message_generators_.size(); i++) { + field_metadata_offsets.push_back(idx); + idx += message_generators_[i]->GenerateFieldMetadata(printer); + } + field_metadata_offsets.push_back(idx); + printer->Outdent(); + printer->Print( + "};\n" + "const ::google::protobuf::internal::SerializationTable " + "TableStruct::serialization_table[] = {\n"); + printer->Indent(); + // We rely on the order we layout the tables to match the order we + // calculate them with FlattenMessagesInFile, so we check here that + // these match exactly. + std::vector<const Descriptor*> calculated_order = + FlattenMessagesInFile(file_); + GOOGLE_CHECK_EQ(calculated_order.size(), message_generators_.size()); + for (int i = 0; i < message_generators_.size(); i++) { + GOOGLE_CHECK_EQ(calculated_order[i], message_generators_[i]->descriptor_); + printer->Print( + "{$num_fields$, TableStruct::field_metadata + $index$},\n", + "classname", message_generators_[i]->classname_, "num_fields", + SimpleItoa(field_metadata_offsets[i + 1] - field_metadata_offsets[i]), + "index", SimpleItoa(field_metadata_offsets[i])); + } + printer->Outdent(); + printer->Print( + "};\n" + "\n"); + } + + // ----------------------------------------------------------------- + // All functionality that need private access. + + // Now generate the InitDefaults for each SCC. + for (int i = 0; i < message_generators_.size(); i++) { + if (IsSCCRepresentative(message_generators_[i]->descriptor_)) { + GenerateInitForSCC(GetSCC(message_generators_[i]->descriptor_), printer); + } } } void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) { ForwardDeclarations decls; - for (int i = 0; i < file_->dependency_count(); i++) { - FileGenerator dependency(file_->dependency(i), options_); - dependency.FillForwardDeclarations(&decls); - } FillForwardDeclarations(&decls); - decls.Print(printer, options_); + decls.PrintForwardDeclarations(printer, options_); } void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) { - for (int i = 0; i < file_->public_dependency_count(); i++) { - FileGenerator dependency(file_->public_dependency(i), options_); - dependency.FillForwardDeclarations(decls); - } for (int i = 0; i < package_parts_.size(); i++) { decls = decls->AddOrGetNamespace(package_parts_[i]); } @@ -959,8 +1145,8 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer, "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" "// source: $filename$\n" "\n" - "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n" - "#define PROTOBUF_$filename_identifier$__INCLUDED\n" + "#ifndef PROTOBUF_$filename_identifier$_INCLUDED\n" + "#define PROTOBUF_$filename_identifier$_INCLUDED\n" "\n" "#include <string>\n", "filename", file_->name(), "filename_identifier", filename_identifier); @@ -970,11 +1156,14 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer, void FileGenerator::GenerateBottomHeaderGuard( io::Printer* printer, const string& filename_identifier) { printer->Print( - "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n", + "#endif // PROTOBUF_$filename_identifier$_INCLUDED\n", "filename_identifier", filename_identifier); } void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { + if (UsingImplicitWeakFields(file_, options_)) { + printer->Print("#include <google/protobuf/implicit_weak_message.h>\n"); + } printer->Print( "#include <google/protobuf/stubs/common.h>\n" @@ -1033,11 +1222,11 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { "#include <google/protobuf/map.h>" " // IWYU pragma: export\n"); if (HasDescriptorMethods(file_, options_)) { - printer->Print( - "#include <google/protobuf/map_field_inl.h>\n"); + printer->Print("#include <google/protobuf/map_entry.h>\n"); + printer->Print("#include <google/protobuf/map_field_inl.h>\n"); } else { - printer->Print( - "#include <google/protobuf/map_field_lite.h>\n"); + printer->Print("#include <google/protobuf/map_entry_lite.h>\n"); + printer->Print("#include <google/protobuf/map_field_lite.h>\n"); } } @@ -1104,29 +1293,56 @@ void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) { void FileGenerator::GenerateGlobalStateFunctionDeclarations( io::Printer* printer) { - // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile - // functions, so that we can declare them to be friends of each class. +// Forward-declare the AddDescriptors, InitDefaults because these are called +// by .pb.cc files depending on this file. printer->Print( "\n" "namespace $file_namespace$ {\n" - "// Internal implementation detail -- do not call these.\n" + "// Internal implementation detail -- do not use these members.\n" "struct $dllexport_decl$TableStruct {\n" + // These tables describe how to serialize and parse messages. Used + // for table driven code. " static const ::google::protobuf::internal::ParseTableField entries[];\n" " static const ::google::protobuf::internal::AuxillaryParseTableField aux[];\n" - " static const ::google::protobuf::internal::ParseTable schema[];\n" + " static const ::google::protobuf::internal::ParseTable schema[$num$];\n" + " static const ::google::protobuf::internal::FieldMetadata field_metadata[];\n" + " static const ::google::protobuf::internal::SerializationTable " + "serialization_table[];\n" " static const ::google::protobuf::uint32 offsets[];\n" - // The following function(s) need to be able to access private members of - // the messages defined in the file. So we make them static members. - // This is the internal implementation of InitDefaults. It should only - // be called by InitDefaults which makes sure it will be called only once. - " static void InitDefaultsImpl();\n" - " static void Shutdown();\n" - "};\n" - "void $dllexport_decl$AddDescriptors();\n" - "void $dllexport_decl$InitDefaults();\n" - "} // namespace $file_namespace$\n", - "file_namespace", FileLevelNamespace(file_->name()), "dllexport_decl", + "};\n", + "file_namespace", FileLevelNamespace(file_), "dllexport_decl", + options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ", + "num", SimpleItoa(std::max(size_t(1), message_generators_.size()))); + if (HasDescriptorMethods(file_, options_)) { + printer->Print( + "void $dllexport_decl$AddDescriptors();\n", "dllexport_decl", + options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); + } + for (int i = 0; i < message_generators_.size(); i++) { + if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue; + string scc_name = ClassName(message_generators_[i]->descriptor_); + // TODO(gerbens) Remove the Impl from header. This is solely because + // it currently still needs to be a friend of the protos. + printer->Print( + "void $dllexport_decl$InitDefaults$scc_name$Impl();\n" + "void $dllexport_decl$InitDefaults$scc_name$();\n", + "scc_name", scc_name, "dllexport_decl", + options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); + } + // TODO(gerbens) This is for proto1 interoperability. Remove when proto1 + // is gone. + printer->Print( + "inline void $dllexport_decl$InitDefaults() {\n", "dllexport_decl", options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); + for (int i = 0; i < message_generators_.size(); i++) { + if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue; + string scc_name = ClassName(message_generators_[i]->descriptor_); + printer->Print(" InitDefaults$scc_name$();\n", "scc_name", scc_name); + } + printer->Print("}\n"); + printer->Print( + "} // namespace $file_namespace$\n", + "file_namespace", FileLevelNamespace(file_)); } void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) { @@ -1175,51 +1391,25 @@ void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) { } void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) { - // An aside about inline functions in .proto.h mode: - // - // The PROTOBUF_INLINE_NOT_IN_HEADERS symbol controls conditionally - // moving much of the inline functions to the .pb.cc file, which can be a - // significant performance benefit for compilation time, at the expense - // of non-inline function calls. - // - // However, in .proto.h mode, the definition of the internal dependent - // base class must remain in the header, and can never be out-lined. The - // dependent base class also needs access to has-bit manipuation - // functions, so the has-bit functions must be unconditionally inlined in - // proto_h mode. - // - // This gives us three flavors of functions: - // - // 1. Functions on the message not used by the internal dependent base - // class: in .proto.h mode, only some functions are defined on the - // message class; others are defined on the dependent base class. - // These are guarded and can be out-lined. These are generated by - // GenerateInlineMethods, and include has_* bit functions in - // non-proto_h mode. - // - // 2. Functions on the internal dependent base class: these functions - // are dependent on a template parameter, so they always need to - // remain in the header. - // - // 3. Functions on the message that are used by the dependent base: the - // dependent base class down casts itself to the message - // implementation class to access these functions (the has_* bit - // manipulation functions). Unlike #1, these functions must - // unconditionally remain in the header. These are emitted by - // GenerateDependentInlineMethods, even though they are not actually - // dependent. - - printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); + // TODO(gerbens) remove pragmas when gcc is no longer used. Current version + // of gcc fires a bogus error when compiled with strict-aliasing. + printer->Print( + "#ifdef __GNUC__\n" + " #pragma GCC diagnostic push\n" + " #pragma GCC diagnostic ignored \"-Wstrict-aliasing\"\n" + "#endif // __GNUC__\n"); // Generate class inline methods. for (int i = 0; i < message_generators_.size(); i++) { if (i > 0) { printer->Print(kThinSeparator); printer->Print("\n"); } - message_generators_[i]->GenerateInlineMethods(printer, - /* is_inline = */ true); + message_generators_[i]->GenerateInlineMethods(printer); } - printer->Print("#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); + printer->Print( + "#ifdef __GNUC__\n" + " #pragma GCC diagnostic pop\n" + "#endif // __GNUC__\n"); for (int i = 0; i < message_generators_.size(); i++) { if (i > 0) { @@ -1235,13 +1425,8 @@ void FileGenerator::GenerateProto2NamespaceEnumSpecializations( io::Printer* printer) { // Emit GetEnumDescriptor specializations into google::protobuf namespace: 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>(); } - // which appears in GetEnumDescriptor() specializations. printer->Print( "\n" - "#ifndef SWIG\n" "namespace google {\nnamespace protobuf {\n" "\n"); for (int i = 0; i < enum_generators_.size(); i++) { @@ -1249,8 +1434,7 @@ void FileGenerator::GenerateProto2NamespaceEnumSpecializations( } printer->Print( "\n" - "} // namespace protobuf\n} // namespace google\n" - "#endif // SWIG\n"); + "} // namespace protobuf\n} // namespace google\n"); } } diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h index e10fe2f3..7e61cbad 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.h +++ b/src/google/protobuf/compiler/cpp/cpp_file.h @@ -35,10 +35,12 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__ +#include <algorithm> #include <memory> #ifndef _SHARED_PTR_H #include <google/protobuf/stubs/shared_ptr.h> #endif +#include <set> #include <string> #include <vector> #include <google/protobuf/stubs/common.h> @@ -82,16 +84,21 @@ class FileGenerator { const string& info_path); void GenerateSource(io::Printer* printer); + int NumMessages() const { return message_generators_.size(); } + // Similar to GenerateSource but generates only one message + void GenerateSourceForMessage(int idx, io::Printer* printer); + void GenerateGlobalSource(io::Printer* printer); + private: // Internal type used by GenerateForwardDeclarations (defined in file.cc). class ForwardDeclarations; - // Generate the BuildDescriptors() procedure, which builds all descriptors - // for types defined in the file. - void GenerateBuildDescriptors(io::Printer* printer); + void GenerateSourceIncludes(io::Printer* printer); + void GenerateSourceDefaultInstance(int idx, io::Printer* printer); - void GenerateNamespaceOpeners(io::Printer* printer); - void GenerateNamespaceClosers(io::Printer* printer); + void GenerateInitForSCC(const SCC* scc, io::Printer* printer); + void GenerateInitializationCode(io::Printer* printer); + void GenerateReflectionInitializationCode(io::Printer* printer); // For other imports, generates their forward-declarations. void GenerateForwardDeclarations(io::Printer* printer); @@ -143,11 +150,23 @@ class FileGenerator { // a breaking change so we prefer the #undef approach. void GenerateMacroUndefs(io::Printer* printer); + bool IsSCCRepresentative(const Descriptor* d) { + return GetSCCRepresentative(d) == d; + } + const Descriptor* GetSCCRepresentative(const Descriptor* d) { + return GetSCC(d)->GetRepresentative(); + } + const SCC* GetSCC(const Descriptor* d) { + return scc_analyzer_.GetSCC(d); + } + + const FileDescriptor* file_; const Options options_; SCCAnalyzer scc_analyzer_; + // Contains the post-order walk of all the messages (and child messages) in // this file. If you need a pre-order walk just reverse iterate. std::vector<MessageGenerator*> message_generators_; @@ -155,10 +174,8 @@ class FileGenerator { std::vector<ServiceGenerator*> service_generators_; std::vector<ExtensionGenerator*> extension_generators_; - // These members are just for owning (and thus proper deleting). Some of the - // message_ and enum_generators above are owned by child messages. - google::protobuf::scoped_array<google::protobuf::scoped_ptr<MessageGenerator> > - message_generators_owner_; + // These members are just for owning (and thus proper deleting). + // Nested (enum/extension)_generators are owned by child messages. google::protobuf::scoped_array<google::protobuf::scoped_ptr<EnumGenerator> > enum_generators_owner_; google::protobuf::scoped_array<google::protobuf::scoped_ptr<ServiceGenerator> > service_generators_owner_; diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc index cee31224..5d8ea300 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -41,6 +41,7 @@ #endif #include <utility> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/compiler/cpp/cpp_file.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/io/printer.h> @@ -84,7 +85,6 @@ bool CppGenerator::Generate(const FileDescriptor* file, // __declspec(dllimport) depending on what is being compiled. // Options file_options; - for (int i = 0; i < options.size(); i++) { if (options[i].first == "dllexport_decl") { file_options.dllexport_decl = options[i].second; @@ -98,14 +98,30 @@ bool CppGenerator::Generate(const FileDescriptor* file, file_options.annotation_guard_name = options[i].second; } else if (options[i].first == "lite") { file_options.enforce_lite = true; + } else if (options[i].first == "lite_implicit_weak_fields") { + file_options.lite_implicit_weak_fields = true; + if (!options[i].second.empty()) { + file_options.num_cc_files = strto32(options[i].second.c_str(), + NULL, 10); + } } else if (options[i].first == "table_driven_parsing") { file_options.table_driven_parsing = true; + } else if (options[i].first == "table_driven_serialization") { + file_options.table_driven_serialization = true; } else { *error = "Unknown generator option: " + options[i].first; return false; } } + // The safe_boundary_check option controls behavior for Google-internal + // protobuf APIs. + if (file_options.safe_boundary_check) { + *error = + "The safe_boundary_check option is not supported outside of Google."; + return false; + } + // ----------------------------------------------------------------- @@ -133,14 +149,13 @@ bool CppGenerator::Generate(const FileDescriptor* file, } } - basename.append(".pb"); { google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( - generator_context->Open(basename + ".h")); + generator_context->Open(basename + ".pb.h")); GeneratedCodeInfo annotations; io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( &annotations); - string info_path = basename + ".h.meta"; + string info_path = basename + ".pb.h.meta"; io::Printer printer(output.get(), '$', file_options.annotate_headers ? &annotation_collector : NULL); @@ -153,10 +168,39 @@ bool CppGenerator::Generate(const FileDescriptor* file, } } - // Generate cc file. - { + // Generate cc file(s). + if (UsingImplicitWeakFields(file, file_options)) { + { + // This is the global .cc file, containing enum/services/tables/reflection + google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + generator_context->Open(basename + ".pb.cc")); + io::Printer printer(output.get(), '$'); + file_generator.GenerateGlobalSource(&printer); + } + + int num_cc_files = file_generator.NumMessages(); + + // If we're using implicit weak fields then we allow the user to optionally + // specify how many files to generate, not counting the global pb.cc file. + // If we have more files than messages, then some files will be generated as + // empty placeholders. + if (file_options.num_cc_files > 0) { + GOOGLE_CHECK_LE(file_generator.NumMessages(), file_options.num_cc_files) + << "There must be at least as many numbered .cc files as messages."; + num_cc_files = file_options.num_cc_files; + } + for (int i = 0; i < num_cc_files; i++) { + // TODO(gerbens) Agree on naming scheme. + google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( + generator_context->Open(basename + "." + SimpleItoa(i) + ".cc")); + io::Printer printer(output.get(), '$'); + if (i < file_generator.NumMessages()) { + file_generator.GenerateSourceForMessage(i, &printer); + } + } + } else { google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( - generator_context->Open(basename + ".cc")); + generator_context->Open(basename + ".pb.cc")); io::Printer printer(output.get(), '$'); file_generator.GenerateSource(&printer); } diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 9cddba5c..172acedd 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -32,19 +32,22 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <google/protobuf/stubs/hash.h> #include <limits> #include <map> +#include <queue> #include <vector> -#include <google/protobuf/stubs/hash.h> -#include <google/protobuf/compiler/cpp/cpp_helpers.h> -#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/cpp/cpp_helpers.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> + + namespace google { namespace protobuf { namespace compiler { @@ -103,6 +106,30 @@ bool HasExtension(const Descriptor* descriptor) { return false; } +// Encode [0..63] as 'A'-'Z', 'a'-'z', '0'-'9', '_' +char Base63Char(int value) { + GOOGLE_CHECK_GE(value, 0); + if (value < 26) return 'A' + value; + value -= 26; + if (value < 26) return 'a' + value; + value -= 26; + if (value < 10) return '0' + value; + GOOGLE_CHECK_EQ(value, 10); + return '_'; +} + +// Given a c identifier has 63 legal characters we can't implement base64 +// encoding. So we return the k least significant "digits" in base 63. +template <typename I> +string Base63(I n, int k) { + string res; + while (k-- > 0) { + res += Base63Char(static_cast<int>(n % 63)); + n /= 63; + } + return res; +} + } // namespace string UnderscoresToCamelCase(const string& input, bool cap_next_letter) { @@ -135,38 +162,62 @@ const char kThickSeparator[] = const char kThinSeparator[] = "// -------------------------------------------------------------------\n"; -string ClassName(const Descriptor* descriptor, bool qualified) { - - // Find "outer", the descriptor of the top-level message in which - // "descriptor" is embedded. - const Descriptor* outer = descriptor; - while (outer->containing_type() != NULL) outer = outer->containing_type(); - - const string& outer_name = outer->full_name(); - string inner_name = descriptor->full_name().substr(outer_name.size()); - - if (qualified) { - return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name); - } else { - return outer->name() + DotsToUnderscores(inner_name); +bool CanInitializeByZeroing(const FieldDescriptor* field) { + if (field->is_repeated() || field->is_extension()) return false; + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_ENUM: + return field->default_value_enum()->number() == 0; + case FieldDescriptor::CPPTYPE_INT32: + return field->default_value_int32() == 0; + case FieldDescriptor::CPPTYPE_INT64: + return field->default_value_int64() == 0; + case FieldDescriptor::CPPTYPE_UINT32: + return field->default_value_uint32() == 0; + case FieldDescriptor::CPPTYPE_UINT64: + return field->default_value_uint64() == 0; + case FieldDescriptor::CPPTYPE_FLOAT: + return field->default_value_float() == 0; + case FieldDescriptor::CPPTYPE_DOUBLE: + return field->default_value_double() == 0; + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() == false; + default: + return false; } } -string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) { +string ClassName(const Descriptor* descriptor) { + const Descriptor* parent = descriptor->containing_type(); + string res; + if (parent) res += ClassName(parent) + "_"; + res += descriptor->name(); + if (IsMapEntryMessage(descriptor)) res += "_DoNotUse"; + return res; +} + +string ClassName(const EnumDescriptor* enum_descriptor) { if (enum_descriptor->containing_type() == NULL) { - if (qualified) { - return "::" + DotsToColons(enum_descriptor->full_name()); - } else { - return enum_descriptor->name(); - } + return enum_descriptor->name(); } else { - string result = ClassName(enum_descriptor->containing_type(), qualified); - result += '_'; - result += enum_descriptor->name(); - return result; + return ClassName(enum_descriptor->containing_type()) + "_" + + enum_descriptor->name(); } } +string Namespace(const string& package) { + if (package.empty()) return ""; + return "::" + DotsToColons(package); +} + +string DefaultInstanceName(const Descriptor* descriptor) { + string prefix = descriptor->file()->package().empty() ? "" : "::"; + return prefix + DotsToColons(descriptor->file()->package()) + "::_" + + ClassName(descriptor, false) + "_default_instance_"; +} + +string ReferenceFunctionName(const Descriptor* descriptor) { + return QualifiedClassName(descriptor) + "_ReferenceStrong"; +} string DependentBaseClassTemplateName(const Descriptor* descriptor) { return ClassName(descriptor, false) + "_InternalBase"; @@ -203,6 +254,30 @@ string EnumValueName(const EnumValueDescriptor* enum_value) { return result; } +int EstimateAlignmentSize(const FieldDescriptor* field) { + if (field == NULL) return 0; + if (field->is_repeated()) return 8; + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_BOOL: + return 1; + + case FieldDescriptor::CPPTYPE_INT32: + case FieldDescriptor::CPPTYPE_UINT32: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_FLOAT: + return 4; + + case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT64: + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + return 8; + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return -1; // Make compiler happy. +} + string FieldConstantName(const FieldDescriptor *field) { string field_name = UnderscoresToCamelCase(field->name(), true); string result = "k" + field_name + "FieldNumber"; @@ -477,19 +552,6 @@ string SafeFunctionName(const Descriptor* descriptor, return function_name; } -bool StaticInitializersForced(const FileDescriptor* file, - const Options& options) { - if (HasDescriptorMethods(file, options) || file->extension_count() > 0) { - return true; - } - for (int i = 0; i < file->message_type_count(); ++i) { - if (HasExtension(file->message_type(i))) { - return true; - } - } - return false; -} - static bool HasMapFields(const Descriptor* descriptor) { for (int i = 0; i < descriptor->field_count(); ++i) { @@ -654,6 +716,24 @@ void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field, "VerifyUtf8Cord", "VerifyUTF8CordNamedField", printer); } +namespace { + +void Flatten(const Descriptor* descriptor, + std::vector<const Descriptor*>* flatten) { + for (int i = 0; i < descriptor->nested_type_count(); i++) + Flatten(descriptor->nested_type(i), flatten); + flatten->push_back(descriptor); +} + +} // namespace + +void FlattenMessagesInFile(const FileDescriptor* file, + std::vector<const Descriptor*>* result) { + for (int i = 0; i < file->message_type_count(); i++) { + Flatten(file->message_type(i), result); + } +} + bool HasWeakFields(const Descriptor* descriptor) { return false; } @@ -662,6 +742,26 @@ bool HasWeakFields(const FileDescriptor* file) { return false; } +bool UsingImplicitWeakFields(const FileDescriptor* file, + const Options& options) { + return options.lite_implicit_weak_fields && + GetOptimizeFor(file, options) == FileOptions::LITE_RUNTIME; +} + + +bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options) { + return UsingImplicitWeakFields(field->file(), options) && + field->type() == FieldDescriptor::TYPE_MESSAGE && + !field->is_required() && !field->is_map() && + field->containing_oneof() == NULL; +} + +struct CompareDescriptors { + bool operator()(const Descriptor* a, const Descriptor* b) { + return a->full_name() < b->full_name(); + } +}; + SCCAnalyzer::NodeData SCCAnalyzer::DFS(const Descriptor* descriptor) { // Must not have visited already. GOOGLE_DCHECK_EQ(cache_.count(descriptor), 0); @@ -701,10 +801,33 @@ SCCAnalyzer::NodeData SCCAnalyzer::DFS(const Descriptor* descriptor) { if (scc_desc == descriptor) break; } + + // The order of descriptors is random and depends how this SCC was + // discovered. In-order to ensure maximum stability we sort it by name. + std::sort(scc->descriptors.begin(), scc->descriptors.end(), + CompareDescriptors()); + AddChildren(scc); } return result; } +void SCCAnalyzer::AddChildren(SCC* scc) { + std::set<const SCC*> seen; + for (int i = 0; i < scc->descriptors.size(); i++) { + const Descriptor* descriptor = scc->descriptors[i]; + for (int j = 0; j < descriptor->field_count(); j++) { + const Descriptor* child_msg = descriptor->field(j)->message_type(); + if (child_msg) { + const SCC* child = GetSCC(child_msg); + if (child == scc) continue; + if (seen.insert(child).second) { + scc->children.push_back(child); + } + } + } + } +} + MessageAnalysis SCCAnalyzer::GetSCCAnalysis(const SCC* scc) { if (analysis_cache_.count(scc)) return analysis_cache_[scc]; MessageAnalysis result = MessageAnalysis(); @@ -757,6 +880,46 @@ MessageAnalysis SCCAnalyzer::GetSCCAnalysis(const SCC* scc) { return analysis_cache_[scc] = result; } +void ListAllFields(const Descriptor* d, + std::vector<const FieldDescriptor*>* fields) { + // Collect sub messages + for (int i = 0; i < d->nested_type_count(); i++) { + ListAllFields(d->nested_type(i), fields); + } + // Collect message level extensions. + for (int i = 0; i < d->extension_count(); i++) { + fields->push_back(d->extension(i)); + } + // Add types of fields necessary + for (int i = 0; i < d->field_count(); i++) { + fields->push_back(d->field(i)); + } +} + +void ListAllFields(const FileDescriptor* d, + std::vector<const FieldDescriptor*>* fields) { + // Collect file level message. + for (int i = 0; i < d->message_type_count(); i++) { + ListAllFields(d->message_type(i), fields); + } + // Collect message level extensions. + for (int i = 0; i < d->extension_count(); i++) { + fields->push_back(d->extension(i)); + } +} + +void ListAllTypesForServices(const FileDescriptor* fd, + std::vector<const Descriptor*>* types) { + for (int i = 0; i < fd->service_count(); i++) { + const ServiceDescriptor* sd = fd->service(i); + for (int j = 0; j < sd->method_count(); j++) { + const MethodDescriptor* method = sd->method(j); + types->push_back(method->input_type()); + types->push_back(method->output_type()); + } + } +} + } // 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 a744a865..4026d0ed 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -38,16 +38,13 @@ #include <map> #include <string> #include <google/protobuf/compiler/cpp/cpp_options.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/descriptor.h> +#include <google/protobuf/stubs/strutil.h> namespace google { namespace protobuf { - -namespace io { -class Printer; -} - namespace compiler { namespace cpp { @@ -56,6 +53,31 @@ namespace cpp { extern const char kThickSeparator[]; extern const char kThinSeparator[]; +// Name space of the proto file. This namespace is such that the string +// "<namespace>::some_name" is the correct fully qualified namespace. +// This means if the package is empty the namespace is "", and otherwise +// the namespace is "::foo::bar::...::baz" without trailing semi-colons. +string Namespace(const string& package); +inline string Namespace(const FileDescriptor* d) { + return Namespace(d->package()); +} +template <typename Desc> +string Namespace(const Desc* d) { + return Namespace(d->file()); +} + +// Returns true if it's safe to reset "field" to zero. +bool CanInitializeByZeroing(const FieldDescriptor* field); + +string ClassName(const Descriptor* descriptor); +string ClassName(const EnumDescriptor* enum_descriptor); +template <typename Desc> +string QualifiedClassName(const Desc* d) { + return Namespace(d) + "::" + ClassName(d); +} + +// DEPRECATED just use ClassName or QualifiedClassName, a boolean is very +// unreadable at the callsite. // Returns the non-nested type name for the given type. If "qualified" is // true, prefix the type with the full namespace. For example, if you had: // package foo.bar; @@ -64,8 +86,21 @@ extern const char kThinSeparator[]; // ::foo::bar::Baz_Qux // While the non-qualified version would be: // Baz_Qux -string ClassName(const Descriptor* descriptor, bool qualified); -string ClassName(const EnumDescriptor* enum_descriptor, bool qualified); +inline string ClassName(const Descriptor* descriptor, bool qualified) { + return qualified ? QualifiedClassName(descriptor) : ClassName(descriptor); +} + +inline string ClassName(const EnumDescriptor* descriptor, bool qualified) { + return qualified ? QualifiedClassName(descriptor) : ClassName(descriptor); +} + +// Fully qualified name of the default_instance of this message. +string DefaultInstanceName(const Descriptor* descriptor); + +// Returns the name of a no-op function that we can call to introduce a linker +// dependency on the given message type. This is used to implement implicit weak +// fields. +string ReferenceFunctionName(const Descriptor* descriptor); // Name of the CRTP class template (for use with proto_h). // This is a class name, like "ProtoName_InternalBase". @@ -89,6 +124,12 @@ string FieldName(const FieldDescriptor* field); // Get the sanitized name that should be used for the given enum in C++ code. string EnumValueName(const EnumValueDescriptor* enum_value); +// Returns an estimate of the compiler's alignment for the field. This +// can't guarantee to be correct because the generated code could be compiled on +// different systems with different alignment rules. The estimates below assume +// 64-bit pointers. +int EstimateAlignmentSize(const FieldDescriptor* field); + // Get the unqualified name that should be used for a field's field // number constant. string FieldConstantName(const FieldDescriptor *field); @@ -147,6 +188,12 @@ string FilenameIdentifier(const string& filename); // For each .proto file generates a unique namespace. In this namespace global // definitions are put to prevent collisions. string FileLevelNamespace(const string& filename); +inline string FileLevelNamespace(const FileDescriptor* file) { + return FileLevelNamespace(file->name()); +} +inline string FileLevelNamespace(const Descriptor* d) { + return FileLevelNamespace(d->file()); +} // Return the qualified C++ name for a file level symbol. string QualifiedFileLevelSymbol(const string& package, const string& name); @@ -159,8 +206,18 @@ string SafeFunctionName(const Descriptor* descriptor, const FieldDescriptor* field, const string& prefix); -// Returns true if unknown fields are preseved after parsing. -inline bool PreserveUnknownFields(const Descriptor* message) { +// Returns true if unknown fields are always preserved after parsing. +inline bool AlwaysPreserveUnknownFields(const FileDescriptor* file) { + return file->syntax() != FileDescriptor::SYNTAX_PROTO3; +} + +// Returns true if unknown fields are preserved after parsing. +inline bool AlwaysPreserveUnknownFields(const Descriptor* message) { + return AlwaysPreserveUnknownFields(message->file()); +} + +// Returns true if generated messages have public unknown fields accessors +inline bool PublicUnknownFieldsAccessors(const Descriptor* message) { return message->file()->syntax() != FileDescriptor::SYNTAX_PROTO3; } @@ -168,10 +225,8 @@ inline bool PreserveUnknownFields(const Descriptor* message) { ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor( const FileDescriptor* file, const Options& options); -// If PreserveUnknownFields() is true, determines whether unknown -// fields will be stored in an UnknownFieldSet or a string. -// If PreserveUnknownFields() is false, this method will not be -// used. +// Determines whether unknown fields will be stored in an UnknownFieldSet or +// a string. inline bool UseUnknownFieldSet(const FileDescriptor* file, const Options& options) { return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME; @@ -214,10 +269,6 @@ inline bool HasFastArraySerialization(const FileDescriptor* file, return GetOptimizeFor(file, options) == FileOptions::SPEED; } -// Returns whether we have to generate code with static initializers. -bool StaticInitializersForced(const FileDescriptor* file, - const Options& options); - inline bool IsMapEntryMessage(const Descriptor* descriptor) { return descriptor->options().map_entry(); @@ -254,6 +305,15 @@ inline bool SupportsArenas(const FieldDescriptor* field) { return SupportsArenas(field->file()); } +inline bool IsCrossFileMessage(const FieldDescriptor* field) { + return field->type() == FieldDescriptor::TYPE_MESSAGE && + field->message_type()->file() != field->file(); +} + +inline string MessageCreateFunction(const Descriptor* d) { + return SupportsArenas(d) ? "CreateMessage" : "Create"; +} + bool IsAnyMessage(const FileDescriptor* descriptor); bool IsAnyMessage(const Descriptor* descriptor); @@ -277,9 +337,26 @@ inline ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor( : file->options().optimize_for(); } +// This orders the messages in a .pb.cc as it's outputted by file.cc +void FlattenMessagesInFile(const FileDescriptor* file, + std::vector<const Descriptor*>* result); +inline std::vector<const Descriptor*> FlattenMessagesInFile( + const FileDescriptor* file) { + std::vector<const Descriptor*> result; + FlattenMessagesInFile(file, &result); + return result; +} + bool HasWeakFields(const Descriptor* desc); bool HasWeakFields(const FileDescriptor* desc); +// Indicates whether we should use implicit weak fields for this file. +bool UsingImplicitWeakFields(const FileDescriptor* file, + const Options& options); + +// Indicates whether to treat this field as implicitly weak. +bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options); + // Returns true if the "required" restriction check should be ignored for the // given field. inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field, @@ -287,8 +364,46 @@ inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field, return false; } +class LIBPROTOC_EXPORT NamespaceOpener { + public: + explicit NamespaceOpener(io::Printer* printer) : printer_(printer) {} + NamespaceOpener(const string& name, io::Printer* printer) + : printer_(printer) { + ChangeTo(name); + } + ~NamespaceOpener() { ChangeTo(""); } + + void ChangeTo(const string& name) { + std::vector<string> new_stack_ = + Split(name, "::", true); + int len = std::min(name_stack_.size(), new_stack_.size()); + int common_idx = 0; + while (common_idx < len) { + if (name_stack_[common_idx] != new_stack_[common_idx]) break; + common_idx++; + } + for (int i = name_stack_.size() - 1; i >= common_idx; i--) { + printer_->Print("} // namespace $ns$\n", "ns", name_stack_[i]); + } + name_stack_.swap(new_stack_); + for (int i = common_idx; i < name_stack_.size(); i++) { + printer_->Print("namespace $ns$ {\n", "ns", name_stack_[i]); + } + } + + private: + io::Printer* printer_; + std::vector<string> name_stack_; +}; + +// Description of each strongly connected component. Note that the order +// of both the descriptors in this SCC and the order of children is +// deterministic. struct SCC { std::vector<const Descriptor*> descriptors; + std::vector<const SCC*> children; + + const Descriptor* GetRepresentative() const { return descriptors[0]; } }; struct MessageAnalysis { @@ -342,8 +457,16 @@ class LIBPROTOC_EXPORT SCCAnalyzer { // Tarjan's Strongly Connected Components algo NodeData DFS(const Descriptor* descriptor); + + // Add the SCC's that are children of this SCC to its children. + void AddChildren(SCC* scc); }; +void ListAllFields(const FileDescriptor* d, + std::vector<const FieldDescriptor*>* fields); +void ListAllTypesForServices(const FileDescriptor* fd, + std::vector<const Descriptor*>* types); + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc index 52a3b8b0..b22c0754 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -114,72 +114,37 @@ MapFieldGenerator::~MapFieldGenerator() {} void MapFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { - if (HasDescriptorMethods(descriptor_->file(), options_)) { - printer->Print( - variables_, - "public:\n" - "class $map_classname$ : public " - "::google::protobuf::internal::MapEntry<$map_classname$, \n" - " $key_cpp$, $val_cpp$,\n" - " $key_wire_type$,\n" - " $val_wire_type$,\n" - " $default_enum_value$ > {\n" - "public:\n" - " typedef ::google::protobuf::internal::MapEntry<$map_classname$, \n" - " $key_cpp$, $val_cpp$,\n" - " $key_wire_type$,\n" - " $val_wire_type$,\n" - " $default_enum_value$ > SuperType;\n" - " $map_classname$();\n" - " $map_classname$(::google::protobuf::Arena* arena);\n" - " void MergeFrom(const ::google::protobuf::Message& other) PROTOBUF_FINAL;\n" - " void MergeFrom(const $map_classname$& other);\n" - " static const Message* internal_default_instance() { return " - "reinterpret_cast<const " - "Message*>(&_$map_classname$_default_instance_); }\n" - " ::google::protobuf::Metadata GetMetadata() const;\n" - "};\n"); - } else { - printer->Print(variables_, - "public:\n" - "typedef ::google::protobuf::internal::MapEntryLite<\n" - " $key_cpp$, $val_cpp$,\n" - " $key_wire_type$,\n" - " $val_wire_type$,\n" - " $default_enum_value$ >\n" - " $map_classname$;\n"); - } printer->Print(variables_, "::google::protobuf::internal::MapField$lite$<\n" " $map_classname$,\n" " $key_cpp$, $val_cpp$,\n" " $key_wire_type$,\n" " $val_wire_type$,\n" - " $default_enum_value$ > $name$_;\n" - "private:\n"); + " $default_enum_value$ > $name$_;\n"); } void MapFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { - printer->Print(variables_, + printer->Print( + variables_, "$deprecated_attr$const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" - " $name$() const;\n" - "$deprecated_attr$::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" - " mutable_$name$();\n"); + " $name$() const;\n"); + printer->Annotate("name", descriptor_); + printer->Print(variables_, + "$deprecated_attr$::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" + " ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); } void MapFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const { - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline" : ""; - printer->Print(variables, - "$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + 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" @@ -188,9 +153,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, void MapFieldGenerator:: GenerateClearingCode(io::Printer* printer) const { - std::map<string, string> variables(variables_); - variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; - printer->Print(variables, "$this_message$$name$_.Clear();\n"); + printer->Print(variables_, "$name$_.Clear();\n"); } void MapFieldGenerator:: @@ -256,7 +219,8 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { } else { printer->Print(variables_, " unknown_fields_stream.WriteVarint32($tag$u);\n" - " unknown_fields_stream.WriteVarint32(data.size());\n" + " unknown_fields_stream.WriteVarint32(\n" + " static_cast< ::google::protobuf::uint32>(data.size()));\n" " unknown_fields_stream.WriteString(data);\n"); } @@ -267,12 +231,16 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { if (key_field->type() == FieldDescriptor::TYPE_STRING) { GenerateUtf8CheckCodeForString( - key_field, options_, true, variables_, - StrCat(key, ".data(), ", key, ".length(),\n").data(), printer); + key_field, options_, true, variables_, + StrCat(key, ".data(), static_cast<int>(", key, ".length()),\n").data(), + printer); } if (value_field->type() == FieldDescriptor::TYPE_STRING) { - GenerateUtf8CheckCodeForString(value_field, options_, true, variables_, - StrCat(value, ".data(), ", value, ".length(),\n").data(), printer); + GenerateUtf8CheckCodeForString( + value_field, options_, true, variables_, + StrCat(value, ".data(), static_cast<int>(", value, ".length()),\n") + .data(), + printer); } // If entry is allocated by arena, its desctructor should be avoided. @@ -376,14 +344,14 @@ void MapFieldGenerator::GenerateSerializeWithCachedSizes( printer->Indent(); printer->Indent(); if (string_key) { - GenerateUtf8CheckCodeForString(key_field, options_, false, variables, - "p->first.data(), p->first.length(),\n", - printer); + GenerateUtf8CheckCodeForString( + key_field, options_, false, variables, + "p->first.data(), static_cast<int>(p->first.length()),\n", printer); } if (string_value) { - GenerateUtf8CheckCodeForString(value_field, options_, false, variables, - "p->second.data(), p->second.length(),\n", - printer); + GenerateUtf8CheckCodeForString( + value_field, options_, false, variables, + "p->second.data(), static_cast<int>(p->second.length()),\n", printer); } printer->Outdent(); printer->Outdent(); @@ -404,13 +372,14 @@ void MapFieldGenerator::GenerateSerializeWithCachedSizes( " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" " it = this->$name$().begin();\n" " it != this->$name$().end(); ++it, ++n) {\n" - " items[n] = SortItem(&*it);\n" + " items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);\n" " }\n" - " ::std::sort(&items[0], &items[n], Less());\n"); + " ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n"); printer->Indent(); GenerateSerializationLoop(printer, variables, SupportsArenas(descriptor_), - utf8_check, "for (size_type i = 0; i < n; i++)", - string_key ? "items[i]" : "items[i].second", false); + utf8_check, "for (size_type i = 0; i < n; i++)", + string_key ? "items[static_cast<ptrdiff_t>(i)]" : + "items[static_cast<ptrdiff_t>(i)].second", false); printer->Outdent(); printer->Print( "} else {\n"); diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h index 02e66497..88e3b464 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h @@ -49,8 +49,7 @@ class MapFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) 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 d9524f64..9b2f090e 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -48,10 +48,13 @@ #include <google/protobuf/compiler/cpp/cpp_extension.h> #include <google/protobuf/compiler/cpp/cpp_field.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> +#include <google/protobuf/compiler/cpp/cpp_padding_optimizer.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/generated_message_table_driven.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/map_entry_lite.h> #include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> @@ -107,119 +110,19 @@ struct ExtensionRangeSorter { } }; -// This returns an estimate of the compiler's alignment for the field. This -// can't guarantee to be correct because the generated code could be compiled on -// different systems with different alignment rules. The estimates below assume -// 64-bit pointers. -int EstimateAlignmentSize(const FieldDescriptor* field) { - if (field == NULL) return 0; - if (field->is_repeated()) return 8; +bool IsPOD(const FieldDescriptor* field) { + if (field->is_repeated() || field->is_extension()) return false; switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_BOOL: - return 1; - - case FieldDescriptor::CPPTYPE_INT32: - case FieldDescriptor::CPPTYPE_UINT32: case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_FLOAT: - return 4; - + case FieldDescriptor::CPPTYPE_INT32: case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT32: case FieldDescriptor::CPPTYPE_UINT64: + case FieldDescriptor::CPPTYPE_FLOAT: case FieldDescriptor::CPPTYPE_DOUBLE: - case FieldDescriptor::CPPTYPE_STRING: - case FieldDescriptor::CPPTYPE_MESSAGE: - return 8; - } - GOOGLE_LOG(FATAL) << "Can't get here."; - return -1; // Make compiler happy. -} - -// FieldGroup is just a helper for OptimizePadding below. It holds a vector of -// fields that are grouped together because they have compatible alignment, and -// a preferred location in the final field ordering. -class FieldGroup { - public: - FieldGroup() - : preferred_location_(0) {} - - // A group with a single field. - FieldGroup(float preferred_location, const FieldDescriptor* field) - : preferred_location_(preferred_location), - fields_(1, field) {} - - // Append the fields in 'other' to this group. - void Append(const FieldGroup& other) { - if (other.fields_.empty()) { - return; - } - // Preferred location is the average among all the fields, so we weight by - // the number of fields on each FieldGroup object. - preferred_location_ = - (preferred_location_ * fields_.size() + - (other.preferred_location_ * other.fields_.size())) / - (fields_.size() + other.fields_.size()); - fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end()); - } - - void SetPreferredLocation(float location) { preferred_location_ = location; } - const std::vector<const FieldDescriptor*>& fields() const { return fields_; } - - // FieldGroup objects sort by their preferred location. - bool operator<(const FieldGroup& other) const { - return preferred_location_ < other.preferred_location_; - } - - private: - // "preferred_location_" is an estimate of where this group should go in the - // final list of fields. We compute this by taking the average index of each - // field in this group in the original ordering of fields. This is very - // approximate, but should put this group close to where its member fields - // originally went. - float preferred_location_; - std::vector<const FieldDescriptor*> fields_; - // We rely on the default copy constructor and operator= so this type can be - // used in a vector. -}; - -// Helper for the code that emits the Clear() method. -bool CanInitializeByZeroing(const FieldDescriptor* field) { - if (field->is_repeated() || field->is_extension()) return false; - switch (field->cpp_type()) { - case internal::WireFormatLite::CPPTYPE_ENUM: - return field->default_value_enum()->number() == 0; - case internal::WireFormatLite::CPPTYPE_INT32: - return field->default_value_int32() == 0; - case internal::WireFormatLite::CPPTYPE_INT64: - return field->default_value_int64() == 0; - case internal::WireFormatLite::CPPTYPE_UINT32: - return field->default_value_uint32() == 0; - case internal::WireFormatLite::CPPTYPE_UINT64: - return field->default_value_uint64() == 0; - case internal::WireFormatLite::CPPTYPE_FLOAT: - return field->default_value_float() == 0; - case internal::WireFormatLite::CPPTYPE_DOUBLE: - return field->default_value_double() == 0; - case internal::WireFormatLite::CPPTYPE_BOOL: - return field->default_value_bool() == false; - default: - return false; - } -} - -bool IsPOD(const FieldDescriptor* field) { - if (field->is_repeated() || field->is_extension()) return false; - switch (field->cpp_type()) { - case internal::WireFormatLite::CPPTYPE_ENUM: - case internal::WireFormatLite::CPPTYPE_INT32: - case internal::WireFormatLite::CPPTYPE_INT64: - case internal::WireFormatLite::CPPTYPE_UINT32: - case internal::WireFormatLite::CPPTYPE_UINT64: - case internal::WireFormatLite::CPPTYPE_FLOAT: - case internal::WireFormatLite::CPPTYPE_DOUBLE: - case internal::WireFormatLite::CPPTYPE_BOOL: + case FieldDescriptor::CPPTYPE_BOOL: return true; - case internal::WireFormatLite::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_STRING: return false; default: return false; @@ -240,133 +143,6 @@ bool CanConstructByZeroing(const FieldDescriptor* field, return ret; } -// Reorder 'fields' so that if the fields are output into a c++ class in the new -// order, fields of similiar family (see below) are together and within each -// family, alignment padding is minimized. -// -// We try to do this while keeping each field as close as possible to its field -// number order so that we don't reduce cache locality much for function that -// access each field in order. Originally, OptimizePadding used declaration -// order for its decisions, but generated code minus the serializer/parsers uses -// the output of OptimizePadding as well (stored in -// MessageGenerator::optimized_order_). Since the serializers use field number -// order, we use that as a tie-breaker. -// -// TODO(ckennelly): If/when we have profiles available for the compiler, use -// those rather than respect declaration order. -// -// We classify each field into a particular "family" of fields, that we perform -// the same operation on in our generated functions. -// -// REPEATED is placed first, as the C++ compiler automatically initializes -// these fields in layout order. -// -// STRING is grouped next, as our Clear/SharedCtor/SharedDtor walks it and -// calls ArenaStringPtr::Destroy on each. -// -// -// MESSAGE is grouped next, as our Clear/SharedDtor code walks it and calls -// delete on each. We initialize these fields with a NULL pointer (see -// MessageFieldGenerator::GenerateConstructorCode), which allows them to be -// memset. -// -// ZERO_INITIALIZABLE is memset in Clear/SharedCtor -// -// OTHER these fields are initialized one-by-one. -void OptimizePadding(std::vector<const FieldDescriptor*>* fields, - const Options& options) { - // The sorted numeric order of Family determines the declaration order in the - // memory layout. - enum Family { - REPEATED = 0, - STRING = 1, - MESSAGE = 2, - ZERO_INITIALIZABLE = 4, - OTHER = 5, - kMaxFamily - }; - - // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes. - std::vector<FieldGroup> aligned_to_1[kMaxFamily]; - std::vector<FieldGroup> aligned_to_4[kMaxFamily]; - std::vector<FieldGroup> aligned_to_8[kMaxFamily]; - for (int i = 0; i < fields->size(); ++i) { - const FieldDescriptor* field = (*fields)[i]; - - Family f = OTHER; - if (field->is_repeated()) { - f = REPEATED; - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { - f = STRING; - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - f = MESSAGE; - - } else if (CanInitializeByZeroing(field)) { - f = ZERO_INITIALIZABLE; - } - - const int j = field->number(); - switch (EstimateAlignmentSize(field)) { - case 1: aligned_to_1[f].push_back(FieldGroup(j, field)); break; - case 4: aligned_to_4[f].push_back(FieldGroup(j, field)); break; - case 8: aligned_to_8[f].push_back(FieldGroup(j, field)); break; - default: - GOOGLE_LOG(FATAL) << "Unknown alignment size."; - } - } - - // For each family, group fields to optimize padding. - for (int f = 0; f < kMaxFamily; f++) { - // Now group fields aligned to 1 byte into sets of 4, and treat those like a - // single field aligned to 4 bytes. - for (int i = 0; i < aligned_to_1[f].size(); i += 4) { - FieldGroup field_group; - for (int j = i; j < aligned_to_1[f].size() && j < i + 4; ++j) { - field_group.Append(aligned_to_1[f][j]); - } - aligned_to_4[f].push_back(field_group); - } - // Sort by preferred location to keep fields as close to their field number - // order as possible. Using stable_sort ensures that the output is - // consistent across runs. - std::stable_sort(aligned_to_4[f].begin(), aligned_to_4[f].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. - for (int i = 0; i < aligned_to_4[f].size(); i += 2) { - FieldGroup field_group; - for (int j = i; j < aligned_to_4[f].size() && j < i + 2; ++j) { - field_group.Append(aligned_to_4[f][j]); - } - if (i == aligned_to_4[f].size() - 1) { - if (f == OTHER) { - // Move incomplete 4-byte block to the beginning. This is done to - // pair with the (possible) leftover blocks from the - // ZERO_INITIALIZABLE family. - field_group.SetPreferredLocation(-1); - } else { - // Move incomplete 4-byte block to the end. - field_group.SetPreferredLocation(fields->size() + 1); - } - } - aligned_to_8[f].push_back(field_group); - } - // Sort by preferred location. - std::stable_sort(aligned_to_8[f].begin(), aligned_to_8[f].end()); - } - - // Now pull out all the FieldDescriptors in order. - fields->clear(); - for (int f = 0; f < kMaxFamily; ++f) { - for (int i = 0; i < aligned_to_8[f].size(); ++i) { - fields->insert(fields->end(), - aligned_to_8[f][i].fields().begin(), - aligned_to_8[f][i].fields().end()); - } - } -} - - // Emits an if-statement with a condition that evaluates to true if |field| is // considered non-default (will be sent over the wire), for message types // without true field presence. Should only be called if @@ -421,25 +197,31 @@ bool HasHasMethod(const FieldDescriptor* field) { void CollectMapInfo(const Descriptor* descriptor, std::map<string, string>* variables) { GOOGLE_CHECK(IsMapEntryMessage(descriptor)); + std::map<string, string>& vars = *variables; const FieldDescriptor* key = descriptor->FindFieldByName("key"); const FieldDescriptor* val = descriptor->FindFieldByName("value"); - (*variables)["key"] = PrimitiveTypeName(key->cpp_type()); + vars["key_cpp"] = PrimitiveTypeName(key->cpp_type()); switch (val->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: - (*variables)["val"] = FieldMessageTypeName(val); + vars["val_cpp"] = FieldMessageTypeName(val); break; case FieldDescriptor::CPPTYPE_ENUM: - (*variables)["val"] = ClassName(val->enum_type(), true); + vars["val_cpp"] = ClassName(val->enum_type(), true); break; default: - (*variables)["val"] = PrimitiveTypeName(val->cpp_type()); - } - (*variables)["key_wire_type"] = - "::google::protobuf::internal::WireFormatLite::TYPE_" + - ToUpper(DeclaredTypeMethodName(key->type())); - (*variables)["val_wire_type"] = - "::google::protobuf::internal::WireFormatLite::TYPE_" + - ToUpper(DeclaredTypeMethodName(val->type())); + vars["val_cpp"] = PrimitiveTypeName(val->cpp_type()); + } + vars["key_wire_type"] = "::google::protobuf::internal::WireFormatLite::TYPE_" + + ToUpper(DeclaredTypeMethodName(key->type())); + vars["val_wire_type"] = "::google::protobuf::internal::WireFormatLite::TYPE_" + + ToUpper(DeclaredTypeMethodName(val->type())); + if (descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3 && + val->type() == FieldDescriptor::TYPE_ENUM) { + const EnumValueDescriptor* default_value = val->default_value_enum(); + vars["default_enum_value"] = Int32ToString(default_value->number()); + } else { + vars["default_enum_value"] = "0"; + } } // Does the given field have a private (internal helper only) has_$name$() @@ -452,22 +234,13 @@ bool HasPrivateHasMethod(const FieldDescriptor* field) { } -bool TableDrivenEnabled(const Descriptor* descriptor, const Options& options) { +bool TableDrivenParsingEnabled( + const Descriptor* descriptor, const Options& options) { if (!options.table_driven_parsing) { return false; } // Consider table-driven parsing. We only do this if: - // - There are no extensions - if (descriptor->extension_range_count() != 0) { - return false; - } - - // - We are not using UnknownFieldSet (part of the non-lite library). - if (UseUnknownFieldSet(descriptor->file(), options)) { - return false; - } - // - We have has_bits for fields. This avoids a check on every field we set // when are present (the common case). if (!HasFieldPresence(descriptor->file())) { @@ -482,16 +255,6 @@ bool TableDrivenEnabled(const Descriptor* descriptor, const Options& options) { max_field_number = field->number(); } - // - There are no map fields. - if (field->is_map()) { - return false; - } - - // - There are no oneof fields. - if (field->containing_oneof()) { - return false; - } - // - There are no weak fields. if (field->options().weak()) { return false; @@ -503,8 +266,10 @@ bool TableDrivenEnabled(const Descriptor* descriptor, const Options& options) { return false; } - // - Field numbers are relatively dense within the actual number of fields - if (max_field_number * table_sparseness >= descriptor->field_count()) { + // - Field numbers are relatively dense within the actual number of fields. + // We check for strictly greater than in the case where there are no fields + // (only extensions) so max_field_number == descriptor->field_count() == 0. + if (max_field_number * table_sparseness > descriptor->field_count()) { return false; } @@ -516,26 +281,174 @@ bool TableDrivenEnabled(const Descriptor* descriptor, const Options& options) { return true; } +void SetUnknkownFieldsVariable(const Descriptor* descriptor, + const Options& options, + std::map<string, string>* variables) { + if (UseUnknownFieldSet(descriptor->file(), options)) { + (*variables)["unknown_fields_type"] = "::google::protobuf::UnknownFieldSet"; + } else { + (*variables)["unknown_fields_type"] = "::std::string"; + } + if (AlwaysPreserveUnknownFields(descriptor)) { + (*variables)["have_unknown_fields"] = + "_internal_metadata_.have_unknown_fields()"; + (*variables)["unknown_fields"] = "_internal_metadata_.unknown_fields()"; + } else { + (*variables)["have_unknown_fields"] = + "(_internal_metadata_.have_unknown_fields() && " + " ::google::protobuf::internal::GetProto3PreserveUnknownsDefault())"; + (*variables)["unknown_fields"] = + "(::google::protobuf::internal::GetProto3PreserveUnknownsDefault()" + " ? _internal_metadata_.unknown_fields()" + " : _internal_metadata_.default_instance())"; + } + (*variables)["mutable_unknown_fields"] = + "_internal_metadata_.mutable_unknown_fields()"; +} + +bool IsCrossFileMapField(const FieldDescriptor* field) { + if (!field->is_map()) { + return false; + } + + const Descriptor* d = field->message_type(); + const FieldDescriptor* value = d->FindFieldByNumber(2); + + return IsCrossFileMessage(value); +} + +bool IsCrossFileMaybeMap(const FieldDescriptor* field) { + if (IsCrossFileMapField(field)) { + return true; + } + + return IsCrossFileMessage(field); +} + +bool IsRequired(const std::vector<const FieldDescriptor*>& v) { + return v.front()->is_required(); +} + +// Allows chunking repeated fields together and non-repeated fields if the +// fields share the same has_byte index. +// TODO(seongkim): use lambda with capture instead of functor. +class MatchRepeatedAndHasByte { + public: + MatchRepeatedAndHasByte(const std::vector<int>* has_bit_indices, + bool has_field_presence) + : has_bit_indices_(*has_bit_indices), + has_field_presence_(has_field_presence) {} + + // Returns true if the following conditions are met: + // --both fields are repeated fields + // --both fields are non-repeated fields with either has_field_presence is + // false or have the same has_byte index. + bool operator()(const FieldDescriptor* a, const FieldDescriptor* b) const { + return a->is_repeated() == b->is_repeated() && + (!has_field_presence_ || a->is_repeated() || + has_bit_indices_[a->index()] / 8 == + has_bit_indices_[b->index()] / 8); + } + + private: + const std::vector<int>& has_bit_indices_; + const bool has_field_presence_; +}; + +// Allows chunking required fields separately after chunking with +// MatchRepeatedAndHasByte. +class MatchRepeatedAndHasByteAndRequired : public MatchRepeatedAndHasByte { + public: + MatchRepeatedAndHasByteAndRequired(const std::vector<int>* has_bit_indices, + bool has_field_presence) + : MatchRepeatedAndHasByte(has_bit_indices, has_field_presence) {} + + bool operator()(const FieldDescriptor* a, const FieldDescriptor* b) const { + return MatchRepeatedAndHasByte::operator()(a, b) && + a->is_required() == b->is_required(); + } +}; + +// Allows chunking zero-initializable fields separately after chunking with +// MatchRepeatedAndHasByte. +class MatchRepeatedAndHasByteAndZeroInits : public MatchRepeatedAndHasByte { + public: + MatchRepeatedAndHasByteAndZeroInits(const std::vector<int>* has_bit_indices, + bool has_field_presence) + : MatchRepeatedAndHasByte(has_bit_indices, has_field_presence) {} + + bool operator()(const FieldDescriptor* a, const FieldDescriptor* b) const { + return MatchRepeatedAndHasByte::operator()(a, b) && + CanInitializeByZeroing(a) == CanInitializeByZeroing(b); + } +}; + +// Collects neighboring fields based on a given criteria (equivalent predicate). +template <typename Predicate> +std::vector<std::vector<const FieldDescriptor*> > CollectFields( + const std::vector<const FieldDescriptor*>& fields, + const Predicate& equivalent) { + std::vector<std::vector<const FieldDescriptor*> > chunks; + if (fields.empty()) { + return chunks; + } + + const FieldDescriptor* last_field = fields.front(); + std::vector<const FieldDescriptor*> chunk; + for (int i = 0; i < fields.size(); i++) { + if (!equivalent(last_field, fields[i]) && !chunk.empty()) { + chunks.push_back(chunk); + chunk.clear(); + } + chunk.push_back(fields[i]); + last_field = fields[i]; + } + if (!chunk.empty()) { + chunks.push_back(chunk); + } + return chunks; +} + +// Returns a bit mask based on has_bit index of "fields" that are typically on +// the same chunk. It is used in a group presence check where _has_bits_ is +// masked to tell if any thing in "fields" is present. +uint32 GenChunkMask(const std::vector<const FieldDescriptor*>& fields, + const std::vector<int>& has_bit_indices) { + GOOGLE_CHECK(!fields.empty()); + int first_index_offset = has_bit_indices[fields.front()->index()] / 32; + uint32 chunk_mask = 0; + for (int i = 0; i < fields.size(); i++) { + const FieldDescriptor* field = fields[i]; + // "index" defines where in the _has_bits_ the field appears. + int index = has_bit_indices[field->index()]; + GOOGLE_CHECK_EQ(first_index_offset, index / 32); + chunk_mask |= static_cast<uint32>(1) << (index % 32); + } + GOOGLE_CHECK_NE(0, chunk_mask); + return chunk_mask; +} + } // anonymous namespace // =================================================================== MessageGenerator::MessageGenerator(const Descriptor* descriptor, + int index_in_file_messages, const Options& options, SCCAnalyzer* scc_analyzer) : descriptor_(descriptor), + index_in_file_messages_(index_in_file_messages), classname_(ClassName(descriptor, false)), options_(options), field_generators_(descriptor, options), max_has_bit_index_(0), - nested_generators_(new google::protobuf::scoped_ptr< - MessageGenerator>[descriptor->nested_type_count()]), enum_generators_( new google::protobuf::scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]), extension_generators_(new google::protobuf::scoped_ptr< ExtensionGenerator>[descriptor->extension_count()]), use_dependent_base_(false), num_weak_fields_(0), + message_layout_helper_(new PaddingOptimizer()), scc_analyzer_(scc_analyzer) { // Compute optimized field order to be used for layout and initialization // purposes. @@ -547,7 +460,8 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, optimized_order_.push_back(field); } } - OptimizePadding(&optimized_order_, options_); + + message_layout_helper_->OptimizeLayout(&optimized_order_, options_); if (HasFieldPresence(descriptor_->file())) { // We use -1 as a sentinel. @@ -563,11 +477,6 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, } } - for (int i = 0; i < descriptor->nested_type_count(); i++) { - nested_generators_[i].reset(new MessageGenerator(descriptor->nested_type(i), - options, scc_analyzer)); - } - for (int i = 0; i < descriptor->enum_type_count(); i++) { enum_generators_[i].reset( new EnumGenerator(descriptor->enum_type(i), options)); @@ -592,7 +501,10 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, use_dependent_base_ = true; } - table_driven_ = TableDrivenEnabled(descriptor_, options_); + table_driven_ = TableDrivenParsingEnabled(descriptor_, options_); + + scc_name_ = + ClassName(scc_analyzer_->GetSCC(descriptor_)->GetRepresentative(), false); } MessageGenerator::~MessageGenerator() {} @@ -610,14 +522,6 @@ size_t MessageGenerator::HasBitsSize() const { return sizeof_has_bits; } -void MessageGenerator::Flatten(std::vector<MessageGenerator*>* list) { - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - nested_generators_[i]->Flatten(list); - } - index_in_file_messages_ = list->size(); - list->push_back(this); -} - void MessageGenerator::AddGenerators( std::vector<EnumGenerator*>* enum_generators, std::vector<ExtensionGenerator*>* extension_generators) { @@ -644,12 +548,6 @@ GenerateDependentFieldAccessorDeclarations(io::Printer* printer) { std::map<string, string> vars; SetCommonFieldVariables(field, &vars, options_); - if (use_dependent_base_ && IsFieldDependent(field)) { - // If the message is dependent, the inline clear_*() method will need - // to delete the message type, so it must be in the dependent base - // class. (See also GenerateFieldAccessorDeclarations.) - printer->Print(vars, "$deprecated_attr$void clear_$name$();\n"); - } // Generate type-specific accessor declarations. field_generators_.get(field).GenerateDependentAccessorDeclarations(printer); printer->Print("\n"); @@ -703,24 +601,25 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { } if (field->is_repeated()) { - printer->Print(vars, "$deprecated_attr$int $name$_size() const;\n"); + printer->Print(vars, "$deprecated_attr$int ${$$name$_size$}$() const;\n"); + printer->Annotate("{", "}", field); } else if (HasHasMethod(field)) { - printer->Print(vars, "$deprecated_attr$bool has_$name$() const;\n"); + printer->Print(vars, "$deprecated_attr$bool ${$has_$name$$}$() const;\n"); + printer->Annotate("{", "}", field); } else if (HasPrivateHasMethod(field)) { printer->Print(vars, - "private:\n" - "bool has_$name$() const;\n" - "public:\n"); + "private:\n" + "bool ${$has_$name$$}$() const;\n" + "public:\n"); + printer->Annotate("{", "}", field); } - if (!dependent_field) { - // If this field is dependent, then its clear_() method is in the - // depenent base class. (See also GenerateDependentAccessorDeclarations.) - printer->Print(vars, "$deprecated_attr$void clear_$name$();\n"); - } + printer->Print(vars, "$deprecated_attr$void ${$clear_$name$$}$();\n"); + printer->Annotate("{", "}", field); printer->Print(vars, "$deprecated_attr$static const int $constant_name$ = " "$number$;\n"); + printer->Annotate("constant_name", field); // Generate type-specific accessor declarations. field_generators_.get(field).GenerateAccessorDeclarations(printer); @@ -758,36 +657,6 @@ GenerateDependentFieldAccessorDefinitions(io::Printer* printer) { if (field->options().weak()) continue; PrintFieldComment(printer, field); - - // These functions are not really dependent: they are part of the - // (non-dependent) derived class. However, they need to live outside - // any #ifdef guards, so we treat them as if they were dependent. - // - // See the comment in FileGenerator::GenerateInlineFunctionDefinitions - // for a more complete explanation. - if (use_dependent_base_ && IsFieldDependent(field)) { - std::map<string, string> vars; - SetCommonFieldVariables(field, &vars, options_); - vars["inline"] = "inline "; - if (field->containing_oneof()) { - vars["field_name"] = UnderscoresToCamelCase(field->name(), true); - vars["oneof_name"] = field->containing_oneof()->name(); - vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index()); - GenerateOneofMemberHasBits(field, vars, printer); - } else if (!field->is_repeated()) { - // There will be no header guard, so this always has to be inline. - GenerateSingularFieldHasBits(field, vars, printer); - } - // vars needed for clear_(), which is in the dependent base: - // (See also GenerateDependentFieldAccessorDeclarations.) - vars["tmpl"] = "template<class T>\n"; - vars["dependent_classname"] = - DependentBaseClassTemplateName(descriptor_) + "<T>"; - vars["this_message"] = DependentBaseDownCast(); - vars["this_const_message"] = DependentBaseConstDownCast(); - GenerateFieldClear(field, vars, printer); - } - // Generate type-specific accessors. field_generators_.get(field) .GenerateDependentInlineAccessorDefinitions(printer); @@ -798,7 +667,7 @@ GenerateDependentFieldAccessorDefinitions(io::Printer* printer) { // Generate has_$name$() and clear_has_$name$() functions for oneofs // Similar to other has-bits, these must always be in the header if we // are using a dependent base class. - GenerateOneofHasBits(printer, true /* is_inline */); + GenerateOneofHasBits(printer); } void MessageGenerator:: @@ -808,8 +677,7 @@ GenerateSingularFieldHasBits(const FieldDescriptor* field, if (field->options().weak()) { printer->Print( vars, - "$inline$" - "bool $classname$::has_$name$() const {\n" + "inline bool $classname$::has_$name$() const {\n" " return _weak_field_map_.Has($number$);\n" "}\n"); return; @@ -824,16 +692,13 @@ GenerateSingularFieldHasBits(const FieldDescriptor* field, vars["has_mask"] = StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); 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"); } else { @@ -842,15 +707,13 @@ GenerateSingularFieldHasBits(const FieldDescriptor* field, 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 this != internal_default_instance() && $name$_ != NULL;\n" "}\n"); } @@ -859,7 +722,7 @@ GenerateSingularFieldHasBits(const FieldDescriptor* field, } void MessageGenerator:: -GenerateOneofHasBits(io::Printer* printer, bool is_inline) { +GenerateOneofHasBits(io::Printer* printer) { for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { std::map<string, string> vars; vars["oneof_name"] = descriptor_->oneof_decl(i)->name(); @@ -867,15 +730,12 @@ GenerateOneofHasBits(io::Printer* printer, bool is_inline) { 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"); } @@ -892,13 +752,11 @@ GenerateOneofMemberHasBits(const FieldDescriptor* field, // method, so that generated code is slightly cleaner (vs. comparing // _oneof_case_[index] against a constant everywhere). 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"); } @@ -906,14 +764,14 @@ GenerateOneofMemberHasBits(const FieldDescriptor* field, void MessageGenerator:: GenerateFieldClear(const FieldDescriptor* field, const std::map<string, string>& vars, + bool is_inline, io::Printer* printer) { - // Generate clear_$name$() (See GenerateFieldAccessorDeclarations and - // GenerateDependentFieldAccessorDeclarations, $dependent_classname$ is - // set by the Generate*Definitions functions.) + // Generate clear_$name$(). + if (is_inline) { + printer->Print("inline "); + } printer->Print(vars, - "$tmpl$" - "$inline$" - "void $dependent_classname$::clear_$name$() {\n"); + "void $classname$::clear_$name$() {\n"); printer->Indent(); @@ -921,12 +779,12 @@ GenerateFieldClear(const FieldDescriptor* field, // Clear this field only if it is the active field in this oneof, // otherwise ignore printer->Print(vars, - "if ($this_message$has_$name$()) {\n"); + "if (has_$name$()) {\n"); printer->Indent(); field_generators_.get(field) .GenerateClearingCode(printer); printer->Print(vars, - "$this_message$clear_has_$oneof_name$();\n"); + "clear_has_$oneof_name$();\n"); printer->Outdent(); printer->Print("}\n"); } else { @@ -934,8 +792,7 @@ GenerateFieldClear(const FieldDescriptor* field, .GenerateClearingCode(printer); if (HasFieldPresence(descriptor_->file())) { if (!field->is_repeated() && !field->options().weak()) { - printer->Print(vars, - "$this_message$clear_has_$name$();\n"); + printer->Print(vars, "clear_has_$name$();\n"); } } } @@ -945,7 +802,7 @@ GenerateFieldClear(const FieldDescriptor* field, } void MessageGenerator:: -GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) { +GenerateFieldAccessorDefinitions(io::Printer* printer) { printer->Print("// $classname$\n\n", "classname", classname_); for (int i = 0; i < descriptor_->field_count(); i++) { @@ -955,7 +812,6 @@ GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) { std::map<string, string> vars; SetCommonFieldVariables(field, &vars, options_); - vars["inline"] = is_inline ? "inline " : ""; if (use_dependent_base_ && IsFieldDependent(field)) { vars["tmpl"] = "template<class T>\n"; vars["dependent_classname"] = @@ -972,31 +828,25 @@ GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_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()) { vars["field_name"] = UnderscoresToCamelCase(field->name(), true); vars["oneof_name"] = field->containing_oneof()->name(); vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index()); - if (!use_dependent_base_ || !IsFieldDependent(field)) { - GenerateOneofMemberHasBits(field, vars, printer); - } + GenerateOneofMemberHasBits(field, vars, printer); } else { // Singular field. - if (!use_dependent_base_ || !IsFieldDependent(field)) { - GenerateSingularFieldHasBits(field, vars, printer); - } + GenerateSingularFieldHasBits(field, vars, printer); } - if (!use_dependent_base_ || !IsFieldDependent(field)) { - GenerateFieldClear(field, vars, printer); + if (!IsCrossFileMaybeMap(field)) { + GenerateFieldClear(field, vars, true, printer); } // Generate type-specific accessors. - field_generators_.get(field).GenerateInlineAccessorDefinitions(printer, - is_inline); + field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); printer->Print("\n"); } @@ -1005,7 +855,7 @@ GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) { // Generate has_$name$() and clear_has_$name$() functions for oneofs // If we aren't using a dependent base, they can be with the other functions // that are #ifdef-guarded. - GenerateOneofHasBits(printer, is_inline); + GenerateOneofHasBits(printer); } } @@ -1041,7 +891,42 @@ GenerateDependentBaseClassDefinition(io::Printer* printer) { void MessageGenerator:: GenerateClassDefinition(io::Printer* printer) { - if (IsMapEntryMessage(descriptor_)) return; + if (IsMapEntryMessage(descriptor_)) { + std::map<string, string> vars; + vars["classname"] = classname_; + CollectMapInfo(descriptor_, &vars); + vars["lite"] = + HasDescriptorMethods(descriptor_->file(), options_) ? "" : "Lite"; + printer->Print( + vars, + "class $classname$ : public " + "::google::protobuf::internal::MapEntry$lite$<$classname$, \n" + " $key_cpp$, $val_cpp$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ > {\n" + "public:\n" + " typedef ::google::protobuf::internal::MapEntry$lite$<$classname$, \n" + " $key_cpp$, $val_cpp$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ > SuperType;\n" + " $classname$();\n" + " $classname$(::google::protobuf::Arena* arena);\n" + " void MergeFrom(const $classname$& other);\n" + " static const $classname$* internal_default_instance() { return " + "reinterpret_cast<const " + "$classname$*>(&_$classname$_default_instance_); }\n"); + if (HasDescriptorMethods(descriptor_->file(), options_)) { + printer->Print( + " void MergeFrom(const ::google::protobuf::Message& other) PROTOBUF_FINAL;\n" + " ::google::protobuf::Metadata GetMetadata() const;\n" + "};\n"); + } else { + printer->Print("};\n"); + } + return; + } if (use_dependent_base_) { GenerateDependentBaseClassDefinition(printer); printer->Print("\n"); @@ -1074,55 +959,54 @@ GenerateClassDefinition(io::Printer* printer) { printer->Print(" public:\n"); printer->Indent(); + printer->Print( + vars, + "$classname$();\n" + "virtual ~$classname$();\n" + "\n" + "$classname$(const $classname$& from);\n" + "\n" + "inline $classname$& operator=(const $classname$& from) {\n" + " CopyFrom(from);\n" + " return *this;\n" + "}\n"); + + if (options_.table_driven_serialization) { + printer->Print( + "private:\n" + "const void* InternalGetTable() const;\n" + "public:\n" + "\n"); + } + + // Generate move constructor and move assignment operator. printer->Print(vars, - "$classname$();\n" - "virtual ~$classname$();\n" - "\n" - "$classname$(const $classname$& from);\n" + "#if LANG_CXX11\n" + "$classname$($classname$&& from) noexcept\n" + " : $classname$() {\n" + " *this = ::std::move(from);\n" + "}\n" "\n" - "inline $classname$& operator=(const $classname$& from) {\n" - " CopyFrom(from);\n" + "inline $classname$& operator=($classname$&& from) noexcept {\n" + " if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {\n" + " if (this != &from) InternalSwap(&from);\n" + " } else {\n" + " CopyFrom(from);\n" + " }\n" " return *this;\n" "}\n" - "\n"); + "#endif\n"); - // Generate move constructor and move assignment operator for types other than - // Any. - #ifdef PROTO_EXPERIMENTAL_ENABLE_MOVE - if (!IsAnyMessage(descriptor_)) { + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + if (PublicUnknownFieldsAccessors(descriptor_)) { printer->Print(vars, - "#if LANG_CXX11\n" - "$classname$($classname$&& from)\n" - " : $classname$() {\n" - " *this = ::std::move(from);\n" - "}\n" - "\n" - "inline $classname$& operator=($classname$&& from) {\n" - " if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {\n" - " InternalSwap(&from);\n" - " } else {\n" - " CopyFrom(from);\n" - " }\n" - " return *this;\n" - "}\n" - "#endif\n"); - } - #endif - - if (PreserveUnknownFields(descriptor_)) { - string type = UseUnknownFieldSet(descriptor_->file(), options_) - ? "::google::protobuf::UnknownFieldSet" - : "::std::string"; - printer->Print( - "inline const $type$& unknown_fields() const {\n" - " return _internal_metadata_.unknown_fields();\n" - "}\n" - "\n" - "inline $type$* mutable_unknown_fields() {\n" - " return _internal_metadata_.mutable_unknown_fields();\n" - "}\n" - "\n", - "type", type ); + "inline const $unknown_fields_type$& unknown_fields() const {\n" + " return $unknown_fields$;\n" + "}\n" + "inline $unknown_fields_type$* mutable_unknown_fields() {\n" + " return $mutable_unknown_fields$;\n" + "}\n" + "\n"); } // N.B.: We exclude GetArena() when arena support is disabled, falling back on @@ -1182,6 +1066,7 @@ GenerateClassDefinition(io::Printer* printer) { vars["message_index"] = SimpleItoa(index_in_file_messages_); printer->Print( vars, + "static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY\n" "static inline const $classname$* internal_default_instance() {\n" " return reinterpret_cast<const $classname$*>(\n" " &_$classname$_default_instance_);\n" @@ -1190,7 +1075,6 @@ GenerateClassDefinition(io::Printer* printer) { " $message_index$;\n" "\n"); - if (SupportsArenas(descriptor_)) { printer->Print(vars, "void UnsafeArenaSwap($classname$* other);\n"); @@ -1212,14 +1096,22 @@ GenerateClassDefinition(io::Printer* printer) { vars["new_final"] = " PROTOBUF_FINAL"; + vars["create_func"] = MessageCreateFunction(descriptor_); printer->Print(vars, "void Swap($classname$* other);\n" + "friend void swap($classname$& a, $classname$& b) {\n" + " a.Swap(&b);\n" + "}\n" "\n" "// implements Message ----------------------------------------------\n" "\n" - "inline $classname$* New() const$new_final$ { return New(NULL); }\n" + "inline $classname$* New() const$new_final$ {\n" + " return ::google::protobuf::Arena::$create_func$<$classname$>(NULL);\n" + "}\n" "\n" - "$classname$* New(::google::protobuf::Arena* arena) const$new_final$;\n"); + "$classname$* New(::google::protobuf::Arena* arena) const$new_final$ {\n" + " return ::google::protobuf::Arena::$create_func$<$classname$>(arena);\n" + "}\n"); // For instances that derive from Message (rather than MessageLite), some // methods are virtual and should be marked as final. @@ -1250,9 +1142,14 @@ GenerateClassDefinition(io::Printer* printer) { "\n" "size_t ByteSizeLong() const PROTOBUF_FINAL;\n" "bool MergePartialFromCodedStream(\n" - " ::google::protobuf::io::CodedInputStream* input)$merge_partial_final$;\n" - "void SerializeWithCachedSizes(\n" - " ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;\n"); + " ::google::protobuf::io::CodedInputStream* input)$merge_partial_final$;\n"); + if (!options_.table_driven_serialization || + descriptor_->options().message_set_wire_format()) { + printer->Print( + "void SerializeWithCachedSizes(\n" + " ::google::protobuf::io::CodedOutputStream* output) const " + "PROTOBUF_FINAL;\n"); + } // DiscardUnknownFields() is implemented in message.cc using reflections. We // need to implement this function in generated code for messages. if (!UseUnknownFieldSet(descriptor_->file(), options_)) { @@ -1278,6 +1175,9 @@ GenerateClassDefinition(io::Printer* printer) { "final", use_final); if (SupportsArenas(descriptor_)) { printer->Print( + // TODO(gerbens) Make this private! Currently people are deriving from + // protos to give access to this constructor, breaking the invariants + // we rely on. "protected:\n" "explicit $classname$(::google::protobuf::Arena* arena);\n" "private:\n" @@ -1331,6 +1231,8 @@ GenerateClassDefinition(io::Printer* printer) { printer->Print("typedef $nested_full_name$ $nested_name$;\n", "nested_name", nested_type->name(), "nested_full_name", ClassName(nested_type, false)); + printer->Annotate("nested_full_name", nested_type); + printer->Annotate("nested_name", nested_type); } } @@ -1443,7 +1345,7 @@ GenerateClassDefinition(io::Printer* printer) { if (SupportsArenas(descriptor_)) { printer->Print( - "friend class ::google::protobuf::Arena;\n" + "template <typename T> friend class ::google::protobuf::Arena::InternalHelper;\n" "typedef void InternalArenaConstructable_;\n" "typedef void DestructorSkippable_;\n"); } @@ -1521,14 +1423,13 @@ GenerateClassDefinition(io::Printer* printer) { // The TableStruct struct needs access to the private parts, in order to // construct the offsets of all members. - // - // Some InitDefault and Shutdown are defined as static member functions of - // TableStruct such that they are also allowed to access private members. + // TODO(gerbens) Remove the friend for InitDefaults. printer->Print( - "friend struct $file_namespace$::TableStruct;\n", + "friend struct ::$file_namespace$::TableStruct;\n" + "friend void ::$file_namespace$::InitDefaults$scc_name$Impl();\n", // Vars. - "file_namespace", - FileLevelNamespace(descriptor_->file()->name())); + "scc_name", scc_name_, "file_namespace", + FileLevelNamespace(descriptor_)); printer->Outdent(); printer->Print("};"); @@ -1548,9 +1449,9 @@ GenerateDependentInlineMethods(io::Printer* printer) { } void MessageGenerator:: -GenerateInlineMethods(io::Printer* printer, bool is_inline) { +GenerateInlineMethods(io::Printer* printer) { if (IsMapEntryMessage(descriptor_)) return; - GenerateFieldAccessorDefinitions(printer, is_inline); + GenerateFieldAccessorDefinitions(printer); // Generate oneof_case() functions. for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { @@ -1560,11 +1461,9 @@ GenerateInlineMethods(io::Printer* printer, bool is_inline) { 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" @@ -1577,7 +1476,6 @@ GenerateExtraDefaultFields(io::Printer* printer) { // Generate oneof default instance and weak field instances for reflection // usage. if (descriptor_->oneof_decl_count() > 0 || num_weak_fields_ > 0) { - printer->Print("public:\n"); for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); @@ -1602,13 +1500,14 @@ GenerateExtraDefaultFields(io::Printer* printer) { bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, size_t aux_offset) { if (!table_driven_) { - printer->Print("{ NULL, NULL, 0, -1, -1, false },\n"); + printer->Print("{ NULL, NULL, 0, -1, -1, -1, -1, NULL, false },\n"); return false; } std::map<string, string> vars; - vars["classname"] = classname_; + vars["classname"] = ClassName(descriptor_); + vars["classtype"] = QualifiedClassName(descriptor_); vars["offset"] = SimpleItoa(offset); vars["aux_offset"] = SimpleItoa(aux_offset); @@ -1635,13 +1534,34 @@ bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, printer->Print(vars, "-1,\n"); } else { printer->Print(vars, - "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" - " $classname$, _has_bits_),\n"); + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" + " $classtype$, _has_bits_),\n"); } + if (descriptor_->oneof_decl_count() > 0) { + printer->Print(vars, + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" + " $classtype$, _oneof_case_),\n"); + } else { + printer->Print("-1, // no _oneof_case_\n"); + } + + if (descriptor_->extension_range_count() > 0) { + printer->Print(vars, + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classtype$, " + "_extensions_),\n"); + } else { + printer->Print("-1, // no _extensions_\n"); + } + + // TODO(ckennelly): Consolidate this with the calculation for + // AuxillaryParseTableField. + vars["ns"] = Namespace(descriptor_); + printer->Print(vars, - "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" - " $classname$, _internal_metadata_),\n"); + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" + " $classtype$, _internal_metadata_),\n" + "&$ns$::_$classname$_default_instance_,\n"); if (UseUnknownFieldSet(descriptor_->file(), options_)) { printer->Print(vars, "true,\n"); @@ -1656,48 +1576,255 @@ bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, void MessageGenerator::GenerateSchema(io::Printer* printer, int offset, int has_offset) { - if (IsMapEntryMessage(descriptor_)) return; - std::map<string, string> vars; - vars["classname"] = classname_; + vars["classname"] = QualifiedClassName(descriptor_); vars["offset"] = SimpleItoa(offset); - vars["has_bits_offsets"] = HasFieldPresence(descriptor_->file()) - ? SimpleItoa(offset + has_offset) - : "-1"; + vars["has_bits_offsets"] = + HasFieldPresence(descriptor_->file()) || IsMapEntryMessage(descriptor_) + ? SimpleItoa(offset + has_offset) + : "-1"; printer->Print(vars, "{ $offset$, $has_bits_offsets$, sizeof($classname$)},\n"); } -void MessageGenerator:: -GenerateDefaultInstanceAllocator(io::Printer* printer) { - // Construct the default instances of all fields, as they will be used - // when creating the default instance of the entire message. +namespace { + +// TODO(gerbens) remove this after the next sync with GitHub code base. +// Then the opensource testing has gained the functionality to compile +// the CalcFieldNum given the symbols defined in generated-message-util. +#ifdef OPENSOURCE_PROTOBUF_CPP_BOOTSTRAP +// We need a clean version of CalcFieldNum that doesn't use new functionality +// in the runtime, because this functionality is not yet in the opensource +// runtime + +uint32 CalculateType(uint32 type, uint32 type_class) { + return (type - 1) + type_class * 20; +} + +uint32 CalcFieldNum(const FieldDescriptor* field, const Options& options) { + bool is_a_map = IsMapEntryMessage(field->containing_type()); + int type = field->type(); + if (field->containing_oneof()) { + return CalculateType(type, 4); + } + if (field->is_packed()) { + return CalculateType(type, 3); + } else if (field->is_repeated()) { + return CalculateType(type, 2); + } else if (!HasFieldPresence(field->file()) && + field->containing_oneof() == NULL && !is_a_map) { + return CalculateType(type, 1); + } else { + return CalculateType(type, 0); + } +} + +#else +// We need to calculate for each field what function the table driven code +// should use to serialize it. This returns the index in a lookup table. +uint32 CalcFieldNum(const FieldDescriptor* field, const Options& options) { + bool is_a_map = IsMapEntryMessage(field->containing_type()); + int type = field->type(); + if (field->containing_oneof()) { + return internal::FieldMetadata::CalculateType( + type, internal::FieldMetadata::kOneOf); + } + if (field->is_packed()) { + return internal::FieldMetadata::CalculateType( + type, internal::FieldMetadata::kPacked); + } else if (field->is_repeated()) { + return internal::FieldMetadata::CalculateType( + type, internal::FieldMetadata::kRepeated); + } else if (!HasFieldPresence(field->file()) && + field->containing_oneof() == NULL && !is_a_map) { + return internal::FieldMetadata::CalculateType( + type, internal::FieldMetadata::kNoPresence); + } else { + return internal::FieldMetadata::CalculateType( + type, internal::FieldMetadata::kPresence); + } +} +#endif + +int FindMessageIndexInFile(const Descriptor* descriptor) { + std::vector<const Descriptor*> flatten = + FlattenMessagesInFile(descriptor->file()); + return std::find(flatten.begin(), flatten.end(), descriptor) - + flatten.begin(); +} + +} // namespace + +int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { + if (!options_.table_driven_serialization) { + return 0; + } + + string full_classname = QualifiedClassName(descriptor_); + + std::vector<const FieldDescriptor*> sorted = SortFieldsByNumber(descriptor_); + if (IsMapEntryMessage(descriptor_)) { + for (int i = 0; i < 2; i++) { + const FieldDescriptor* field = sorted[i]; + uint32 tag = internal::WireFormatLite::MakeTag( + field->number(), WireFormat::WireTypeForFieldType(field->type())); + + std::map<string, string> vars; + vars["classname"] = QualifiedClassName(descriptor_); + vars["field_name"] = FieldName(field); + vars["tag"] = SimpleItoa(tag); + vars["hasbit"] = SimpleItoa(i); + vars["type"] = SimpleItoa(CalcFieldNum(field, options_)); + vars["ptr"] = "NULL"; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + GOOGLE_CHECK(!IsMapEntryMessage(field->message_type())); + { + vars["ptr"] = + "::" + FileLevelNamespace(field->message_type()) + + "::TableStruct::serialization_table + " + + SimpleItoa(FindMessageIndexInFile(field->message_type())); + } + } + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" + "::google::protobuf::internal::MapEntryHelper<$classname$::" + "SuperType>, $field_name$_), $tag$," + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" + "::google::protobuf::internal::MapEntryHelper<$classname$::" + "SuperType>, _has_bits_) * 8 + $hasbit$, $type$, " + "$ptr$},\n"); + } + return 2; + } + printer->Print( + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " + "_cached_size_), 0, 0, 0, NULL},\n", + "classname", full_classname); + std::vector<const Descriptor::ExtensionRange*> sorted_extensions; + for (int i = 0; i < descriptor_->extension_range_count(); ++i) { + sorted_extensions.push_back(descriptor_->extension_range(i)); + } + std::sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeSorter()); + for (int i = 0, extension_idx = 0; /* no range */; i++) { + for (; extension_idx < sorted_extensions.size() && + (i == sorted.size() || + sorted_extensions[extension_idx]->start < sorted[i]->number()); + extension_idx++) { + const Descriptor::ExtensionRange* range = + sorted_extensions[extension_idx]; + printer->Print( + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " + "_extensions_), $start$, $end$, " + "::google::protobuf::internal::FieldMetadata::kSpecial, " + "reinterpret_cast<const " + "void*>(::google::protobuf::internal::ExtensionSerializer)},\n", + "classname", full_classname, "start", SimpleItoa(range->start), "end", + SimpleItoa(range->end)); + } + if (i == sorted.size()) break; + const FieldDescriptor* field = sorted[i]; + + uint32 tag = internal::WireFormatLite::MakeTag( + field->number(), WireFormat::WireTypeForFieldType(field->type())); + if (field->is_packed()) { + tag = internal::WireFormatLite::MakeTag( + field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + } + + string classfieldname = FieldName(field); + if (field->containing_oneof()) { + classfieldname = field->containing_oneof()->name(); + } + std::map<string, string> vars; + vars["classname"] = full_classname; + vars["field_name"] = classfieldname; + vars["tag"] = SimpleItoa(tag); + vars["ptr"] = "NULL"; + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (IsMapEntryMessage(field->message_type())) { + vars["idx"] = SimpleItoa(FindMessageIndexInFile(field->message_type())); + vars["fieldclassname"] = QualifiedClassName(field->message_type()); + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, $field_name$_), $tag$, $idx$, " + "::google::protobuf::internal::FieldMetadata::kSpecial, " + "reinterpret_cast<const void*>(static_cast< " + "::google::protobuf::internal::SpecialSerializer>(" + "::google::protobuf::internal::MapFieldSerializer< " + "::google::protobuf::internal::MapEntryToMapField<" + "$fieldclassname$>::MapFieldType, " + "TableStruct::serialization_table>))},\n"); + continue; + } else { + vars["ptr"] = + "::" + FileLevelNamespace(field->message_type()) + + "::TableStruct::serialization_table + " + + SimpleItoa(FindMessageIndexInFile(field->message_type())); + } + } + vars["type"] = SimpleItoa(CalcFieldNum(field, options_)); + + + if (field->options().weak()) { + // TODO(gerbens) merge weak fields into ranges + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, _weak_field_map_), $tag$, $tag$, " + "::google::protobuf::internal::FieldMetadata::kSpecial, " + "reinterpret_cast<const " + "void*>(::google::protobuf::internal::WeakFieldSerializer)},\n"); + } else if (field->containing_oneof()) { + vars["oneofoffset"] = + SimpleItoa(sizeof(uint32) * field->containing_oneof()->index()); + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, $field_name$_), $tag$, " + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, _oneof_case_) + $oneofoffset$, " + "$type$, $ptr$},\n"); + } else if (HasFieldPresence(descriptor_->file()) && + has_bit_indices_[field->index()] != -1) { + vars["hasbitsoffset"] = SimpleItoa(has_bit_indices_[field->index()]); + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, $field_name$_), $tag$, " + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, _has_bits_) * 8 + $hasbitsoffset$, $type$, " + "$ptr$},\n"); + } else { + printer->Print(vars, + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($" + "classname$, $field_name$_), $tag$, ~0u, $type$, " + "$ptr$},\n"); + } + } + int num_field_metadata = 1 + sorted.size() + sorted_extensions.size(); + num_field_metadata++; + string serializer = UseUnknownFieldSet(descriptor_->file(), options_) + ? "::google::protobuf::internal::UnknownFieldSetSerializer" + : "::google::protobuf::internal::UnknownFieldSerializerLite"; + printer->Print( + "{GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " + "_internal_metadata_), 0, ~0u, " + "::google::protobuf::internal::FieldMetadata::kSpecial, reinterpret_cast<const " + "void*>($serializer$)},\n", + "classname", full_classname, "serializer", serializer); + return num_field_metadata; +} + +void MessageGenerator::GenerateFieldDefaultInstances(io::Printer* printer) { + // Construct the default instances for all fields that need one. for (int i = 0; i < descriptor_->field_count(); i++) { field_generators_.get(descriptor_->field(i)) .GenerateDefaultInstanceAllocator(printer); } - - // Construct the default instance. We can't call InitAsDefaultInstance() yet - // because we need to make sure all default instances that this one might - // depend on are constructed first. - printer->Print("_$classname$_default_instance_.DefaultConstruct();\n", - "classname", classname_); } void MessageGenerator:: GenerateDefaultInstanceInitializer(io::Printer* printer) { - if (IsMapEntryMessage(descriptor_)) { - printer->Print( - "_$classname$_default_instance_.get_mutable()->set_default_instance(_$" - "classname$_default_instance_.get_mutable());\n" - "_$classname$_default_instance_.get_mutable()->InitAsDefaultInstance();" - "\n", - "classname", classname_); - return; - } - // The default instance needs all of its embedded message pointers // cross-linked to other default instances. We can't do this initialization // in the constructor because some other default instances may not have been @@ -1715,14 +1842,16 @@ GenerateDefaultInstanceInitializer(io::Printer* printer) { if (field->containing_oneof() || field->options().weak()) { name = "_" + classname_ + "_default_instance_."; } else { - name = "_" + classname_ + "_default_instance_.get_mutable()->"; + name = + "_" + classname_ + "_default_instance_._instance.get_mutable()->"; } name += FieldName(field); printer->Print( - "$name$_ = const_cast< $type$*>(\n" + "$ns$::$name$_ = const_cast< $type$*>(\n" " $type$::internal_default_instance());\n", // Vars. - "name", name, "type", FieldMessageTypeName(field)); + "name", name, "type", FieldMessageTypeName(field), "ns", + Namespace(descriptor_)); } else if (field->containing_oneof() && HasDescriptorMethods(descriptor_->file(), options_)) { field_generators_.get(descriptor_->field(i)) @@ -1732,52 +1861,43 @@ GenerateDefaultInstanceInitializer(io::Printer* printer) { } void MessageGenerator:: -GenerateShutdownCode(io::Printer* printer) { - if (IsMapEntryMessage(descriptor_)) return; - - printer->Print("_$classname$_default_instance_.Shutdown();\n", "classname", - classname_); - - if (HasDescriptorMethods(descriptor_->file(), options_)) { - printer->Print("delete file_level_metadata[$index$].reflection;\n", "index", - SimpleItoa(index_in_file_messages_)); - } - - // Handle default instances of fields. - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GenerateShutdownCode(printer); - } -} - -void MessageGenerator:: GenerateClassMethods(io::Printer* printer) { if (IsMapEntryMessage(descriptor_)) { + printer->Print( + "$classname$::$classname$() {}\n" + "$classname$::$classname$(::google::protobuf::Arena* arena) : " + "SuperType(arena) {}\n" + "void $classname$::MergeFrom(const $classname$& other) {\n" + " MergeFromInternal(other);\n" + "}\n", + "classname", classname_); if (HasDescriptorMethods(descriptor_->file(), options_)) { printer->Print( - "$parent$::$classname$::$classname$() {}\n" - "$parent$::$classname$::$classname$(::google::protobuf::Arena* arena) : " - "SuperType(arena) {}\n" - "::google::protobuf::Metadata $parent$::$classname$::GetMetadata() const {\n" - " $file_namespace$::protobuf_AssignDescriptorsOnce();\n" - " return $file_namespace$::file_level_metadata[$index$];\n" + "::google::protobuf::Metadata $classname$::GetMetadata() const {\n" + " ::$file_namespace$::protobuf_AssignDescriptorsOnce();\n" + " return ::$file_namespace$::file_level_metadata[$index$];\n" "}\n" - "void $parent$::$classname$::MergeFrom(\n" + "void $classname$::MergeFrom(\n" " const ::google::protobuf::Message& other) {\n" " ::google::protobuf::Message::MergeFrom(other);\n" "}\n" - "void $parent$::$classname$::MergeFrom(const $classname$& other) {\n" - " MergeFromInternal(other);\n" - "}\n" "\n", - "file_namespace", FileLevelNamespace(descriptor_->file()->name()), - "parent", ClassName(descriptor_->containing_type(), false), + "file_namespace", FileLevelNamespace(descriptor_), "classname", classname_, "index", SimpleItoa(index_in_file_messages_)); } return; } + // TODO(gerbens) Remove this function. With a little bit of cleanup and + // refactoring this is superfluous. + printer->Print("void $classname$::InitAsDefaultInstance() {\n", "classname", + classname_); + printer->Indent(); + GenerateDefaultInstanceInitializer(printer); + printer->Outdent(); + printer->Print("}\n"); + if (IsAnyMessage(descriptor_)) { printer->Print( "void $classname$::PackFrom(const ::google::protobuf::Message& message) {\n" @@ -1798,8 +1918,17 @@ GenerateClassMethods(io::Printer* printer) { // Generate non-inline field definitions. for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) + const FieldDescriptor* field = descriptor_->field(i); + field_generators_.get(field) .GenerateNonInlineAccessorDefinitions(printer); + if (IsCrossFileMaybeMap(field)) { + std::map<string, string> vars; + SetCommonFieldVariables(field, &vars, options_); + if (field->containing_oneof()) { + SetCommonOneofFieldVariables(field, &vars); + } + GenerateFieldClear(field, vars, false, printer); + } } // Generate field number constants. @@ -1854,16 +1983,26 @@ GenerateClassMethods(io::Printer* printer) { GenerateSwap(printer); printer->Print("\n"); + if (options_.table_driven_serialization) { + printer->Print( + "const void* $classname$::InternalGetTable() const {\n" + " return ::$file_namespace$::TableStruct::serialization_table + " + "$index$;\n" + "}\n" + "\n", + "classname", classname_, "index", SimpleItoa(index_in_file_messages_), + "file_namespace", FileLevelNamespace(descriptor_)); + } if (HasDescriptorMethods(descriptor_->file(), options_)) { printer->Print( "::google::protobuf::Metadata $classname$::GetMetadata() const {\n" " $file_namespace$::protobuf_AssignDescriptorsOnce();\n" - " return " + " return ::" "$file_namespace$::file_level_metadata[kIndexInFileMessages];\n" "}\n" "\n", "classname", classname_, "file_namespace", - FileLevelNamespace(descriptor_->file()->name())); + FileLevelNamespace(descriptor_)); } else { printer->Print( "::std::string $classname$::GetTypeName() const {\n" @@ -1926,13 +2065,25 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { processing_type |= static_cast<unsigned>( field->is_repeated() ? internal::kRepeatedMask : 0); + processing_type |= static_cast<unsigned>( + field->containing_oneof() ? internal::kOneofMask : 0); + + if (field->is_map()) { + processing_type = internal::TYPE_MAP; + } + const unsigned char tag_size = WireFormat::TagSize(field->number(), field->type()); std::map<string, string> vars; - vars["classname"] = classname_; - vars["name"] = FieldName(field); - vars["has"] = SimpleItoa(has_bit_indices_[field->index()]); + vars["classname"] = QualifiedClassName(descriptor_); + if (field->containing_oneof() != NULL) { + vars["name"] = field->containing_oneof()->name(); + vars["presence"] = SimpleItoa(field->containing_oneof()->index()); + } else { + vars["name"] = FieldName(field); + vars["presence"] = SimpleItoa(has_bit_indices_[field->index()]); + } vars["nwtype"] = SimpleItoa(normal_wiretype); vars["pwtype"] = SimpleItoa(packed_wiretype); vars["ptype"] = SimpleItoa(processing_type); @@ -1942,7 +2093,7 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { "{\n" " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" " $classname$, $name$_),\n" - " static_cast< ::google::protobuf::uint32>($has$),\n" + " static_cast< ::google::protobuf::uint32>($presence$),\n" " $nwtype$, $pwtype$, $ptype$, $tag_size$\n" "},\n"); } @@ -1977,42 +2128,39 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { printer->Print( vars, "{::google::protobuf::internal::AuxillaryParseTableField::enum_aux{" - "$type$_IsValid, \"$type$\" }},\n"); + "$type$_IsValid}},\n"); last_field_number++; break; case FieldDescriptor::CPPTYPE_MESSAGE: { - std::vector<string> package_parts; - - const Descriptor* outer = field->message_type(); - while (outer->containing_type() != NULL) { - outer = outer->containing_type(); + if (field->is_map()) { + vars["classname"] = QualifiedClassName(field->message_type()); + printer->Print(vars, + "{::google::protobuf::internal::AuxillaryParseTableField::map_" + "aux{&::google::protobuf::internal::ParseMap<$classname$>}},\n"); + last_field_number++; + break; + } else { + vars["classname"] = ClassName(field->message_type(), false); } - - package_parts = Split( - outer->full_name(), ".", true); - // outer->full_name() contains the class itself. Remove it as it is - // used in the name of the default instance variable. - GOOGLE_DCHECK_NE(package_parts.size(), 0); - package_parts.back().clear(); - - vars["classname"] = ClassName(field->message_type(), false); - vars["ns"] = Join(package_parts, "::"); + vars["ns"] = Namespace(field->message_type()); vars["type"] = FieldMessageTypeName(field); - vars["file_namespace"] = FileLevelNamespace(outer->file()->name()); + vars["file_namespace"] = + FileLevelNamespace(field->message_type()); - printer->Print(vars, + printer->Print( + vars, "{::google::protobuf::internal::AuxillaryParseTableField::message_aux{\n" - " &::$ns$_$classname$_default_instance_,\n"); + " &$ns$::_$classname$_default_instance_,\n"); bool dont_emit_table = - !TableDrivenEnabled(field->message_type(), options_); + !TableDrivenParsingEnabled(field->message_type(), options_); if (dont_emit_table) { printer->Print(" NULL,\n"); } else { printer->Print(vars, - " ::$ns$$file_namespace$::TableStruct::schema +\n" - " ::$ns$$classname$::kIndexInFileMessages,\n"); + " ::$file_namespace$::TableStruct::schema +\n" + " $ns$::$classname$::kIndexInFileMessages,\n"); } printer->Print("}},\n"); @@ -2024,8 +2172,9 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { case FieldOptions::STRING: vars["default"] = field->default_value_string().empty() - ? "&::google::protobuf::internal::fixed_address_empty_string" - : "&" + classname_ + "::_default_" + FieldName(field) + "_"; + ? "&::google::protobuf::internal::fixed_address_empty_string" + : "&" + Namespace(field) + " ::" + classname_ + + "::_default_" + FieldName(field) + "_"; break; case FieldOptions::CORD: case FieldOptions::STRING_PIECE: @@ -2034,16 +2183,10 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { break; } vars["full_name"] = field->full_name(); - vars["strict"] = - field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 - ? "true" : "false"; - vars["type"] = field->full_name(); printer->Print(vars, "{::google::protobuf::internal::AuxillaryParseTableField::string_aux{\n" " $default$,\n" - " \"$full_name$\",\n" - " $strict$,\n" - " \"$type$\"\n" + " \"$full_name$\"\n" "}},\n"); last_field_number++; break; @@ -2057,11 +2200,11 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { std::pair<size_t, size_t> MessageGenerator::GenerateOffsets( io::Printer* printer) { - if (IsMapEntryMessage(descriptor_)) return std::make_pair(0, 0); std::map<string, string> variables; - variables["classname"] = classname_; + string full_classname = QualifiedClassName(descriptor_); + variables["classname"] = full_classname; - if (HasFieldPresence(descriptor_->file())) { + if (HasFieldPresence(descriptor_->file()) || IsMapEntryMessage(descriptor_)) { printer->Print( variables, "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " @@ -2102,28 +2245,29 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets( for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); if (field->containing_oneof() || field->options().weak()) { - printer->Print( - "GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(" - "(&_$classname$_default_instance_), $name$_),\n", - "classname", classname_, "name", FieldName(field)); + printer->Print("offsetof($classname$DefaultTypeInternal, $name$_),\n", + "classname", full_classname, "name", FieldName(field)); } else { printer->Print( "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " - "$name$_),\n", - "classname", classname_, - "name", FieldName(field)); + "$name$_),\n", + "classname", full_classname, "name", FieldName(field)); } } for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { const OneofDescriptor* oneof = descriptor_->oneof_decl(i); printer->Print( - "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n", - "classname", classname_, - "name", oneof->name()); + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n", + "classname", full_classname, "name", oneof->name()); } - if (HasFieldPresence(descriptor_->file())) { + if (IsMapEntryMessage(descriptor_)) { + entries += 2; + printer->Print( + "0,\n" + "1,\n"); + } else if (HasFieldPresence(descriptor_->file())) { entries += has_bit_indices_.size(); for (int i = 0; i < has_bit_indices_.size(); i++) { const string index = has_bit_indices_[i] >= 0 ? @@ -2175,15 +2319,9 @@ GenerateSharedDestructorCode(io::Printer* printer) { "classname", classname_); printer->Indent(); if (SupportsArenas(descriptor_)) { - // Do nothing when the message is allocated in an arena. printer->Print( - "::google::protobuf::Arena* arena = GetArenaNoVirtual();\n" - "if (arena != NULL) {\n" - " return;\n" - "}\n" - "\n"); + "GOOGLE_DCHECK(GetArenaNoVirtual() == NULL);\n"); } - // Write the destructors for each field except oneof members. // optimized_order_ does not contain oneof fields. for (int i = 0; i < optimized_order_.size(); i++) { @@ -2308,12 +2446,13 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, if (copy_constructor) { pod_template = "::memcpy(&$first$_, &from.$first$_,\n" - " reinterpret_cast<char*>(&$last$_) -\n" - " reinterpret_cast<char*>(&$first$_) + sizeof($last$_));\n"; + " static_cast<size_t>(reinterpret_cast<char*>(&$last$_) -\n" + " reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n"; } else { pod_template = - "::memset(&$first$_, 0, reinterpret_cast<char*>(&$last$_) -\n" - " reinterpret_cast<char*>(&$first$_) + sizeof($last$_));\n"; + "::memset(&$first$_, 0, static_cast<size_t>(\n" + " reinterpret_cast<char*>(&$last$_) -\n" + " reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n"; } for (int i = 0; i < optimized_order_.size(); ++i) { @@ -2384,8 +2523,7 @@ GenerateStructors(io::Printer* printer) { initializer_with_arena += ", _weak_field_map_(arena)"; } - string initializer_null; - initializer_null = ", _internal_metadata_(NULL)"; + string initializer_null = superclass + "(), _internal_metadata_(NULL)"; if (IsAnyMessage(descriptor_)) { initializer_null += ", _any_metadata_(&type_url_, &value_)"; } @@ -2395,142 +2533,152 @@ GenerateStructors(io::Printer* printer) { printer->Print( "$classname$::$classname$()\n" - " : $superclass$()$initializer$ {\n" + " : $initializer$ {\n" " if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {\n" - " $file_namespace$::InitDefaults();\n" + " ::$file_namespace$::InitDefaults$scc_name$();\n" " }\n" " SharedCtor();\n" " // @@protoc_insertion_point(constructor:$full_name$)\n" "}\n", - "classname", classname_, "superclass", superclass, "full_name", - descriptor_->full_name(), "initializer", initializer_null, - "file_namespace", FileLevelNamespace(descriptor_->file()->name())); + "classname", classname_, "full_name", descriptor_->full_name(), + "scc_name", scc_name_, "initializer", initializer_null, "file_namespace", + FileLevelNamespace(descriptor_)); if (SupportsArenas(descriptor_)) { printer->Print( "$classname$::$classname$(::google::protobuf::Arena* arena)\n" " : $initializer$ {\n" - // When arenas are used it's safe to assume we have finished - // static init time (protos with arenas are unsafe during static init) - "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n" - " $file_namespace$::InitDefaults();\n" - "#endif // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n" + " ::$file_namespace$::InitDefaults$scc_name$();\n" " SharedCtor();\n" " RegisterArenaDtor(arena);\n" " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" "}\n", "initializer", initializer_with_arena, "classname", classname_, "superclass", superclass, "full_name", descriptor_->full_name(), - "file_namespace", FileLevelNamespace(descriptor_->file()->name())); + "scc_name", scc_name_, "file_namespace", + FileLevelNamespace(descriptor_)); } // Generate the copy constructor. - printer->Print( - "$classname$::$classname$(const $classname$& from)\n" - " : $superclass$()", - "classname", classname_, - "superclass", superclass, - "full_name", descriptor_->full_name()); - printer->Indent(); - printer->Indent(); - printer->Indent(); + if (UsingImplicitWeakFields(descriptor_->file(), options_)) { + // If we are in lite mode and using implicit weak fields, we generate a + // one-liner copy constructor that delegates to MergeFrom. This saves some + // code size and also cuts down on the complexity of implicit weak fields. + // We might eventually want to do this for all lite protos. + printer->Print( + "$classname$::$classname$(const $classname$& from)\n" + " : $classname$() {\n" + " MergeFrom(from);\n" + "}\n", + "classname", classname_); + } else { + printer->Print( + "$classname$::$classname$(const $classname$& from)\n" + " : $superclass$()", + "classname", classname_, + "superclass", superclass, + "full_name", descriptor_->full_name()); + printer->Indent(); + printer->Indent(); + printer->Indent(); - printer->Print( - ",\n_internal_metadata_(NULL)"); + printer->Print( + ",\n_internal_metadata_(NULL)"); - if (HasFieldPresence(descriptor_->file())) { - printer->Print(",\n_has_bits_(from._has_bits_)"); - } + if (HasFieldPresence(descriptor_->file())) { + printer->Print(",\n_has_bits_(from._has_bits_)"); + } - bool need_to_emit_cached_size = true; - const string cached_size_decl = ",\n_cached_size_(0)"; - // We reproduce the logic used for laying out _cached_sized_ in the class - // definition, as to initialize it in-order. - if (HasFieldPresence(descriptor_->file()) && - (HasBitsSize() % 8) != 0) { - printer->Print(cached_size_decl.c_str()); - need_to_emit_cached_size = false; - } + bool need_to_emit_cached_size = true; + const string cached_size_decl = ",\n_cached_size_(0)"; + // We reproduce the logic used for laying out _cached_sized_ in the class + // definition, as to initialize it in-order. + if (HasFieldPresence(descriptor_->file()) && + (HasBitsSize() % 8) != 0) { + printer->Print(cached_size_decl.c_str()); + need_to_emit_cached_size = false; + } - std::vector<bool> processed(optimized_order_.size(), false); - for (int i = 0; i < optimized_order_.size(); ++i) { - const FieldDescriptor* field = optimized_order_[i]; + std::vector<bool> processed(optimized_order_.size(), false); + for (int i = 0; i < optimized_order_.size(); ++i) { + const FieldDescriptor* field = optimized_order_[i]; - if (!(field->is_repeated() && !(field->is_map())) - ) { - continue; - } + if (!(field->is_repeated() && !(field->is_map())) + ) { + continue; + } - processed[i] = true; - printer->Print(",\n$name$_(from.$name$_)", - "name", FieldName(field)); - } + processed[i] = true; + printer->Print(",\n$name$_(from.$name$_)", + "name", FieldName(field)); + } - if (need_to_emit_cached_size) { - printer->Print(cached_size_decl.c_str()); - need_to_emit_cached_size = false; - } + if (need_to_emit_cached_size) { + printer->Print(cached_size_decl.c_str()); + need_to_emit_cached_size = false; + } - if (IsAnyMessage(descriptor_)) { - printer->Print(",\n_any_metadata_(&type_url_, &value_)"); - } - if (num_weak_fields_ > 0) { - printer->Print(",\n_weak_field_map_(from._weak_field_map_)"); - } + if (IsAnyMessage(descriptor_)) { + printer->Print(",\n_any_metadata_(&type_url_, &value_)"); + } + if (num_weak_fields_ > 0) { + printer->Print(",\n_weak_field_map_(from._weak_field_map_)"); + } - printer->Outdent(); - printer->Outdent(); - printer->Print(" {\n"); + printer->Outdent(); + printer->Outdent(); + printer->Print(" {\n"); - printer->Print( - "_internal_metadata_.MergeFrom(from._internal_metadata_);\n"); + printer->Print( + "_internal_metadata_.MergeFrom(from._internal_metadata_);\n"); - if (descriptor_->extension_range_count() > 0) { - printer->Print("_extensions_.MergeFrom(from._extensions_);\n"); - } + if (descriptor_->extension_range_count() > 0) { + printer->Print("_extensions_.MergeFrom(from._extensions_);\n"); + } - GenerateConstructorBody(printer, processed, true); + GenerateConstructorBody(printer, processed, true); - // Copy oneof fields. Oneof field requires oneof case check. - for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { - printer->Print( - "clear_has_$oneofname$();\n" - "switch (from.$oneofname$_case()) {\n", - "oneofname", descriptor_->oneof_decl(i)->name()); - printer->Indent(); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + // Copy oneof fields. Oneof field requires oneof case check. + for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { printer->Print( - "case k$field_name$: {\n", - "field_name", UnderscoresToCamelCase(field->name(), true)); + "clear_has_$oneofname$();\n" + "switch (from.$oneofname$_case()) {\n", + "oneofname", descriptor_->oneof_decl(i)->name()); printer->Indent(); - field_generators_.get(field).GenerateMergingCode(printer); + for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + printer->Print( + "case k$field_name$: {\n", + "field_name", UnderscoresToCamelCase(field->name(), true)); + printer->Indent(); + field_generators_.get(field).GenerateMergingCode(printer); + printer->Print( + "break;\n"); + printer->Outdent(); + printer->Print( + "}\n"); + } printer->Print( - "break;\n"); + "case $cap_oneof_name$_NOT_SET: {\n" + " break;\n" + "}\n", + "oneof_index", + SimpleItoa(descriptor_->oneof_decl(i)->index()), + "cap_oneof_name", + ToUpper(descriptor_->oneof_decl(i)->name())); printer->Outdent(); printer->Print( "}\n"); } - printer->Print( - "case $cap_oneof_name$_NOT_SET: {\n" - " break;\n" - "}\n", - "oneof_index", - SimpleItoa(descriptor_->oneof_decl(i)->index()), - "cap_oneof_name", - ToUpper(descriptor_->oneof_decl(i)->name())); + printer->Outdent(); printer->Print( - "}\n"); + " // @@protoc_insertion_point(copy_constructor:$full_name$)\n" + "}\n" + "\n", + "full_name", descriptor_->full_name()); } - printer->Outdent(); - printer->Print( - " // @@protoc_insertion_point(copy_constructor:$full_name$)\n" - "}\n" - "\n", - "full_name", descriptor_->full_name()); - // Generate the shared constructor code. GenerateSharedConstructorCode(printer); @@ -2566,42 +2714,34 @@ GenerateStructors(io::Printer* printer) { !descriptor_->options().no_standard_descriptor_accessor()) { printer->Print( "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n" - " $file_namespace$::protobuf_AssignDescriptorsOnce();\n" - " return " + " ::$file_namespace$::protobuf_AssignDescriptorsOnce();\n" + " return ::" "$file_namespace$::file_level_metadata[kIndexInFileMessages]." "descriptor;\n" "}\n" "\n", "classname", classname_, "file_namespace", - FileLevelNamespace(descriptor_->file()->name())); + FileLevelNamespace(descriptor_)); } printer->Print( "const $classname$& $classname$::default_instance() {\n" - " $file_namespace$::InitDefaults();\n" + " ::$file_namespace$::InitDefaults$scc_name$();\n" " return *internal_default_instance();\n" "}\n\n", - "classname", classname_, "file_namespace", - FileLevelNamespace(descriptor_->file()->name())); + "classname", classname_, "scc_name", scc_name_, "file_namespace", + FileLevelNamespace(descriptor_)); +} - if (SupportsArenas(descriptor_)) { - printer->Print( - "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n" - " return ::google::protobuf::Arena::CreateMessage<$classname$>(arena);\n" - "}\n", - "classname", classname_); - } else { - printer->Print( - "$classname$* $classname$::New(::google::protobuf::Arena* arena) const {\n" - " $classname$* n = new $classname$;\n" - " if (arena != NULL) {\n" - " arena->Own(n);\n" - " }\n" - " return n;\n" +void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) { + printer->Print( + "template<> " + "GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE " + "$classname$* Arena::$create_func$< $classname$ >(Arena* arena) {\n" + " return Arena::$create_func$Internal< $classname$ >(arena);\n" "}\n", - "classname", classname_); - } - + "classname", QualifiedClassName(descriptor_), + "create_func", MessageCreateFunction(descriptor_)); } // Return the number of bits set in n, a non-negative integer. @@ -2614,188 +2754,214 @@ static int popcnt(uint32 n) { return result; } +bool MessageGenerator::MaybeGenerateOptionalFieldCondition( + io::Printer* printer, const FieldDescriptor* field, + int expected_has_bits_index) { + int has_bit_index = has_bit_indices_[field->index()]; + if (!field->options().weak() && + expected_has_bits_index == has_bit_index / 32) { + const string mask = + StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); + printer->Print( + "if (cached_has_bits & 0x$mask$u) {\n", + "mask", mask); + return true; + } + return false; +} + void MessageGenerator:: GenerateClear(io::Printer* printer) { + // Performance tuning parameters + const int kMaxUnconditionalPrimitiveBytesClear = 4; + printer->Print( "void $classname$::Clear() {\n" "// @@protoc_insertion_point(message_clear_start:$full_name$)\n", "classname", classname_, "full_name", descriptor_->full_name()); printer->Indent(); + printer->Print( + // TODO(jwb): It would be better to avoid emitting this if it is not used, + // rather than emitting a workaround for the resulting warning. + "::google::protobuf::uint32 cached_has_bits = 0;\n" + "// Prevent compiler warnings about cached_has_bits being unused\n" + "(void) cached_has_bits;\n\n"); + + int cached_has_bit_index = -1; + // Step 1: Extensions if (descriptor_->extension_range_count() > 0) { printer->Print("_extensions_.Clear();\n"); } - int last_i = -1; - for (int i = 0; i < optimized_order_.size(); ) { - // Detect infinite loops. - GOOGLE_CHECK_NE(i, last_i); - last_i = i; - - // Step 2: Repeated fields don't use _has_bits_; emit code to clear them - // here. - for (; i < optimized_order_.size(); i++) { - const FieldDescriptor* field = optimized_order_[i]; - const FieldGenerator& generator = field_generators_.get(field); - - if (!field->is_repeated()) { - break; - } + int unconditional_budget = kMaxUnconditionalPrimitiveBytesClear; + for (int i = 0; i < optimized_order_.size(); i++) { + const FieldDescriptor* field = optimized_order_[i]; - if (use_dependent_base_ && IsFieldDependent(field)) { - printer->Print("clear_$name$();\n", "name", FieldName(field)); - } else { - generator.GenerateMessageClearingCode(printer); - } + if (!CanInitializeByZeroing(field)) { + continue; } - // Step 3: Greedily seek runs of fields that can be cleared by - // memset-to-0. - int last_chunk = -1; - int last_chunk_start = -1; - int last_chunk_end = -1; - uint32 last_chunk_mask = 0; + unconditional_budget -= EstimateAlignmentSize(field); + } - int memset_run_start = -1; - int memset_run_end = -1; - for (; i < optimized_order_.size(); i++) { - const FieldDescriptor* field = optimized_order_[i]; + std::vector<std::vector<const FieldDescriptor*> > chunks_frag = CollectFields( + optimized_order_, + MatchRepeatedAndHasByteAndZeroInits( + &has_bit_indices_, HasFieldPresence(descriptor_->file()))); - if (!CanInitializeByZeroing(field)) { - break; + // Merge next non-zero initializable chunk if it has the same has_byte index + // and not meeting unconditional clear condition. + std::vector<std::vector<const FieldDescriptor*> > chunks; + if (!HasFieldPresence(descriptor_->file())) { + // Don't bother with merging without has_bit field. + chunks = chunks_frag; + } else { + // Note that only the next chunk is considered for merging. + for (int i = 0; i < chunks_frag.size(); i++) { + chunks.push_back(chunks_frag[i]); + const FieldDescriptor* field = chunks_frag[i].front(); + const FieldDescriptor* next_field = + (i + 1) < chunks_frag.size() ? chunks_frag[i + 1].front() : NULL; + if (CanInitializeByZeroing(field) && + (chunks_frag[i].size() == 1 || unconditional_budget < 0) && + next_field != NULL && + has_bit_indices_[field->index()] / 8 == + has_bit_indices_[next_field->index()] / 8) { + GOOGLE_CHECK(!CanInitializeByZeroing(next_field)); + // Insert next chunk to the current one and skip next chunk. + chunks.back().insert(chunks.back().end(), chunks_frag[i + 1].begin(), + chunks_frag[i + 1].end()); + i++; } + } + } - // "index" defines where in the _has_bits_ the field appears. - // "i" is our loop counter within optimized_order_. - int index = HasFieldPresence(descriptor_->file()) ? - has_bit_indices_[field->index()] : 0; - int chunk = index / 8; + for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) { + std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index]; + GOOGLE_CHECK(!chunk.empty()); - if (last_chunk == -1) { - last_chunk = chunk; - last_chunk_start = i; - } else if (chunk != last_chunk) { - // Emit the fields for this chunk so far. - break; - } + // Step 2: Repeated fields don't use _has_bits_; emit code to clear them + // here. + if (chunk.front()->is_repeated()) { + for (int i = 0; i < chunk.size(); i++) { + const FieldDescriptor* field = chunk[i]; + const FieldGenerator& generator = field_generators_.get(field); - if (memset_run_start == -1) { - memset_run_start = i; + generator.GenerateMessageClearingCode(printer); } - - memset_run_end = i; - last_chunk_end = i; - last_chunk_mask |= static_cast<uint32>(1) << (index % 32); + continue; } - // Step 4: Non-repeated, non-zero initializable fields. - for (; i < optimized_order_.size(); i++) { - const FieldDescriptor* field = optimized_order_[i]; - if (field->is_repeated() || CanInitializeByZeroing(field)) { - break; - } - - // "index" defines where in the _has_bits_ the field appears. - // "i" is our loop counter within optimized_order_. - int index = HasFieldPresence(descriptor_->file()) ? - has_bit_indices_[field->index()] : 0; - int chunk = index / 8; + // Step 3: Non-repeated fields that can be cleared by memset-to-0, then + // non-repeated, non-zero initializable fields. + int last_chunk = HasFieldPresence(descriptor_->file()) + ? has_bit_indices_[chunk.front()->index()] / 8 + : 0; + int last_chunk_start = 0; + int memset_run_start = -1; + int memset_run_end = -1; - if (last_chunk == -1) { - last_chunk = chunk; - last_chunk_start = i; - } else if (chunk != last_chunk) { - // Emit the fields for this chunk so far. - break; + for (int i = 0; i < chunk.size(); i++) { + const FieldDescriptor* field = chunk[i]; + if (CanInitializeByZeroing(field)) { + if (memset_run_start == -1) { + memset_run_start = i; + } + memset_run_end = i; } - - last_chunk_end = i; - last_chunk_mask |= static_cast<uint32>(1) << (index % 32); } - if (last_chunk != -1) { - GOOGLE_DCHECK_NE(-1, last_chunk_start); - GOOGLE_DCHECK_NE(-1, last_chunk_end); - GOOGLE_DCHECK_NE(0, last_chunk_mask); + const bool have_outer_if = + HasFieldPresence(descriptor_->file()) && chunk.size() > 1 && + (memset_run_end != chunk.size() - 1 || unconditional_budget < 0); + if (have_outer_if) { + uint32 last_chunk_mask = GenChunkMask(chunk, has_bit_indices_); const int count = popcnt(last_chunk_mask); - const bool have_outer_if = HasFieldPresence(descriptor_->file()) && - (last_chunk_start != last_chunk_end); - if (have_outer_if) { - // Check (up to) 8 has_bits at a time if we have more than one field in - // this chunk. Due to field layout ordering, we may check - // _has_bits_[last_chunk * 8 / 32] multiple times. - GOOGLE_DCHECK_LE(2, count); - GOOGLE_DCHECK_GE(8, count); + // Check (up to) 8 has_bits at a time if we have more than one field in + // this chunk. Due to field layout ordering, we may check + // _has_bits_[last_chunk * 8 / 32] multiple times. + GOOGLE_DCHECK_LE(2, count); + GOOGLE_DCHECK_GE(8, count); - printer->Print( - "if (_has_bits_[$index$ / 32] & $mask$u) {\n", - "index", SimpleItoa(last_chunk * 8), - "mask", SimpleItoa(last_chunk_mask)); - printer->Indent(); + if (cached_has_bit_index != last_chunk / 4) { + cached_has_bit_index = last_chunk / 4; + printer->Print("cached_has_bits = _has_bits_[$idx$];\n", "idx", + SimpleItoa(cached_has_bit_index)); } + printer->Print("if (cached_has_bits & $mask$u) {\n", "mask", + SimpleItoa(last_chunk_mask)); + printer->Indent(); + } - if (memset_run_start != -1) { - if (memset_run_start == memset_run_end) { - // For clarity, do not memset a single field. - const FieldGenerator& generator = - field_generators_.get(optimized_order_[memset_run_start]); - generator.GenerateMessageClearingCode(printer); - } else { - const string first_field_name = - FieldName(optimized_order_[memset_run_start]); - const string last_field_name = - FieldName(optimized_order_[memset_run_end]); - - printer->Print( - "::memset(&$first$_, 0, reinterpret_cast<char*>(&$last$_) -\n" - " reinterpret_cast<char*>(&$first$_) + sizeof($last$_));\n", - "first", first_field_name, - "last", last_field_name); - } + if (memset_run_start != -1) { + if (memset_run_start == memset_run_end) { + // For clarity, do not memset a single field. + const FieldGenerator& generator = + field_generators_.get(chunk[memset_run_start]); + generator.GenerateMessageClearingCode(printer); + } else { + const string first_field_name = FieldName(chunk[memset_run_start]); + const string last_field_name = FieldName(chunk[memset_run_end]); - // Advance last_chunk_start to skip over the fields we zeroed/memset. - last_chunk_start = memset_run_end + 1; + printer->Print( + "::memset(&$first$_, 0, static_cast<size_t>(\n" + " reinterpret_cast<char*>(&$last$_) -\n" + " reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n", + "first", first_field_name, "last", last_field_name); } - // Go back and emit clears for each of the fields we processed. - for (int j = last_chunk_start; j <= last_chunk_end; j++) { - const FieldDescriptor* field = optimized_order_[j]; - const string fieldname = FieldName(field); - const FieldGenerator& generator = field_generators_.get(field); + // Advance last_chunk_start to skip over the fields we zeroed/memset. + last_chunk_start = memset_run_end + 1; + } + + // Go back and emit clears for each of the fields we processed. + for (int j = last_chunk_start; j < chunk.size(); j++) { + const FieldDescriptor* field = chunk[j]; + const string fieldname = FieldName(field); + const FieldGenerator& generator = field_generators_.get(field); - // It's faster to just overwrite primitive types, but we should only - // clear strings and messages if they were set. - // - // TODO(kenton): Let the CppFieldGenerator decide this somehow. - bool should_check_bit = + // It's faster to just overwrite primitive types, but we should only + // clear strings and messages if they were set. + // + // TODO(kenton): Let the CppFieldGenerator decide this somehow. + bool should_check_bit = field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || field->cpp_type() == FieldDescriptor::CPPTYPE_STRING; - bool have_enclosing_if = false; - if (should_check_bit && - // If no field presence, then always clear strings/messages as well. - HasFieldPresence(descriptor_->file())) { - printer->Print("if (has_$name$()) {\n", "name", fieldname); - printer->Indent(); - have_enclosing_if = true; + bool have_enclosing_if = false; + if (should_check_bit && + // If no field presence, then always clear strings/messages as well. + HasFieldPresence(descriptor_->file())) { + if (!field->options().weak() && + cached_has_bit_index != (has_bit_indices_[field->index()] / 32)) { + cached_has_bit_index = (has_bit_indices_[field->index()] / 32); + printer->Print("cached_has_bits = _has_bits_[$new_index$];\n", + "new_index", SimpleItoa(cached_has_bit_index)); } - - generator.GenerateMessageClearingCode(printer); - - if (have_enclosing_if) { - printer->Outdent(); - printer->Print("}\n"); + if (!MaybeGenerateOptionalFieldCondition(printer, field, + cached_has_bit_index)) { + printer->Print("if (has_$name$()) {\n", "name", fieldname); } + printer->Indent(); + have_enclosing_if = true; } - if (have_outer_if) { + generator.GenerateMessageClearingCode(printer); + + if (have_enclosing_if) { printer->Outdent(); printer->Print("}\n"); } } + + if (have_outer_if) { + printer->Outdent(); + printer->Print("}\n"); + } } // Step 4: Unions. @@ -2814,9 +2980,7 @@ GenerateClear(io::Printer* printer) { printer->Print("_has_bits_.Clear();\n"); } - if (PreserveUnknownFields(descriptor_)) { - printer->Print("_internal_metadata_.Clear();\n"); - } + printer->Print("_internal_metadata_.Clear();\n"); printer->Outdent(); printer->Print("}\n"); @@ -2920,6 +3084,7 @@ GenerateSwap(io::Printer* printer) { printer->Print("void $classname$::InternalSwap($classname$* other) {\n", "classname", classname_); printer->Indent(); + printer->Print("using std::swap;\n"); if (HasGeneratedMethods(descriptor_->file(), options_)) { for (int i = 0; i < optimized_order_.size(); i++) { @@ -2931,24 +3096,22 @@ GenerateSwap(io::Printer* printer) { for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { printer->Print( - "std::swap($oneof_name$_, other->$oneof_name$_);\n" - "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n", + "swap($oneof_name$_, other->$oneof_name$_);\n" + "swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n", "oneof_name", descriptor_->oneof_decl(i)->name(), "i", SimpleItoa(i)); } if (HasFieldPresence(descriptor_->file())) { for (int i = 0; i < HasBitsSize() / 4; ++i) { - printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n", + printer->Print("swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n", "i", SimpleItoa(i)); } } - if (PreserveUnknownFields(descriptor_)) { - printer->Print("_internal_metadata_.Swap(&other->_internal_metadata_);\n"); - } + printer->Print("_internal_metadata_.Swap(&other->_internal_metadata_);\n"); - printer->Print("std::swap(_cached_size_, other->_cached_size_);\n"); + printer->Print("swap(_cached_size_, other->_cached_size_);\n"); if (descriptor_->extension_range_count() > 0) { printer->Print("_extensions_.Swap(&other->_extensions_);\n"); } @@ -3251,25 +3414,19 @@ GenerateCopyFrom(io::Printer* printer) { void MessageGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) { + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); if (descriptor_->options().message_set_wire_format()) { // Special-case MessageSet. - printer->Print( + vars["classname"] = classname_; + printer->Print(vars, "bool $classname$::MergePartialFromCodedStream(\n" - " ::google::protobuf::io::CodedInputStream* input) {\n", - "classname", classname_); - - printer->Print( - " return _extensions_.ParseMessageSet(input, " - "internal_default_instance(),\n" - " mutable_unknown_fields());\n", - // Vars. - "classname", classname_); - - printer->Print( + " ::google::protobuf::io::CodedInputStream* input) {\n" + " return _extensions_.ParseMessageSet(input,\n" + " internal_default_instance(), $mutable_unknown_fields$);\n" "}\n"); return; } - std::vector<const FieldDescriptor*> ordered_fields = SortFieldsByNumber(descriptor_); @@ -3281,14 +3438,17 @@ GenerateMergeFromCodedStream(io::Printer* printer) { if (table_driven_) { printer->Indent(); + const string lite = UseUnknownFieldSet(descriptor_->file(), options_) ? + "" : "Lite"; + printer->Print( - "return ::google::protobuf::internal::MergePartialFromCodedStream(\n" + "return ::google::protobuf::internal::MergePartialFromCodedStream$lite$(\n" " this,\n" - " $file_namespace$::TableStruct::schema[\n" + " ::$file_namespace$::TableStruct::schema[\n" " $classname$::kIndexInFileMessages],\n" " input);\n", - "classname", classname_, - "file_namespace", FileLevelNamespace(descriptor_->file()->name())); + "classname", classname_, "file_namespace", + FileLevelNamespace(descriptor_), "lite", lite); printer->Outdent(); @@ -3296,23 +3456,32 @@ GenerateMergeFromCodedStream(io::Printer* printer) { return; } + if (SupportsArenas(descriptor_)) { + for (int i = 0; i < ordered_fields.size(); i++) { + const FieldDescriptor* field = ordered_fields[i]; + const FieldGenerator& field_generator = field_generators_.get(field); + if (field_generator.MergeFromCodedStreamNeedsArena()) { + printer->Print( + " ::google::protobuf::Arena* arena = GetArenaNoVirtual();\n"); + break; + } + } + } + printer->Print( - "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\n" - " ::google::protobuf::uint32 tag;\n"); - - if (PreserveUnknownFields(descriptor_) && - !UseUnknownFieldSet(descriptor_->file(), options_)) { - // Use LazyStringOutputString to avoid initializing unknown fields string - // unless it is actually needed. For the same reason, disable eager refresh - // on the CodedOutputStream. + "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto " + "failure\n" + " ::google::protobuf::uint32 tag;\n"); + + if (!UseUnknownFieldSet(descriptor_->file(), options_)) { printer->Print( - " ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n" - " ::google::protobuf::NewPermanentCallback(&_internal_metadata_,\n" - " &::google::protobuf::internal::InternalMetadataWithArenaLite::\n" - " mutable_unknown_fields));\n" - " ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n" - " &unknown_fields_string, false);\n", - "classname", classname_); + " ::google::protobuf::internal::LiteUnknownFieldSetter unknown_fields_setter(\n" + " &_internal_metadata_);\n" + " ::google::protobuf::io::StringOutputStream unknown_fields_output(\n" + " unknown_fields_setter.buffer());\n" + " ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n" + " &unknown_fields_output, false);\n", + "classname", classname_); } printer->Print( @@ -3354,13 +3523,12 @@ GenerateMergeFromCodedStream(io::Printer* printer) { } printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = " - "input->ReadTagWithCutoff$lasttag$($max$u);\n" + "input->ReadTagWithCutoffNoLastTag($max$u);\n" "tag = p.first;\n" "if (!p.second) goto handle_unusual;\n", "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 : (maxtag <= kCutoff1 ? kCutoff1 : - maxtag)), - "lasttag", !capture_last_tag ? "NoLastTag" : ""); + maxtag))); if (descriptor_->field_count() > 0) { // We don't even want to print the switch() if we have no fields because @@ -3395,9 +3563,11 @@ GenerateMergeFromCodedStream(io::Printer* printer) { const FieldGenerator& field_generator = field_generators_.get(field); // Emit code to parse the common, expected case. - printer->Print("if (static_cast< ::google::protobuf::uint8>(tag) ==\n" - " static_cast< ::google::protobuf::uint8>($commontag$u)) {\n", - "commontag", SimpleItoa(WireFormat::MakeTag(field))); + printer->Print( + "if (static_cast< ::google::protobuf::uint8>(tag) ==\n" + " static_cast< ::google::protobuf::uint8>($truncated$u /* $full$ & 0xFF */)) {\n", + "truncated", SimpleItoa(WireFormat::MakeTag(field) & 0xFF), + "full", SimpleItoa(WireFormat::MakeTag(field))); printer->Indent(); if (field->is_packed()) { @@ -3411,22 +3581,30 @@ GenerateMergeFromCodedStream(io::Printer* printer) { if (field->is_packed()) { internal::WireFormatLite::WireType wiretype = WireFormat::WireTypeForFieldType(field->type()); - printer->Print("} else if (static_cast< ::google::protobuf::uint8>(tag) ==\n" - " static_cast< ::google::protobuf::uint8>($uncommontag$u)) {\n", - "uncommontag", SimpleItoa( - internal::WireFormatLite::MakeTag( - field->number(), wiretype))); + const uint32 tag = internal::WireFormatLite::MakeTag( + field->number(), wiretype); + printer->Print( + "} else if (\n" + " static_cast< ::google::protobuf::uint8>(tag) ==\n" + " static_cast< ::google::protobuf::uint8>($truncated$u /* $full$ & 0xFF */)) {\n", + "truncated", SimpleItoa(tag & 0xFF), + "full", SimpleItoa(tag)); + printer->Indent(); field_generator.GenerateMergeFromCodedStream(printer); printer->Outdent(); } else if (field->is_packable() && !field->is_packed()) { internal::WireFormatLite::WireType wiretype = internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED; - printer->Print("} else if (static_cast< ::google::protobuf::uint8>(tag) ==\n" - " static_cast< ::google::protobuf::uint8>($uncommontag$u)) {\n", - "uncommontag", SimpleItoa( - internal::WireFormatLite::MakeTag( - field->number(), wiretype))); + const uint32 tag = internal::WireFormatLite::MakeTag( + field->number(), wiretype); + + printer->Print( + "} else if (\n" + " static_cast< ::google::protobuf::uint8>(tag) ==\n" + " static_cast< ::google::protobuf::uint8>($truncated$u /* $full$ & 0xFF */)) {\n", + "truncated", SimpleItoa(tag & 0xFF), + "full", SimpleItoa(tag)); printer->Indent(); field_generator.GenerateMergeFromCodedStreamWithPacking(printer); printer->Outdent(); @@ -3452,12 +3630,20 @@ GenerateMergeFromCodedStream(io::Printer* printer) { printer->Print("handle_unusual:\n"); printer->Indent(); // If tag is 0 or an end-group tag then this must be the end of the message. - printer->Print( - "if (tag == 0 ||\n" - " ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" - " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n" - " goto success;\n" - "}\n"); + if (capture_last_tag) { + printer->Print( + "if (tag == 0 ||\n" + " ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" + " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n" + " input->SetLastTag(tag);\n" + " goto success;\n" + "}\n"); + } else { + printer->Print( + "if (tag == 0) {\n" + " goto success;\n" + "}\n"); + } // Handle extension ranges. if (descriptor_->extension_range_count() > 0) { @@ -3485,23 +3671,16 @@ GenerateMergeFromCodedStream(io::Printer* printer) { } } printer->Print(") {\n"); - if (PreserveUnknownFields(descriptor_)) { - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - printer->Print( - " DO_(_extensions_.ParseField(tag, input, " - "internal_default_instance(),\n" - " mutable_unknown_fields()));\n"); - } else { - printer->Print( - " DO_(_extensions_.ParseField(tag, input, " - "internal_default_instance(),\n" - " &unknown_fields_stream));\n"); - } + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + printer->Print(vars, + " DO_(_extensions_.ParseField(tag, input,\n" + " internal_default_instance(),\n" + " $mutable_unknown_fields$));\n"); } else { printer->Print( - // With static initializers. - " DO_(_extensions_.ParseField(tag, input, " - "internal_default_instance());\n"); + " DO_(_extensions_.ParseField(tag, input,\n" + " internal_default_instance(),\n" + " &unknown_fields_stream));\n"); } printer->Print( " continue;\n" @@ -3509,19 +3688,14 @@ GenerateMergeFromCodedStream(io::Printer* printer) { } // We really don't recognize this tag. Skip it. - if (PreserveUnknownFields(descriptor_)) { - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - printer->Print( + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + printer->Print(vars, "DO_(::google::protobuf::internal::WireFormat::SkipField(\n" - " input, tag, mutable_unknown_fields()));\n"); - } else { - printer->Print( - "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n" - " input, tag, &unknown_fields_stream));\n"); - } + " input, tag, $mutable_unknown_fields$));\n"); } else { printer->Print( - "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n"); + "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n" + " input, tag, &unknown_fields_stream));\n"); } if (descriptor_->field_count() > 0) { @@ -3658,13 +3832,16 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) { " _extensions_.SerializeMessageSetWithCachedSizes(output);\n", "classname", classname_); GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_)); - printer->Print( + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + printer->Print(vars, " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n" - " unknown_fields(), output);\n"); + " $unknown_fields$, output);\n"); printer->Print( "}\n"); return; } + if (options_.table_driven_serialization) return; printer->Print( "void $classname$::SerializeWithCachedSizes(\n" @@ -3699,10 +3876,12 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { " deterministic, target);\n", "classname", classname_); GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_)); - printer->Print( + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + printer->Print(vars, " target = ::google::protobuf::internal::WireFormat::\n" " SerializeUnknownMessageSetItemsToArray(\n" - " unknown_fields(), target);\n"); + " $unknown_fields$, target);\n"); printer->Print( " return target;\n" "}\n"); @@ -3715,6 +3894,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { "classname", classname_); printer->Indent(); + printer->Print("(void)deterministic; // Unused\n"); printer->Print( "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n", "full_name", descriptor_->full_name()); @@ -3866,29 +4046,29 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { } } - if (PreserveUnknownFields(descriptor_)) { - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - printer->Print("if (_internal_metadata_.have_unknown_fields()) {\n"); - printer->Indent(); - if (to_array) { - printer->Print( - "target = " - "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n" - " unknown_fields(), target);\n"); - } else { - printer->Print( - "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n" - " unknown_fields(), output);\n"); - } - printer->Outdent(); - - printer->Print( - "}\n"); + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + printer->Print(vars, + "if ($have_unknown_fields$) {\n"); + printer->Indent(); + if (to_array) { + printer->Print(vars, + "target = " + "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n" + " $unknown_fields$, target);\n"); } else { - printer->Print( - "output->WriteRaw(unknown_fields().data(),\n" - " static_cast<int>(unknown_fields().size()));\n"); + printer->Print(vars, + "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n" + " $unknown_fields$, output);\n"); } + printer->Outdent(); + + printer->Print("}\n"); + } else { + printer->Print(vars, + "output->WriteRaw($unknown_fields$.data(),\n" + " static_cast<int>($unknown_fields$.size()));\n"); } } @@ -3932,18 +4112,19 @@ void MessageGenerator:: GenerateByteSize(io::Printer* printer) { if (descriptor_->options().message_set_wire_format()) { // Special-case MessageSet. - printer->Print( - "size_t $classname$::ByteSizeLong() const {\n" - "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" - " size_t total_size = _extensions_.MessageSetByteSize();\n", - "classname", classname_, "full_name", descriptor_->full_name()); GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_)); - printer->Print( - "if (_internal_metadata_.have_unknown_fields()) {\n" - " total_size += ::google::protobuf::internal::WireFormat::\n" - " ComputeUnknownMessageSetItemsSize(unknown_fields());\n" - "}\n"); - printer->Print( + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + vars["classname"] = classname_; + vars["full_name"] = descriptor_->full_name(); + printer->Print(vars, + "size_t $classname$::ByteSizeLong() const {\n" + "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" + " size_t total_size = _extensions_.MessageSetByteSize();\n" + " if ($have_unknown_fields$) {\n" + " total_size += ::google::protobuf::internal::WireFormat::\n" + " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n" + " }\n" " int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);\n" " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" " _cached_size_ = cached_size;\n" @@ -3997,19 +4178,19 @@ GenerateByteSize(io::Printer* printer) { "\n"); } - if (PreserveUnknownFields(descriptor_)) { - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - printer->Print( - "if (_internal_metadata_.have_unknown_fields()) {\n" - " total_size +=\n" - " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n" - " unknown_fields());\n" - "}\n"); - } else { - printer->Print( - "total_size += unknown_fields().size();\n" - "\n"); - } + std::map<string, string> vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + printer->Print(vars, + "if ($have_unknown_fields$) {\n" + " total_size +=\n" + " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n" + " $unknown_fields$);\n" + "}\n"); + } else { + printer->Print(vars, + "total_size += $unknown_fields$.size();\n" + "\n"); } // Handle required fields (if any). We expect all of them to be @@ -4050,28 +4231,30 @@ GenerateByteSize(io::Printer* printer) { } } - int last_i = -1; - for (int i = 0; i < optimized_order_.size(); ) { - // Detect infinite loops. - GOOGLE_CHECK_NE(i, last_i); - last_i = i; + std::vector<std::vector<const FieldDescriptor*> > chunks = CollectFields( + optimized_order_, + MatchRepeatedAndHasByteAndRequired( + &has_bit_indices_, HasFieldPresence(descriptor_->file()))); - // Skip required fields. - for (; i < optimized_order_.size() && - optimized_order_[i]->is_required(); i++) { - } + // Remove chunks with required fields. + chunks.erase(std::remove_if(chunks.begin(), chunks.end(), IsRequired), + chunks.end()); + + for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) { + const std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index]; + GOOGLE_CHECK(!chunk.empty()); // Handle repeated fields. - for (; i < optimized_order_.size(); i++) { - const FieldDescriptor* field = optimized_order_[i]; - if (!field->is_repeated()) { - break; - } + if (chunk.front()->is_repeated()) { + for (int i = 0; i < chunk.size(); i++) { + const FieldDescriptor* field = chunk[i]; - PrintFieldComment(printer, field); - const FieldGenerator& generator = field_generators_.get(field); - generator.GenerateByteSize(printer); - printer->Print("\n"); + PrintFieldComment(printer, field); + const FieldGenerator& generator = field_generators_.get(field); + generator.GenerateByteSize(printer); + printer->Print("\n"); + } + continue; } // Handle optional (non-repeated/oneof) fields. @@ -4083,92 +4266,62 @@ GenerateByteSize(io::Printer* printer) { // descriptor_->field(8), descriptor_->field(9), ... // descriptor_->field(15), // etc. - int last_chunk = -1; - int last_chunk_start = -1; - int last_chunk_end = -1; - uint32 last_chunk_mask = 0; - for (; i < optimized_order_.size(); i++) { - const FieldDescriptor* field = optimized_order_[i]; - if (field->is_repeated() || field->is_required()) { - break; - } + int last_chunk = HasFieldPresence(descriptor_->file()) + ? has_bit_indices_[chunk.front()->index()] / 8 + : 0; + GOOGLE_DCHECK_NE(-1, last_chunk); - // "index" defines where in the _has_bits_ the field appears. - // "i" is our loop counter within optimized_order_. - int index = HasFieldPresence(descriptor_->file()) ? - has_bit_indices_[field->index()] : 0; - int chunk = index / 8; + const bool have_outer_if = + HasFieldPresence(descriptor_->file()) && chunk.size() > 1; - if (last_chunk == -1) { - last_chunk = chunk; - last_chunk_start = i; - } else if (chunk != last_chunk) { - // Emit the fields for this chunk so far. - break; - } + if (have_outer_if) { + uint32 last_chunk_mask = GenChunkMask(chunk, has_bit_indices_); + const int count = popcnt(last_chunk_mask); - last_chunk_end = i; - last_chunk_mask |= static_cast<uint32>(1) << (index % 32); - } + // Check (up to) 8 has_bits at a time if we have more than one field in + // this chunk. Due to field layout ordering, we may check + // _has_bits_[last_chunk * 8 / 32] multiple times. + GOOGLE_DCHECK_LE(2, count); + GOOGLE_DCHECK_GE(8, count); - if (last_chunk != -1) { - GOOGLE_DCHECK_NE(-1, last_chunk_start); - GOOGLE_DCHECK_NE(-1, last_chunk_end); - GOOGLE_DCHECK_NE(0, last_chunk_mask); + printer->Print("if (_has_bits_[$index$ / 32] & $mask$u) {\n", "index", + SimpleItoa(last_chunk * 8), "mask", + SimpleItoa(last_chunk_mask)); + printer->Indent(); + } - const int count = popcnt(last_chunk_mask); - const bool have_outer_if = HasFieldPresence(descriptor_->file()) && - (last_chunk_start != last_chunk_end); + // Go back and emit checks for each of the fields we processed. + for (int j = 0; j < chunk.size(); j++) { + const FieldDescriptor* field = chunk[j]; + const FieldGenerator& generator = field_generators_.get(field); - if (have_outer_if) { - // Check (up to) 8 has_bits at a time if we have more than one field in - // this chunk. Due to field layout ordering, we may check - // _has_bits_[last_chunk * 8 / 32] multiple times. - GOOGLE_DCHECK_LE(2, count); - GOOGLE_DCHECK_GE(8, count); + PrintFieldComment(printer, field); - printer->Print( - "if (_has_bits_[$index$ / 32] & $mask$u) {\n", - "index", SimpleItoa(last_chunk * 8), - "mask", SimpleItoa(last_chunk_mask)); + bool have_enclosing_if = false; + if (HasFieldPresence(descriptor_->file())) { + printer->Print("if (has_$name$()) {\n", "name", FieldName(field)); printer->Indent(); + have_enclosing_if = true; + } else { + // Without field presence: field is serialized only if it has a + // non-default value. + have_enclosing_if = + EmitFieldNonDefaultCondition(printer, "this->", field); } - // Go back and emit checks for each of the fields we processed. - for (int j = last_chunk_start; j <= last_chunk_end; j++) { - const FieldDescriptor* field = optimized_order_[j]; - const FieldGenerator& generator = field_generators_.get(field); - - PrintFieldComment(printer, field); - - bool have_enclosing_if = false; - if (HasFieldPresence(descriptor_->file())) { - printer->Print( - "if (has_$name$()) {\n", - "name", FieldName(field)); - printer->Indent(); - have_enclosing_if = true; - } else { - // Without field presence: field is serialized only if it has a - // non-default value. - have_enclosing_if = EmitFieldNonDefaultCondition( - printer, "this->", field); - } - - generator.GenerateByteSize(printer); + generator.GenerateByteSize(printer); - if (have_enclosing_if) { - printer->Outdent(); - printer->Print( + if (have_enclosing_if) { + printer->Outdent(); + printer->Print( "}\n" "\n"); - } } + } - if (have_outer_if) { - printer->Outdent(); - printer->Print("}\n"); - } + if (have_outer_if) { + printer->Outdent(); + printer->Print("}\n"); } } @@ -4268,10 +4421,17 @@ GenerateIsInitialized(io::Printer* printer) { !ShouldIgnoreRequiredFieldCheck(field, options_) && scc_analyzer_->HasRequiredFields(field->message_type())) { if (field->is_repeated()) { - printer->Print( - "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))" - " return false;\n", - "name", FieldName(field)); + if (IsImplicitWeakField(field, options_)) { + printer->Print( + "if (!::google::protobuf::internal::AllAreInitializedWeak(this->$name$_))" + " return false;\n", + "name", FieldName(field)); + } else { + printer->Print( + "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))" + " return false;\n", + "name", FieldName(field)); + } } else if (field->options().weak()) { continue; } else { @@ -4358,7 +4518,6 @@ GenerateIsInitialized(io::Printer* printer) { "}\n"); } - } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index 23aaeeb0..06e2030b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -43,6 +43,7 @@ #include <string> #include <google/protobuf/compiler/cpp/cpp_field.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> +#include <google/protobuf/compiler/cpp/cpp_message_layout_helper.h> #include <google/protobuf/compiler/cpp/cpp_options.h> namespace google { @@ -62,12 +63,10 @@ class ExtensionGenerator; // extension.h class MessageGenerator { public: // See generator.cc for the meaning of dllexport_decl. - MessageGenerator(const Descriptor* descriptor, const Options& options, - SCCAnalyzer* scc_analyzer); + MessageGenerator(const Descriptor* descriptor, int index_in_file_messages, + const Options& options, SCCAnalyzer* scc_analyzer); ~MessageGenerator(); - // Appends the pre-order walk of the nested generators to list. - void Flatten(std::vector<MessageGenerator*>* list); // Append the two types of nested generators to the corresponding vector. void AddGenerators(std::vector<EnumGenerator*>* enum_generators, std::vector<ExtensionGenerator*>* extension_generators); @@ -86,7 +85,7 @@ class MessageGenerator { // Generate definitions of inline methods (placed at the end of the header // file). - void GenerateInlineMethods(io::Printer* printer, bool is_inline); + void GenerateInlineMethods(io::Printer* printer); // Dependent methods are always inline. void GenerateDependentInlineMethods(io::Printer* printer); @@ -96,28 +95,27 @@ class MessageGenerator { // Generate extra fields void GenerateExtraDefaultFields(io::Printer* printer); - // Generates code that allocates the message's default instance. - void GenerateDefaultInstanceAllocator(io::Printer* printer); + // Generates code that creates default instances for fields. + void GenerateFieldDefaultInstances(io::Printer* printer); // Generates code that initializes the message's default instance. This // is separate from allocating because all default instances must be // allocated before any can be initialized. void GenerateDefaultInstanceInitializer(io::Printer* printer); - // Generates code that should be run when ShutdownProtobufLibrary() is called, - // to delete all dynamically-allocated objects. - void GenerateShutdownCode(io::Printer* printer); - // Generate all non-inline methods for this class. void GenerateClassMethods(io::Printer* printer); + // Generate source file code that should go outside any namespace. + void GenerateSourceInProto2Namespace(io::Printer* printer); + private: // Generate declarations and definitions of accessors for fields. void GenerateDependentBaseClassDefinition(io::Printer* printer); void GenerateDependentFieldAccessorDeclarations(io::Printer* printer); void GenerateFieldAccessorDeclarations(io::Printer* printer); void GenerateDependentFieldAccessorDefinitions(io::Printer* printer); - void GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline); + void GenerateFieldAccessorDefinitions(io::Printer* printer); // Generate the table-driven parsing array. Returns the number of entries // generated. @@ -132,6 +130,9 @@ class MessageGenerator { // of entries generated and the index of the first has_bit entry. std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer); void GenerateSchema(io::Printer* printer, int offset, int has_offset); + // For each field generates a table entry describing the field for the + // table driven serializer. + int GenerateFieldMetadata(io::Printer* printer); // Generate constructors and destructor. void GenerateStructors(io::Printer* printer); @@ -147,6 +148,13 @@ class MessageGenerator { // Generate the arena-specific destructor code. void GenerateArenaDestructorCode(io::Printer* printer); + // Helper for GenerateClear and others. Optionally emits a condition that + // assumes the existence of the cached_has_bits variable, and returns true if + // the condition was printed. + bool MaybeGenerateOptionalFieldCondition(io::Printer* printer, + const FieldDescriptor* field, + int expected_has_bits_index); + // Generate standard Message methods. void GenerateClear(io::Printer* printer); void GenerateOneofClear(io::Printer* printer); @@ -179,13 +187,12 @@ class MessageGenerator { io::Printer* printer, const Descriptor::ExtensionRange* range, bool unbounded); - // Generates has_foo() functions and variables for singular field has-bits. void GenerateSingularFieldHasBits(const FieldDescriptor* field, std::map<string, string> vars, io::Printer* printer); // Generates has_foo() functions and variables for oneof field has-bits. - void GenerateOneofHasBits(io::Printer* printer, bool is_inline); + void GenerateOneofHasBits(io::Printer* printer); // Generates has_foo_bar() functions for oneof members. void GenerateOneofMemberHasBits(const FieldDescriptor* field, const std::map<string, string>& vars, @@ -193,6 +200,7 @@ class MessageGenerator { // Generates the clear_foo() method for a field. void GenerateFieldClear(const FieldDescriptor* field, const std::map<string, string>& vars, + bool is_inline, io::Printer* printer); void GenerateConstructorBody(io::Printer* printer, @@ -203,6 +211,7 @@ class MessageGenerator { std::vector<uint32> RequiredFieldsBitMask() const; const Descriptor* descriptor_; + int index_in_file_messages_; string classname_; Options options_; FieldGeneratorMap field_generators_; @@ -213,7 +222,6 @@ class MessageGenerator { std::vector<const FieldDescriptor *> optimized_order_; std::vector<int> has_bit_indices_; int max_has_bit_index_; - google::protobuf::scoped_array<google::protobuf::scoped_ptr<MessageGenerator> > nested_generators_; google::protobuf::scoped_array<google::protobuf::scoped_ptr<EnumGenerator> > enum_generators_; google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> > extension_generators_; int num_required_fields_; @@ -222,9 +230,10 @@ class MessageGenerator { // table_driven_ indicates the generated message uses table-driven parsing. bool table_driven_; - int index_in_file_messages_; + google::protobuf::scoped_ptr<MessageLayoutHelper> message_layout_helper_; SCCAnalyzer* scc_analyzer_; + string scc_name_; friend class FileGenerator; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index fc3c4564..530a6392 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -45,15 +45,44 @@ namespace cpp { namespace { +// When we are generating code for implicit weak fields, we need to insert some +// additional casts. These functions return the casted expression if +// implicit_weak_field is true but otherwise return the original expression. +// Ordinarily a static_cast is enough to cast google::protobuf::MessageLite* to a class +// deriving from it, but we need a reinterpret_cast in cases where the generated +// message is forward-declared but its full definition is not visible. +string StaticCast(const string& type, const string& expression, + bool implicit_weak_field) { + if (implicit_weak_field) { + return "static_cast< " + type + " >(" + expression + ")"; + } else { + return expression; + } +} + +string ReinterpretCast(const string& type, const string& expression, + bool implicit_weak_field) { + if (implicit_weak_field) { + return "reinterpret_cast< " + type + " >(" + expression + ")"; + } else { + return expression; + } +} + void SetMessageVariables(const FieldDescriptor* descriptor, std::map<string, string>* variables, const Options& options) { SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = FieldMessageTypeName(descriptor); - if (descriptor->options().weak() || !descriptor->containing_oneof()) { - (*variables)["non_null_ptr_to_name"] = - StrCat("this->", (*variables)["name"], "_"); - } + (*variables)["casted_member"] = + ReinterpretCast((*variables)["type"] + "*", (*variables)["name"] + "_", + IsImplicitWeakField(descriptor, options)); + (*variables)["type_default_instance"] = + DefaultInstanceName(descriptor->message_type()); + (*variables)["type_reference_function"] = + IsImplicitWeakField(descriptor, options) + ? (" " + ReferenceFunctionName(descriptor->message_type()) + "();\n") + : ""; (*variables)["stream_writer"] = (*variables)["declared_type"] + (HasFastArraySerialization(descriptor->message_type()->file(), options) @@ -65,14 +94,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, SafeFunctionName(descriptor->containing_type(), descriptor, "release_"); (*variables)["full_name"] = descriptor->full_name(); - if (options.proto_h && IsFieldDependent(descriptor)) { - (*variables)["dependent_type"] = "T::" + DependentTypeName(descriptor); - (*variables)["dependent_typename"] = - "typename T::" + DependentTypeName(descriptor); - } else { - (*variables)["dependent_type"] = FieldMessageTypeName(descriptor); - (*variables)["dependent_typename"] = FieldMessageTypeName(descriptor); - } + (*variables)["create_func"] = + MessageCreateFunction(descriptor->message_type()); } } // namespace @@ -83,7 +106,7 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, const Options& options) : FieldGenerator(options), descriptor_(descriptor), - dependent_field_(options.proto_h && IsFieldDependent(descriptor)) { + implicit_weak_field_(IsImplicitWeakField(descriptor, options)) { SetMessageVariables(descriptor, &variables_, options); } @@ -91,108 +114,85 @@ MessageFieldGenerator::~MessageFieldGenerator() {} void MessageFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, "$type$* $name$_;\n"); -} - -void MessageFieldGenerator:: -GenerateGetterDeclaration(io::Printer* printer) const { - printer->Print(variables_, - "$deprecated_attr$const $type$& $name$() const;\n"); -} - -void MessageFieldGenerator:: -GenerateDependentAccessorDeclarations(io::Printer* printer) const { - if (!dependent_field_) { - return; + if (implicit_weak_field_) { + printer->Print(variables_, "google::protobuf::MessageLite* $name$_;\n"); + } else { + printer->Print(variables_, "$type$* $name$_;\n"); } - // Arena manipulation code is out-of-line in the derived message class. - printer->Print(variables_, - "$deprecated_attr$$type$* mutable_$name$();\n" - "$deprecated_attr$$type$* $release_name$();\n" - "$deprecated_attr$void set_allocated_$name$($type$* $name$);\n"); } void MessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { - if (SupportsArenas(descriptor_)) { + if (implicit_weak_field_) { + // These private accessors are used by MergeFrom and + // MergePartialFromCodedStream, and their purpose is to provide access to + // the field without creating a strong dependency on the message type. printer->Print(variables_, "private:\n" - "void _slow_mutable_$name$();\n"); - if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, - "void _slow_set_allocated_$name$(\n" - " ::google::protobuf::Arena* message_arena, $type$** $name$);\n"); - } - printer->Print(variables_, - "$type$* _slow_$release_name$();\n" + "const google::protobuf::MessageLite& _internal_$name$() const;\n" + "google::protobuf::MessageLite* _internal_mutable_$name$();\n" "public:\n"); } - GenerateGetterDeclaration(printer); - if (!dependent_field_) { - printer->Print(variables_, - "$deprecated_attr$$type$* mutable_$name$();\n" - "$deprecated_attr$$type$* $release_name$();\n" - "$deprecated_attr$void set_allocated_$name$($type$* $name$);\n"); - } + printer->Print(variables_, + "$deprecated_attr$const $type$& $name$() const;\n"); + printer->Annotate("name", descriptor_); + printer->Print(variables_, "$deprecated_attr$$type$* $release_name$();\n"); + printer->Annotate("release_name", descriptor_); + printer->Print(variables_, + "$deprecated_attr$$type$* ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$set_allocated_$name$$}$" + "($type$* $name$);\n"); + printer->Annotate("{", "}", descriptor_); if (SupportsArenas(descriptor_)) { printer->Print(variables_, - "$deprecated_attr$$type$* unsafe_arena_release_$name$();\n" - "$deprecated_attr$void unsafe_arena_set_allocated_$name$(\n" - " $type$* $name$);\n"); + "$deprecated_attr$void " + "${$unsafe_arena_set_allocated_$name$$}$(\n" + " $type$* $name$);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$$type$* ${$unsafe_arena_release_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); } } void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( io::Printer* printer) const { - if (SupportsArenas(descriptor_)) { + if (implicit_weak_field_) { 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" + "const google::protobuf::MessageLite& $classname$::_internal_$name$() const {\n" + " if ($name$_ != NULL) {\n" + " return *$name$_;\n" + " } else if (&$type_default_instance$ != NULL) {\n" + " return *reinterpret_cast<const google::protobuf::MessageLite*>(\n" + " &$type_default_instance$);\n" " } else {\n" - " $type$* temp = new $type$(*$name$_);\n" - " $name$_ = NULL;\n" - " return temp;\n" + " return *reinterpret_cast<const google::protobuf::MessageLite*>(\n" + " &::google::protobuf::internal::implicit_weak_message_default_instance);\n" " }\n" - "}\n" - "$type$* $classname$::unsafe_arena_release_$name$() {\n" - " // @@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n" - " $clear_hasbit$\n" - " $type$* temp = $name$_;\n" - " $name$_ = NULL;\n" - " return temp;\n" "}\n"); - if (SupportsArenas(descriptor_->message_type())) { - // NOTE: the same logic is mirrored in weak_message_field.cc. Any - // arena-related semantics changes should be made in both places. + } + if (SupportsArenas(descriptor_)) { + if (implicit_weak_field_) { 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"); + "google::protobuf::MessageLite* $classname$::_internal_mutable_$name$() {\n" + " $set_hasbit$\n" + " if ($name$_ == NULL) {\n" + " if (&$type_default_instance$ == NULL) {\n" + " $name$_ = ::google::protobuf::Arena::CreateMessage<\n" + " ::google::protobuf::internal::ImplicitWeakMessage>(\n" + " GetArenaNoVirtual());\n" + " } else {\n" + " $name$_ = reinterpret_cast<const google::protobuf::MessageLite*>(\n" + " &$type_default_instance$)->New(GetArenaNoVirtual());\n" + " }\n" + " }\n" + " return $name$_;\n" + "}\n"); } + printer->Print(variables_, "void $classname$::unsafe_arena_set_allocated_$name$(\n" " $type$* $name$) {\n" @@ -210,279 +210,148 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( " // @@protoc_insertion_point(field_unsafe_arena_set_allocated" ":$full_name$)\n" "}\n"); + } else if (implicit_weak_field_) { + printer->Print(variables_, + "google::protobuf::MessageLite* $classname$::_internal_mutable_$name$() {\n" + " $set_hasbit$\n" + " if ($name$_ == NULL) {\n" + " if (&$type_default_instance$ == NULL) {\n" + " $name$_ = new ::google::protobuf::internal::ImplicitWeakMessage;\n" + " } else {\n" + " $name$_ = reinterpret_cast<const google::protobuf::MessageLite*>(\n" + " &$type_default_instance$)->New();\n" + " }\n" + " }\n" + " return $name$_;\n" + "}\n"); } } void MessageFieldGenerator:: -GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { - if (!dependent_field_) { - return; - } +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline const $type$& $classname$::$name$() const {\n" + "$type_reference_function$" + " const $type$* p = $casted_member$;\n" + " // @@protoc_insertion_point(field_get:$full_name$)\n" + " return p != NULL ? *p : *reinterpret_cast<const $type$*>(\n" + " &$type_default_instance$);\n" + "}\n"); - std::map<string, string> variables(variables_); - // For the CRTP base class, all mutation methods are dependent, and so - // they must be in the header. - variables["dependent_classname"] = - DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>"; - variables["this_message"] = DependentBaseDownCast(); - if (!variables["set_hasbit"].empty()) { - variables["set_hasbit"] = - variables["this_message"] + variables["set_hasbit"]; - } - if (!variables["clear_hasbit"].empty()) { - variables["clear_hasbit"] = - variables["this_message"] + variables["clear_hasbit"]; + printer->Print(variables_, + "inline $type$* $classname$::$release_name$() {\n" + " // @@protoc_insertion_point(field_release:$full_name$)\n" + "$type_reference_function$" + " $clear_hasbit$\n" + " $type$* temp = $casted_member$;\n"); + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (GetArenaNoVirtual() != NULL) {\n" + " temp = ::google::protobuf::internal::DuplicateIfNonNull(temp, NULL);\n" + " }\n"); } + printer->Print(variables_, + " $name$_ = NULL;\n" + " return temp;\n" + "}\n"); if (SupportsArenas(descriptor_)) { - printer->Print(variables, - "template <class T>\n" - "inline $type$* $dependent_classname$::mutable_$name$() {\n" - " $set_hasbit$\n" - " $dependent_typename$*& $name$_ = $this_message$$name$_;\n" - " if ($name$_ == NULL) {\n" - " $this_message$_slow_mutable_$name$();\n" - " }\n" - " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $name$_;\n" - "}\n" - "template <class T>\n" - "inline $type$* $dependent_classname$::$release_name$() {\n" - " // @@protoc_insertion_point(field_release:$full_name$)\n" - " $dependent_typename$*& $name$_ = $this_message$$name$_;\n" - " $clear_hasbit$\n" - " if ($this_message$GetArenaNoVirtual() != NULL) {\n" - " return $this_message$_slow_$release_name$();\n" - " } else {\n" - " $dependent_typename$* temp = $name$_;\n" - " $name$_ = NULL;\n" - " return temp;\n" - " }\n" - "}\n" - "template <class T>\n" - "inline void $dependent_classname$::" - "set_allocated_$name$($type$* $name$) {\n" - " ::google::protobuf::Arena* message_arena = $this_message$GetArenaNoVirtual();\n" - " $dependent_typename$*& $name$_ = $this_message$$name$_;\n" - " if (message_arena == NULL) {\n" - " delete $name$_;\n" - " }\n" - " if ($name$ != NULL) {\n"); - if (SupportsArenas(descriptor_->message_type())) { - // If we're on an arena and the incoming message is not, simply Own() it - // rather than copy to the arena -- either way we need a heap dealloc, - // 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, - " $this_message$_slow_set_allocated_$name$(message_arena, " - "&$name$);\n"); - } else { - printer->Print(variables, - " if (message_arena != NULL) {\n" - " message_arena->Own($name$);\n" - " }\n"); - } - printer->Print(variables, - " }\n" - " $name$_ = $name$;\n" - " if ($name$) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - // TODO(dlj): move insertion points to message class. - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); - } else { - printer->Print(variables, - "template <class T>\n" - "inline $type$* $dependent_classname$::mutable_$name$() {\n" - " $set_hasbit$\n" - " $dependent_typename$*& $name$_ = $this_message$$name$_;\n" - " if ($name$_ == NULL) {\n" - " $name$_ = new $dependent_typename$;\n" - " }\n" - " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $name$_;\n" - "}\n" - "template <class T>\n" - "inline $type$* $dependent_classname$::$release_name$() {\n" - " // @@protoc_insertion_point(field_release:$full_name$)\n" + printer->Print(variables_, + "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" + " // @@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n" + "$type_reference_function$" " $clear_hasbit$\n" - " $dependent_typename$*& $name$_ = $this_message$$name$_;\n" - " $dependent_typename$* temp = $name$_;\n" + " $type$* temp = $casted_member$;\n" " $name$_ = NULL;\n" " return temp;\n" - "}\n" - "template <class T>\n" - "inline void $dependent_classname$::" - "set_allocated_$name$($type$* $name$) {\n" - " $dependent_typename$*& $name$_ = $this_message$$name$_;\n" - " delete $name$_;\n"); - - if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables, - " if ($name$ != NULL && static_cast< $dependent_typename$* >($name$)" - "->GetArena() != NULL) {\n" - " $dependent_typename$* new_$name$ = new $dependent_typename$;\n" - " new_$name$->CopyFrom(*$name$);\n" - " $name$ = new_$name$;\n" - " }\n"); - } - - printer->Print(variables, - " $name$_ = $name$;\n" - " if ($name$) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n"); } -} -void MessageFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const { - if (dependent_field_) { - // for dependent fields we cannot access its internal_default_instance, - // because the type is incomplete. - // TODO(gerbens) deprecate dependent base class. - std::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" - " return $name$_ != NULL ? *$name$_\n" - " : *internal_default_instance()->$name$_;\n" - "}\n"); - return; + printer->Print(variables_, + "inline $type$* $classname$::mutable_$name$() {\n" + "$type_reference_function$" + " $set_hasbit$\n" + " if ($name$_ == NULL) {\n"); + if (implicit_weak_field_) { + printer->Print(variables_, + " _internal_mutable_$name$();\n"); + } else { + printer->Print(variables_, + " $name$_ = ::google::protobuf::Arena::$create_func$< $type$ >(\n" + " GetArenaNoVirtual());\n"); } - - std::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" - " return $name$_ != NULL ? *$name$_\n" - " : *$type$::internal_default_instance();\n" + printer->Print(variables_, + " }\n" + " // @@protoc_insertion_point(field_mutable:$full_name$)\n" + " return $casted_member$;\n" "}\n"); - if (SupportsArenas(descriptor_)) { - printer->Print(variables, - "$inline$" - "$type$* $classname$::mutable_$name$() {\n" - " $set_hasbit$\n" - " if ($name$_ == NULL) {\n" - " _slow_mutable_$name$();\n" - " }\n" - " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $name$_;\n" - "}\n" - "$inline$" - "$type$* $classname$::$release_name$() {\n" - " // @@protoc_insertion_point(field_release:$full_name$)\n" - " $clear_hasbit$\n" - " if (GetArenaNoVirtual() != NULL) {\n" - " return _slow_$release_name$();\n" - " } else {\n" - " $type$* temp = $name$_;\n" - " $name$_ = NULL;\n" - " return temp;\n" - " }\n" - "}\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"); - if (SupportsArenas(descriptor_->message_type())) { - // If we're on an arena and the incoming message is not, simply Own() it - // rather than copy to the arena -- either way we need a heap dealloc, - // 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, - " _slow_set_allocated_$name$(message_arena, &$name$);\n"); - } else { - printer->Print(variables, - " if (message_arena != NULL) {\n" - " message_arena->Own($name$);\n" - " }\n"); - } - printer->Print(variables, - " }\n" - " $name$_ = $name$;\n" - " if ($name$) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); + // We handle the most common case inline, and delegate less common cases to + // the slow fallback function. + printer->Print(variables_, + "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" + " ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();\n"); + printer->Print(variables_, + " if (message_arena == NULL) {\n"); + if (IsCrossFileMessage(descriptor_)) { + printer->Print(variables_, + " delete reinterpret_cast< ::google::protobuf::MessageLite*>($name$_);\n"); } else { - printer->Print(variables, - "$inline$" - "$type$* $classname$::mutable_$name$() {\n" - " $set_hasbit$\n" - " if ($name$_ == NULL) {\n" - " $name$_ = new $type$;\n" - " }\n" - " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $name$_;\n" - "}\n" - "$inline$" - "$type$* $classname$::$release_name$() {\n" - " // @@protoc_insertion_point(field_release:$full_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" - " delete $name$_;\n"); - - if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables, - " if ($name$ != NULL && $name$->GetArena() != NULL) {\n" - " $type$* new_$name$ = new $type$;\n" - " new_$name$->CopyFrom(*$name$);\n" - " $name$ = new_$name$;\n" - " }\n"); - } - - printer->Print(variables, - " $name$_ = $name$;\n" - " if ($name$) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); + printer->Print(variables_, + " delete $name$_;\n"); + } + printer->Print(variables_, + " }\n" + " if ($name$) {\n"); + if (SupportsArenas(descriptor_->message_type()) && + IsCrossFileMessage(descriptor_)) { + // We have to read the arena through the virtual method, because the type + // isn't defined in this file. + printer->Print(variables_, + " ::google::protobuf::Arena* submessage_arena =\n" + " reinterpret_cast< ::google::protobuf::MessageLite*>($name$)->GetArena();\n"); + } else if (!SupportsArenas(descriptor_->message_type())) { + printer->Print(variables_, + " ::google::protobuf::Arena* submessage_arena = NULL;\n"); + } else { + printer->Print(variables_, + " ::google::protobuf::Arena* submessage_arena =\n" + " ::google::protobuf::Arena::GetArena($name$);\n"); } + printer->Print(variables_, + " if (message_arena != submessage_arena) {\n" + " $name$ = ::google::protobuf::internal::GetOwnedMessage(\n" + " message_arena, $name$, submessage_arena);\n" + " }\n" + " $set_hasbit$\n" + " } else {\n" + " $clear_hasbit$\n" + " }\n"); + if (implicit_weak_field_) { + printer->Print(variables_, + " $name$_ = reinterpret_cast<MessageLite*>($name$);\n"); + } else { + printer->Print(variables_, + " $name$_ = $name$;\n"); + } + printer->Print(variables_, + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n"); } void MessageFieldGenerator:: GenerateClearingCode(io::Printer* printer) const { - std::map<string, string> variables(variables_); - variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; if (!HasFieldPresence(descriptor_->file())) { // If we don't have has-bits, message presence is indicated only by ptr != // NULL. Thus on clear, we need to delete the object. - printer->Print(variables, - "if ($this_message$GetArenaNoVirtual() == NULL && " - "$this_message$$name$_ != NULL) delete $this_message$$name$_;\n" - "$this_message$$name$_ = NULL;\n"); + printer->Print(variables_, + "if (GetArenaNoVirtual() == NULL && $name$_ != NULL) {\n" + " delete $name$_;\n" + "}\n" + "$name$_ = NULL;\n"); } else { - printer->Print(variables, - "if ($this_message$$name$_ != NULL) $this_message$$name$_->" - "$dependent_type$::Clear();\n"); + printer->Print(variables_, + "if ($name$_ != NULL) $name$_->Clear();\n"); } } @@ -499,30 +368,36 @@ GenerateMessageClearingCode(io::Printer* printer) const { } else { printer->Print(variables_, "GOOGLE_DCHECK($name$_ != NULL);\n" - "$name$_->$type$::Clear();\n"); + "$name$_->Clear();\n"); } } void MessageFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "mutable_$name$()->$type$::MergeFrom(from.$name$());\n"); + if (implicit_weak_field_) { + printer->Print(variables_, + "_internal_mutable_$name$()->CheckTypeAndMergeFrom(\n" + " from._internal_$name$());\n"); + } else { + printer->Print(variables_, + "mutable_$name$()->$type$::MergeFrom(from.$name$());\n"); + } } void MessageFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); + printer->Print(variables_, "swap($name$_, other->$name$_);\n"); } void MessageFieldGenerator:: GenerateDestructorCode(io::Printer* printer) const { + // TODO(gerbens) Remove this when we don't need to destruct default instances. // In google3 a default instance will never get deleted so we don't need to // worry about that but in opensource protobuf default instances are deleted // in shutdown process and we need to take special care when handling them. printer->Print(variables_, - "if (this != internal_default_instance()) {\n" - " delete $name$_;\n" - "}\n"); + "if (this != internal_default_instance()) "); + printer->Print(variables_, "delete $name$_;\n"); } void MessageFieldGenerator:: @@ -532,25 +407,6 @@ GenerateConstructorCode(io::Printer* printer) const { void MessageFieldGenerator:: GenerateCopyConstructorCode(io::Printer* printer) const { - // For non-Arena enabled messages, everything always goes on the heap. - // - // For Arena enabled messages, the logic is a bit more convoluted. - // - // In the copy constructor, we call InternalMetadataWithArena::MergeFrom, - // which does *not* copy the Arena pointer. In the generated MergeFrom - // (see MessageFieldGenerator::GenerateMergingCode), we: - // -> copy the has bits (but this is done in bulk by a memcpy in the copy - // constructor) - // -> check whether the destination field pointer is NULL (it will be, since - // we're initializing it and would have called SharedCtor) and if so: - // -> call _slow_mutable_$name$(), which calls either - // ::google::protobuf::Arena::CreateMessage<>(GetArenaNoVirtual()), or - // ::google::protobuf::Arena::Create<>(GetArenaNoVirtual()) - // - // At this point, GetArenaNoVirtual returns NULL since the Arena pointer - // wasn't copied, so both of these methods allocate the submessage on the - // heap. - printer->Print(variables_, "if (from.has_$name$()) {\n" " $name$_ = new $type$(*from.$name$_);\n" @@ -561,13 +417,17 @@ GenerateCopyConstructorCode(io::Printer* printer) const { void MessageFieldGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) const { - if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { + if (implicit_weak_field_) { printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n" + "DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(\n" + " input, _internal_mutable_$name$()));\n"); + } else if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { + printer->Print(variables_, + "DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(\n" " input, mutable_$name$()));\n"); } else { printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n" + "DO_(::google::protobuf::internal::WireFormatLite::ReadGroup(\n" " $number$, input, mutable_$name$()));\n"); } } @@ -576,23 +436,23 @@ void MessageFieldGenerator:: GenerateSerializeWithCachedSizes(io::Printer* printer) const { printer->Print(variables_, "::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n" - " $number$, *$non_null_ptr_to_name$, output);\n"); + " $number$, *$field_member$, output);\n"); } void MessageFieldGenerator:: GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { printer->Print(variables_, "target = ::google::protobuf::internal::WireFormatLite::\n" - " InternalWrite$declared_type$NoVirtualToArray(\n" - " $number$, *$non_null_ptr_to_name$, deterministic, target);\n"); + " InternalWrite$declared_type$ToArray(\n" + " $number$, *$field_member$, deterministic, target);\n"); } void MessageFieldGenerator:: GenerateByteSize(io::Printer* printer) const { printer->Print(variables_, "total_size += $tag_size$ +\n" - " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n" - " *$non_null_ptr_to_name$);\n"); + " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n" + " *$field_member$);\n"); } // =================================================================== @@ -607,177 +467,85 @@ MessageOneofFieldGenerator(const FieldDescriptor* descriptor, MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {} - -void MessageOneofFieldGenerator:: -GenerateDependentAccessorDeclarations(io::Printer* printer) const { - // Oneof field getters must be dependent as they call default_instance(). - // Otherwise, the logic is the same as MessageFields. - if (!dependent_field_) { - return; - } +void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions( + io::Printer* printer) const { printer->Print(variables_, - "$deprecated_attr$const $type$& $name$() const;\n"); - MessageFieldGenerator::GenerateDependentAccessorDeclarations(printer); -} - -void MessageOneofFieldGenerator:: -GenerateGetterDeclaration(io::Printer* printer) const { - // Oneof field getters must be dependent as they call default_instance(). - // Unlike MessageField, this means there is no (non-dependent) getter to - // generate. - if (dependent_field_) { - return; + "void $classname$::set_allocated_$name$($type$* $name$) {\n" + " ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();\n" + " clear_$oneof_name$();\n" + " if ($name$) {\n"); + if (SupportsArenas(descriptor_->message_type()) && + descriptor_->file() != descriptor_->message_type()->file()) { + // We have to read the arena through the virtual method, because the type + // isn't defined in this file. + printer->Print(variables_, + " ::google::protobuf::Arena* submessage_arena =\n" + " reinterpret_cast< ::google::protobuf::MessageLite*>($name$)->GetArena();\n"); + } else if (!SupportsArenas(descriptor_->message_type())) { + printer->Print(variables_, + " ::google::protobuf::Arena* submessage_arena = NULL;\n"); + } else { + printer->Print(variables_, + " ::google::protobuf::Arena* submessage_arena =\n" + " ::google::protobuf::Arena::GetArena($name$);\n"); } printer->Print(variables_, - "$deprecated_attr$const $type$& $name$() const;\n"); -} - -void MessageOneofFieldGenerator:: -GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { - // For the CRTP base class, all mutation methods are dependent, and so - // they must be in the header. - if (!dependent_base_) { - return; - } - std::map<string, string> variables(variables_); - variables["inline"] = "inline "; - variables["dependent_classname"] = - DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>"; - variables["this_message"] = "reinterpret_cast<T*>(this)->"; - // Const message access is needed for the dependent getter. - variables["this_const_message"] = "reinterpret_cast<const T*>(this)->"; - variables["tmpl"] = "template <class T>\n"; - variables["field_member"] = variables["this_message"] + - variables["oneof_prefix"] + variables["name"] + - "_"; - InternalGenerateInlineAccessorDefinitions(variables, printer); + " if (message_arena != submessage_arena) {\n" + " $name$ = ::google::protobuf::internal::GetOwnedMessage(\n" + " message_arena, $name$, submessage_arena);\n" + " }\n" + " set_has_$name$();\n" + " $field_member$ = $name$;\n" + " }\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n"); } void MessageOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const { - if (dependent_base_) { - return; +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline $type$* $classname$::$release_name$() {\n" + " // @@protoc_insertion_point(field_release:$full_name$)\n" + " if (has_$name$()) {\n" + " clear_has_$oneof_name$();\n" + " $type$* temp = $field_member$;\n"); + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (GetArenaNoVirtual() != NULL) {\n" + " temp = ::google::protobuf::internal::DuplicateIfNonNull(temp, NULL);\n" + " }\n"); } - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; - variables["dependent_classname"] = variables["classname"]; - variables["this_message"] = ""; - variables["this_const_message"] = ""; - variables["tmpl"] = ""; - variables["field_member"] = - variables["oneof_prefix"] + variables["name"] + "_"; - variables["dependent_type"] = variables["type"]; - InternalGenerateInlineAccessorDefinitions(variables, printer); -} + printer->Print(variables_, + " $field_member$ = NULL;\n" + " return temp;\n" + " } else {\n" + " return NULL;\n" + " }\n" + "}\n"); -void MessageOneofFieldGenerator::InternalGenerateInlineAccessorDefinitions( - const std::map<string, string>& variables, io::Printer* printer) const { - printer->Print(variables, - "$tmpl$" - "$inline$ " - "const $type$& $dependent_classname$::$name$() const {\n" + printer->Print(variables_, + "inline const $type$& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" - " return $this_const_message$has_$name$()\n" - " ? *$this_const_message$$oneof_prefix$$name$_\n" - " : $dependent_type$::default_instance();\n" + " return has_$name$()\n" + " ? *$field_member$\n" + " : *reinterpret_cast< $type$*>(&$type_default_instance$);\n" "}\n"); if (SupportsArenas(descriptor_)) { - printer->Print(variables, - "$tmpl$" - "$inline$" - "$type$* $dependent_classname$::mutable_$name$() {\n" - " if (!$this_message$has_$name$()) {\n" - " $this_message$clear_$oneof_name$();\n" - " $this_message$set_has_$name$();\n"); - if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables, - " $field_member$ = \n" - " ::google::protobuf::Arena::CreateMessage< $dependent_typename$ >(\n" - " $this_message$GetArenaNoVirtual());\n"); - } else { - printer->Print(variables, - " $this_message$$oneof_prefix$$name$_ = \n" - " ::google::protobuf::Arena::Create< $dependent_typename$ >(\n" - " $this_message$GetArenaNoVirtual());\n"); - } - printer->Print(variables, - " }\n" - " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $field_member$;\n" - "}\n" - "$tmpl$" - "$inline$" - "$type$* $dependent_classname$::$release_name$() {\n" - " // @@protoc_insertion_point(field_release:$full_name$)\n" - " if ($this_message$has_$name$()) {\n" - " $this_message$clear_has_$oneof_name$();\n" - " if ($this_message$GetArenaNoVirtual() != NULL) {\n" - // N.B.: safe to use the underlying field pointer here because we are sure - // that it is non-NULL (because has_$name$() returned true). - " $dependent_typename$* temp = " - "new $dependent_typename$(*$field_member$);\n" - " $field_member$ = NULL;\n" - " return temp;\n" - " } else {\n" - " $dependent_typename$* temp = $field_member$;\n" - " $field_member$ = NULL;\n" - " return temp;\n" - " }\n" - " } else {\n" - " return NULL;\n" - " }\n" - "}\n" - "$tmpl$" - "$inline$" - "void $dependent_classname$::" - "set_allocated_$name$($type$* $name$) {\n" - " $this_message$clear_$oneof_name$();\n" - " if ($name$) {\n"); - - if (SupportsArenas(descriptor_->message_type())) { - 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. - " if ($this_message$GetArenaNoVirtual() != NULL &&\n" - " ::google::protobuf::Arena::GetArena($name$) == NULL) {\n" - " $this_message$GetArenaNoVirtual()->Own($name$);\n" - " } else if ($this_message$GetArenaNoVirtual() !=\n" - " ::google::protobuf::Arena::GetArena($name$)) {\n" - " $dependent_typename$* new_$name$ = \n" - " ::google::protobuf::Arena::CreateMessage< $dependent_typename$ >(\n" - " $this_message$GetArenaNoVirtual());\n" - " new_$name$->CopyFrom(*$name$);\n" - " $name$ = new_$name$;\n" - " }\n"); - } else { - printer->Print(variables, - " if ($this_message$GetArenaNoVirtual() != NULL) {\n" - " $this_message$GetArenaNoVirtual()->Own($name$);\n" - " }\n"); - } - - printer->Print(variables, - " $this_message$set_has_$name$();\n" - " $field_member$ = $name$;\n" - " }\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n" - "$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n" + printer->Print(variables_, + "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" " // @@protoc_insertion_point(field_unsafe_arena_release" ":$full_name$)\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " $type$* temp = $oneof_prefix$$name$_;\n" - " $oneof_prefix$$name$_ = NULL;\n" + " $type$* temp = $field_member$;\n" + " $field_member$ = NULL;\n" " return temp;\n" " } else {\n" " return NULL;\n" " }\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 @@ -785,73 +553,36 @@ void MessageOneofFieldGenerator::InternalGenerateInlineAccessorDefinitions( " clear_$oneof_name$();\n" " if ($name$) {\n" " set_has_$name$();\n" - " $oneof_prefix$$name$_ = $name$;\n" + " $field_member$ = $name$;\n" " }\n" " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:" "$full_name$)\n" "}\n"); - } else { - printer->Print(variables, - "$tmpl$" - "$inline$" - "$type$* $dependent_classname$::mutable_$name$() {\n" - " if (!$this_message$has_$name$()) {\n" - " $this_message$clear_$oneof_name$();\n" - " $this_message$set_has_$name$();\n" - " $field_member$ = new $dependent_typename$;\n" - " }\n" - " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $field_member$;\n" - "}\n" - "$tmpl$" - "$inline$" - "$type$* $dependent_classname$::$release_name$() {\n" - " // @@protoc_insertion_point(field_release:$full_name$)\n" - " if ($this_message$has_$name$()) {\n" - " $this_message$clear_has_$oneof_name$();\n" - " $dependent_typename$* temp = $field_member$;\n" - " $field_member$ = NULL;\n" - " return temp;\n" - " } else {\n" - " return NULL;\n" - " }\n" - "}\n" - "$tmpl$" - "$inline$" - "void $dependent_classname$::" - "set_allocated_$name$($type$* $name$) {\n" - " $this_message$clear_$oneof_name$();\n" - " if ($name$) {\n"); - if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables, - " if (static_cast< $dependent_typename$*>($name$)->" - "GetArena() != NULL) {\n" - " $dependent_typename$* new_$name$ = new $dependent_typename$;\n" - " new_$name$->CopyFrom(*$name$);\n" - " $name$ = new_$name$;\n" - " }\n"); - } - printer->Print(variables, - " $this_message$set_has_$name$();\n" - " $field_member$ = $name$;\n" - " }\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); } + + printer->Print(variables_, + "inline $type$* $classname$::mutable_$name$() {\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$ = ::google::protobuf::Arena::$create_func$< $type$ >(\n" + " GetArenaNoVirtual());\n" + " }\n" + " // @@protoc_insertion_point(field_mutable:$full_name$)\n" + " return $field_member$;\n" + "}\n"); } void MessageOneofFieldGenerator:: GenerateClearingCode(io::Printer* printer) const { - std::map<string, string> variables(variables_); - variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; if (SupportsArenas(descriptor_)) { - printer->Print(variables, - "if ($this_message$GetArenaNoVirtual() == NULL) {\n" - " delete $this_message$$oneof_prefix$$name$_;\n" + printer->Print(variables_, + "if (GetArenaNoVirtual() == NULL) {\n" + " delete $field_member$;\n" "}\n"); } else { - printer->Print(variables, - "delete $this_message$$oneof_prefix$$name$_;\n"); + printer->Print(variables_, + "delete $field_member$;\n"); } } @@ -884,7 +615,7 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( : FieldGenerator(options), descriptor_(descriptor), dependent_field_(options.proto_h && IsFieldDependent(descriptor)), - dependent_getter_(dependent_field_ && options.safe_boundary_check) { + implicit_weak_field_(IsImplicitWeakField(descriptor, options)) { SetMessageVariables(descriptor, &variables_, options); } @@ -898,25 +629,12 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedMessageFieldGenerator:: InternalGenerateTypeDependentAccessorDeclarations(io::Printer* printer) const { - printer->Print(variables_, - "$deprecated_attr$$type$* mutable_$name$(int index);\n" - "$deprecated_attr$$type$* add_$name$();\n"); - if (dependent_getter_) { - printer->Print(variables_, - "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< $type$ >&\n" - " $name$() const;\n"); - } - printer->Print(variables_, - "$deprecated_attr$::google::protobuf::RepeatedPtrField< $type$ >*\n" - " mutable_$name$();\n"); + printer->Print(variables_, "$deprecated_attr$$type$* ${$add_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedMessageFieldGenerator:: GenerateDependentAccessorDeclarations(io::Printer* printer) const { - if (dependent_getter_) { - printer->Print(variables_, - "$deprecated_attr$const $type$& $name$(int index) const;\n"); - } if (dependent_field_) { InternalGenerateTypeDependentAccessorDeclarations(printer); } @@ -924,18 +642,24 @@ GenerateDependentAccessorDeclarations(io::Printer* printer) const { void RepeatedMessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { - if (!dependent_getter_) { - printer->Print(variables_, - "$deprecated_attr$const $type$& $name$(int index) const;\n"); - } + printer->Print(variables_, + "$deprecated_attr$$type$* ${$mutable_$name$$}$(int index);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$::google::protobuf::RepeatedPtrField< $type$ >*\n" + " ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + + printer->Print(variables_, + "$deprecated_attr$const $type$& $name$(int index) const;\n"); + printer->Annotate("name", descriptor_); if (!dependent_field_) { InternalGenerateTypeDependentAccessorDeclarations(printer); } - if (!dependent_getter_) { - printer->Print(variables_, - "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< $type$ >&\n" - " $name$() const;\n"); - } + printer->Print(variables_, + "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< $type$ >&\n" + " $name$() const;\n"); + printer->Annotate("name", descriptor_); } void RepeatedMessageFieldGenerator:: @@ -951,114 +675,97 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { variables["this_message"] = DependentBaseDownCast(); variables["this_const_message"] = DependentBaseConstDownCast(); - if (dependent_getter_) { - printer->Print(variables, - "template <class T>\n" - "inline const $type$& $dependent_classname$::$name$(int index) const {\n" - " // @@protoc_insertion_point(field_get:$full_name$)\n" - " return $this_const_message$$name$_.$cppget$(index);\n" - "}\n"); - } - // Generate per-element accessors: printer->Print(variables, "template <class T>\n" - "inline $type$* $dependent_classname$::mutable_$name$(int index) {\n" - // TODO(dlj): move insertion points - " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $this_message$$name$_.Mutable(index);\n" - "}\n" - "template <class T>\n" "inline $type$* $dependent_classname$::add_$name$() {\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" + "$type_reference_function$" " return $this_message$$name$_.Add();\n" "}\n"); +} - if (dependent_getter_) { - printer->Print(variables, - "template <class T>\n" - "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" - "$dependent_classname$::$name$() const {\n" - " // @@protoc_insertion_point(field_list:$full_name$)\n" - " return $this_const_message$$name$_;\n" - "}\n"); - } - - // Generate mutable access to the entire list: - printer->Print(variables, - "template <class T>\n" +void RepeatedMessageFieldGenerator:: +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + printer->Print(variables_, + "inline $type$* $classname$::mutable_$name$(int index) {\n" + // TODO(dlj): move insertion points + " // @@protoc_insertion_point(field_mutable:$full_name$)\n" + "$type_reference_function$" + " return $name$_.Mutable(index);\n" + "}\n" "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" - "$dependent_classname$::mutable_$name$() {\n" + "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" - " return &$this_message$$name$_;\n" + "$type_reference_function$" + " return &$name$_;\n" "}\n"); -} -void RepeatedMessageFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const { - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; - - if (!dependent_getter_) { - printer->Print(variables, - "$inline$" - "const $type$& $classname$::$name$(int index) const {\n" + if (options_.safe_boundary_check) { + 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" + "$type_reference_function$" + " return $name$_.InternalCheckedGet(index,\n" + " *reinterpret_cast<const $type$*>(&$type_default_instance$));\n" + "}\n"); + } else { + printer->Print(variables_, + "inline const $type$& $classname$::$name$(int index) const {\n" + " // @@protoc_insertion_point(field_get:$full_name$)\n" + "$type_reference_function$" + " return $name$_.Get(index);\n" "}\n"); } if (!dependent_field_) { - printer->Print(variables, - "$inline$" - "$type$* $classname$::mutable_$name$(int index) {\n" - // TODO(dlj): move insertion points - " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $name$_.Mutable(index);\n" - "}\n" - "$inline$" - "$type$* $classname$::add_$name$() {\n" + printer->Print(variables_, + "inline $type$* $classname$::add_$name$() {\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" + "$type_reference_function$" " return $name$_.Add();\n" "}\n"); } - if (!dependent_field_) { - printer->Print(variables, - "$inline$" - "::google::protobuf::RepeatedPtrField< $type$ >*\n" - "$classname$::mutable_$name$() {\n" - " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" - " return &$name$_;\n" - "}\n"); - } - if (!dependent_getter_) { - 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"); - } + printer->Print(variables_, + "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" + "$classname$::$name$() const {\n" + " // @@protoc_insertion_point(field_list:$full_name$)\n" + "$type_reference_function$" + " return $name$_;\n" + "}\n"); } void RepeatedMessageFieldGenerator:: GenerateClearingCode(io::Printer* printer) const { - std::map<string, string> variables(variables_); - variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; - printer->Print(variables, "$this_message$$name$_.Clear();\n"); + if (implicit_weak_field_) { + printer->Print( + variables_, + "CastToBase(&$name$_)->Clear<" + "::google::protobuf::internal::ImplicitWeakTypeHandler<$type$>>();\n"); + } else { + printer->Print(variables_, "$name$_.Clear();\n"); + } } void RepeatedMessageFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); + if (implicit_weak_field_) { + printer->Print( + variables_, + "CastToBase(&$name$_)->MergeFrom<" + "::google::protobuf::internal::ImplicitWeakTypeHandler<$type$>>(CastToBase(" + "from.$name$_));\n"); + } else { + printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); + } } void RepeatedMessageFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n"); + printer->Print( + variables_, + "CastToBase(&$name$_)->InternalSwap(CastToBase(&other->$name$_));\n"); } void RepeatedMessageFieldGenerator:: @@ -1069,34 +776,55 @@ GenerateConstructorCode(io::Printer* printer) const { void RepeatedMessageFieldGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) const { if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormatLite::" - "ReadMessageNoVirtual(\n" - " input, add_$name$()));\n"); + if (implicit_weak_field_) { + printer->Print(variables_, + "DO_(::google::protobuf::internal::WireFormatLite::" + "ReadMessage(input, CastToBase(&$name$_)->AddWeak(\n" + " reinterpret_cast<const ::google::protobuf::MessageLite*>(\n" + " &$type_default_instance$))));\n"); + } else { + printer->Print(variables_, + "DO_(::google::protobuf::internal::WireFormatLite::" + "ReadMessage(\n" + " input, add_$name$()));\n"); + } } else { printer->Print(variables_, "DO_(::google::protobuf::internal::WireFormatLite::" - "ReadGroupNoVirtual(\n" - " $number$, input, add_$name$()));\n"); + "ReadGroup($number$, input, add_$name$()));\n"); } } void RepeatedMessageFieldGenerator:: GenerateSerializeWithCachedSizes(io::Printer* printer) const { printer->Print(variables_, - "for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n" + "for (unsigned int i = 0,\n" + " n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n" " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n" - " $number$, this->$name$(i), output);\n" + " $number$,\n"); + if (implicit_weak_field_) { + printer->Print( + variables_, + " CastToBase($name$_).Get<" + "::google::protobuf::internal::ImplicitWeakTypeHandler<$type$>>(" + "static_cast<int>(i)),\n"); + } else { + printer->Print(variables_, + " this->$name$(static_cast<int>(i)),\n"); + } + printer->Print(variables_, + " output);\n" "}\n"); } void RepeatedMessageFieldGenerator:: GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { printer->Print(variables_, - "for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n" + "for (unsigned int i = 0,\n" + " n = static_cast<unsigned int>(this->$name$_size()); i < n; i++) {\n" " target = ::google::protobuf::internal::WireFormatLite::\n" - " InternalWrite$declared_type$NoVirtualToArray(\n" - " $number$, this->$name$(i), deterministic, target);\n" + " InternalWrite$declared_type$ToArray(\n" + " $number$, this->$name$(static_cast<int>(i)), deterministic, target);\n" "}\n"); } @@ -1104,15 +832,24 @@ void RepeatedMessageFieldGenerator:: GenerateByteSize(io::Printer* printer) const { printer->Print(variables_, "{\n" - " unsigned int count = this->$name$_size();\n"); + " unsigned int count = static_cast<unsigned int>(this->$name$_size());\n"); printer->Indent(); printer->Print(variables_, "total_size += $tag_size$UL * count;\n" "for (unsigned int i = 0; i < count; i++) {\n" " total_size +=\n" - " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n" - " this->$name$(i));\n" - "}\n"); + " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"); + if (implicit_weak_field_) { + printer->Print( + variables_, + " CastToBase($name$_).Get<" + "::google::protobuf::internal::ImplicitWeakTypeHandler<$type$>>(" + "static_cast<int>(i)));\n"); + } else { + printer->Print(variables_, + " this->$name$(static_cast<int>(i)));\n"); + } + printer->Print(variables_, "}\n"); printer->Outdent(); printer->Print("}\n"); } diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h index cd9737f0..e165404f 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h @@ -44,6 +44,8 @@ namespace protobuf { namespace compiler { namespace cpp { +bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options); + class MessageFieldGenerator : public FieldGenerator { public: MessageFieldGenerator(const FieldDescriptor* descriptor, @@ -52,11 +54,8 @@ class MessageFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; - void GenerateDependentAccessorDeclarations(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMessageClearingCode(io::Printer* printer) const; @@ -71,13 +70,8 @@ class MessageFieldGenerator : public FieldGenerator { void GenerateByteSize(io::Printer* printer) const; protected: - void GenerateArenaManipulationCode(const std::map<string, string>& variables, - io::Printer* printer) const; - - virtual void GenerateGetterDeclaration(io::Printer* printer) const; - const FieldDescriptor* descriptor_; - const bool dependent_field_; + const bool implicit_weak_field_; std::map<string, string> variables_; private: @@ -91,11 +85,8 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { ~MessageOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateDependentAccessorDeclarations(io::Printer* printer) const; - void GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; - void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const { } + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; // MessageFieldGenerator, from which we inherit, overrides this so we need to @@ -105,13 +96,7 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { void GenerateDestructorCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; - protected: - void GenerateGetterDeclaration(io::Printer* printer) const; - private: - void InternalGenerateInlineAccessorDefinitions( - const std::map<string, string>& variables, io::Printer* printer) const; - const bool dependent_base_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator); }; @@ -127,8 +112,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { void GenerateDependentAccessorDeclarations(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; void GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; @@ -145,7 +129,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { const FieldDescriptor* descriptor_; const bool dependent_field_; - const bool dependent_getter_; + const bool implicit_weak_field_; std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); diff --git a/src/google/protobuf/compiler/profile.proto b/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h index 09ebe091..d502a6f0 100644 --- a/src/google/protobuf/compiler/profile.proto +++ b/src/google/protobuf/compiler/cpp/cpp_message_layout_helper.h @@ -29,40 +29,33 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Author: seongkim@google.com (Seong Beom Kim) -// -// protoc (Protocol Compiler) can generate more efficient code -// if it knows how a workload accesses fields of a message; -// e.g. some much more frequently than others. -// -// Protos defined here describe the access information per message -// and per field. Note that one can use any methods to collect -// the access patterns like CPU profiling, instrumented build, etc. +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__ + +#include <google/protobuf/compiler/cpp/cpp_options.h> +#include <google/protobuf/descriptor.h> -syntax = "proto2"; +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { -package google.protobuf.compiler; +// Provides an abstract interface to optimize message layout +// by rearranging the fields of a message. +class MessageLayoutHelper { + public: + virtual ~MessageLayoutHelper() {} -// To convey the access pattern of a field, it classifies -// the type of the accessor methods into getters, setters and -// configs. Getters and setters read and write the field -// respectively and other operations like checking if the field -// exists are considered as configs. -message FieldAccessInfo { - optional string name = 1; - optional uint64 getters_count = 2; - optional uint64 setters_count = 3; - optional uint64 configs_count = 4; -} + virtual void OptimizeLayout(std::vector<const FieldDescriptor*>* fields, + const Options& options) = 0; +}; -// "count" correlates with how many samples an access info has -// for a message. High "count" means more confident optimization -// based on the info. -message MessageAccessInfo { - optional string name = 1; - optional uint64 count = 2; - repeated FieldAccessInfo field = 3; -} +} // namespace cpp +} // namespace compiler +} // namespace protobuf -message AccessInfo { - repeated MessageAccessInfo message = 1; -} +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc new file mode 100644 index 00000000..f72a7d60 --- /dev/null +++ b/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc @@ -0,0 +1,169 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/test_util.h> +#include <google/protobuf/unittest.pb.h> +#include <gtest/gtest.h> + +#if LANG_CXX11 +#include <google/protobuf/stubs/type_traits.h> +#endif + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. +namespace cpp_unittest { + +// Moves are enabled only when compiling with a C++11 compiler or newer. +#if LANG_CXX11 + +TEST(MovableMessageTest, MoveConstructor) { + protobuf_unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + const auto* nested = &message1.optional_nested_message(); + + protobuf_unittest::TestAllTypes message2(std::move(message1)); + TestUtil::ExpectAllFieldsSet(message2); + + // Check if the optional_nested_message was actually moved (and not just + // copied). + EXPECT_EQ(nested, &message2.optional_nested_message()); + EXPECT_NE(nested, &message1.optional_nested_message()); +} + +TEST(MovableMessageTest, MoveAssignmentOperator) { + protobuf_unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + const auto* nested = &message1.optional_nested_message(); + + protobuf_unittest::TestAllTypes message2; + message2 = std::move(message1); + TestUtil::ExpectAllFieldsSet(message2); + + // Check if the optional_nested_message was actually moved (and not just + // copied). + EXPECT_EQ(nested, &message2.optional_nested_message()); + EXPECT_NE(nested, &message1.optional_nested_message()); +} + +TEST(MovableMessageTest, SelfMoveAssignment) { + // The `self` reference is necessary to defeat -Wself-move. + protobuf_unittest::TestAllTypes message, &self = message; + TestUtil::SetAllFields(&message); + message = std::move(self); + TestUtil::ExpectAllFieldsSet(message); +} + +TEST(MovableMessageTest, MoveSameArena) { + Arena arena; + + auto* message1_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena); + TestUtil::SetAllFields(message1_on_arena); + const auto* nested = &message1_on_arena->optional_nested_message(); + + auto* message2_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena); + + // Moving messages on the same arena should lead to swapped pointers. + *message2_on_arena = std::move(*message1_on_arena); + EXPECT_EQ(nested, &message2_on_arena->optional_nested_message()); +} + +TEST(MovableMessageTest, MoveDifferentArenas) { + Arena arena1, arena2; + + auto* message1_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena1); + TestUtil::SetAllFields(message1_on_arena); + const auto* nested = &message1_on_arena->optional_nested_message(); + + auto* message2_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena2); + + // Moving messages on two different arenas should lead to a copy. + *message2_on_arena = std::move(*message1_on_arena); + EXPECT_NE(nested, &message2_on_arena->optional_nested_message()); + TestUtil::ExpectAllFieldsSet(*message1_on_arena); + TestUtil::ExpectAllFieldsSet(*message2_on_arena); +} + +TEST(MovableMessageTest, MoveFromArena) { + Arena arena; + + auto* message1_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena); + TestUtil::SetAllFields(message1_on_arena); + const auto* nested = &message1_on_arena->optional_nested_message(); + + protobuf_unittest::TestAllTypes message2; + + // Moving from a message on the arena should lead to a copy. + message2 = std::move(*message1_on_arena); + EXPECT_NE(nested, &message2.optional_nested_message()); + TestUtil::ExpectAllFieldsSet(*message1_on_arena); + TestUtil::ExpectAllFieldsSet(message2); +} + +TEST(MovableMessageTest, MoveToArena) { + Arena arena; + + protobuf_unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + const auto* nested = &message1.optional_nested_message(); + + auto* message2_on_arena = + Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena); + + // Moving to a message on the arena should lead to a copy. + *message2_on_arena = std::move(message1); + EXPECT_NE(nested, &message2_on_arena->optional_nested_message()); + TestUtil::ExpectAllFieldsSet(message1); + TestUtil::ExpectAllFieldsSet(*message2_on_arena); +} + +TEST(MovableMessageTest, Noexcept) { + EXPECT_TRUE( + std::is_nothrow_move_constructible<protobuf_unittest::TestAllTypes>()); + EXPECT_TRUE(std::is_nothrow_move_assignable<protobuf_unittest::TestAllTypes>()); +} + +#endif // LANG_CXX11 + +} // namespace cpp_unittest + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index bdaa12a5..b0dd8836 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -39,6 +39,8 @@ namespace google { namespace protobuf { namespace compiler { +class AccessInfoMap; + namespace cpp { // Generator options (see generator.cc for a description of each): @@ -49,7 +51,11 @@ struct Options { transitive_pb_h(true), annotate_headers(false), enforce_lite(false), - table_driven_parsing(false) {} + table_driven_parsing(false), + table_driven_serialization(false), + lite_implicit_weak_fields(false), + num_cc_files(0), + access_info_map(NULL) {} string dllexport_decl; bool safe_boundary_check; @@ -58,8 +64,12 @@ struct Options { bool annotate_headers; bool enforce_lite; bool table_driven_parsing; + bool table_driven_serialization; + bool lite_implicit_weak_fields; + int num_cc_files; string annotation_pragma_name; string annotation_guard_name; + const AccessInfoMap* access_info_map; }; } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc new file mode 100644 index 00000000..e9303865 --- /dev/null +++ b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc @@ -0,0 +1,220 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/compiler/cpp/cpp_padding_optimizer.h> + +#include <google/protobuf/compiler/cpp/cpp_helpers.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +namespace { + +// FieldGroup is just a helper for PaddingOptimizer below. It holds a vector of +// fields that are grouped together because they have compatible alignment, and +// a preferred location in the final field ordering. +class FieldGroup { + public: + FieldGroup() : preferred_location_(0) {} + + // A group with a single field. + FieldGroup(float preferred_location, const FieldDescriptor* field) + : preferred_location_(preferred_location), fields_(1, field) {} + + // Append the fields in 'other' to this group. + void Append(const FieldGroup& other) { + if (other.fields_.empty()) { + return; + } + // Preferred location is the average among all the fields, so we weight by + // the number of fields on each FieldGroup object. + preferred_location_ = (preferred_location_ * fields_.size() + + (other.preferred_location_ * other.fields_.size())) / + (fields_.size() + other.fields_.size()); + fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end()); + } + + void SetPreferredLocation(float location) { preferred_location_ = location; } + const std::vector<const FieldDescriptor*>& fields() const { return fields_; } + + // FieldGroup objects sort by their preferred location. + bool operator<(const FieldGroup& other) const { + return preferred_location_ < other.preferred_location_; + } + + private: + // "preferred_location_" is an estimate of where this group should go in the + // final list of fields. We compute this by taking the average index of each + // field in this group in the original ordering of fields. This is very + // approximate, but should put this group close to where its member fields + // originally went. + float preferred_location_; + std::vector<const FieldDescriptor*> fields_; + // We rely on the default copy constructor and operator= so this type can be + // used in a vector. +}; + +} // namespace + +// Reorder 'fields' so that if the fields are output into a c++ class in the new +// order, fields of similar family (see below) are together and within each +// family, alignment padding is minimized. +// +// We try to do this while keeping each field as close as possible to its field +// number order so that we don't reduce cache locality much for function that +// access each field in order. Originally, OptimizePadding used declaration +// order for its decisions, but generated code minus the serializer/parsers uses +// the output of OptimizePadding as well (stored in +// MessageGenerator::optimized_order_). Since the serializers use field number +// order, we use that as a tie-breaker. +// +// We classify each field into a particular "family" of fields, that we perform +// the same operation on in our generated functions. +// +// REPEATED is placed first, as the C++ compiler automatically initializes +// these fields in layout order. +// +// STRING is grouped next, as our Clear/SharedCtor/SharedDtor walks it and +// calls ArenaStringPtr::Destroy on each. +// +// +// MESSAGE is grouped next, as our Clear/SharedDtor code walks it and calls +// delete on each. We initialize these fields with a NULL pointer (see +// MessageFieldGenerator::GenerateConstructorCode), which allows them to be +// memset. +// +// ZERO_INITIALIZABLE is memset in Clear/SharedCtor +// +// OTHER these fields are initialized one-by-one. +void PaddingOptimizer::OptimizeLayout( + std::vector<const FieldDescriptor*>* fields, const Options& options) { + // The sorted numeric order of Family determines the declaration order in the + // memory layout. + enum Family { + REPEATED = 0, + STRING = 1, + MESSAGE = 3, + ZERO_INITIALIZABLE = 4, + OTHER = 5, + kMaxFamily + }; + + // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes. + std::vector<FieldGroup> aligned_to_1[kMaxFamily]; + std::vector<FieldGroup> aligned_to_4[kMaxFamily]; + std::vector<FieldGroup> aligned_to_8[kMaxFamily]; + for (int i = 0; i < fields->size(); ++i) { + const FieldDescriptor* field = (*fields)[i]; + + Family f = OTHER; + if (field->is_repeated()) { + f = REPEATED; + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + f = STRING; + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + f = MESSAGE; + + } else if (CanInitializeByZeroing(field)) { + f = ZERO_INITIALIZABLE; + } + + const int j = field->number(); + switch (EstimateAlignmentSize(field)) { + case 1: + aligned_to_1[f].push_back(FieldGroup(j, field)); + break; + case 4: + aligned_to_4[f].push_back(FieldGroup(j, field)); + break; + case 8: + aligned_to_8[f].push_back(FieldGroup(j, field)); + break; + default: + GOOGLE_LOG(FATAL) << "Unknown alignment size " << EstimateAlignmentSize(field) + << "for a field " << field->full_name() << "."; + } + } + + // For each family, group fields to optimize padding. + for (int f = 0; f < kMaxFamily; f++) { + // Now group fields aligned to 1 byte into sets of 4, and treat those like a + // single field aligned to 4 bytes. + for (int i = 0; i < aligned_to_1[f].size(); i += 4) { + FieldGroup field_group; + for (int j = i; j < aligned_to_1[f].size() && j < i + 4; ++j) { + field_group.Append(aligned_to_1[f][j]); + } + aligned_to_4[f].push_back(field_group); + } + // Sort by preferred location to keep fields as close to their field number + // order as possible. Using stable_sort ensures that the output is + // consistent across runs. + std::stable_sort(aligned_to_4[f].begin(), aligned_to_4[f].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. + for (int i = 0; i < aligned_to_4[f].size(); i += 2) { + FieldGroup field_group; + for (int j = i; j < aligned_to_4[f].size() && j < i + 2; ++j) { + field_group.Append(aligned_to_4[f][j]); + } + if (i == aligned_to_4[f].size() - 1) { + if (f == OTHER) { + // Move incomplete 4-byte block to the beginning. This is done to + // pair with the (possible) leftover blocks from the + // ZERO_INITIALIZABLE family. + field_group.SetPreferredLocation(-1); + } else { + // Move incomplete 4-byte block to the end. + field_group.SetPreferredLocation(fields->size() + 1); + } + } + aligned_to_8[f].push_back(field_group); + } + // Sort by preferred location. + std::stable_sort(aligned_to_8[f].begin(), aligned_to_8[f].end()); + } + + // Now pull out all the FieldDescriptors in order. + fields->clear(); + for (int f = 0; f < kMaxFamily; ++f) { + for (int i = 0; i < aligned_to_8[f].size(); ++i) { + fields->insert(fields->end(), aligned_to_8[f][i].fields().begin(), + aligned_to_8[f][i].fields().end()); + } + } +} + +} // namespace cpp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h new file mode 100644 index 00000000..9641ba40 --- /dev/null +++ b/src/google/protobuf/compiler/cpp/cpp_padding_optimizer.h @@ -0,0 +1,64 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: seongkim@google.com (Seong Beom Kim) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__ +#define GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__ + +#include <google/protobuf/compiler/cpp/cpp_message_layout_helper.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { + +// Rearranges the fields of a message to minimize padding. +// Fields are grouped by the type and the size. +// For example, grouping four boolean fields and one int32 +// field results in zero padding overhead. See OptimizeLayout's +// comment for details. +class PaddingOptimizer : public MessageLayoutHelper { + public: + PaddingOptimizer() {} + ~PaddingOptimizer() {} + + void OptimizeLayout(std::vector<const FieldDescriptor*>* fields, + const Options& options); +}; + +} // namespace cpp +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__ diff --git a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc index 34a41d82..ceb2270e 100644 --- a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc @@ -132,7 +132,7 @@ class TestGenerator : public CodeGenerator { // Check field accessors for a message inside oneof{}: TryInsert("test.pb.h", "field_get:foo.Bar.oneOfMessage", context); TryInsert("test.pb.h", "field_mutable:foo.Bar.oneOfMessage", context); - TryInsert("test.pb.h", "field_set_allocated:foo.Bar.oneOfMessage", context); + TryInsert("test.pb.cc", "field_set_allocated:foo.Bar.oneOfMessage", context); // Check field accessors for an optional enum: TryInsert("test.pb.h", "field_get:foo.Bar.optEnum", context); diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc index 020c1941..701f9d2d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -115,21 +115,21 @@ GeneratePrivateMembers(io::Printer* printer) const { void PrimitiveFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { + printer->Print(variables_, "$deprecated_attr$$type$ $name$() const;\n"); + printer->Annotate("name", descriptor_); printer->Print(variables_, - "$deprecated_attr$$type$ $name$() const;\n" - "$deprecated_attr$void set_$name$($type$ value);\n"); + "$deprecated_attr$void ${$set_$name$$}$($type$ value);\n"); + printer->Annotate("{", "}", descriptor_); } void PrimitiveFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; - printer->Print(variables, - "$inline$$type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + 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" @@ -148,7 +148,7 @@ GenerateMergingCode(io::Printer* printer) const { void PrimitiveFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "std::swap($name$_, other->$name$_);\n"); + printer->Print(variables_, "swap($name$_, other->$name$_);\n"); } void PrimitiveFieldGenerator:: @@ -210,30 +210,28 @@ PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {} void PrimitiveOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; - printer->Print(variables, - "$inline$$type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + 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" + " return $field_member$;\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" " }\n" - " $oneof_prefix$$name$_ = value;\n" + " $field_member$ = value;\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n"); } void PrimitiveOneofFieldGenerator:: GenerateClearingCode(io::Printer* printer) const { - printer->Print(variables_, "$oneof_prefix$$name$_ = $default$;\n"); + printer->Print(variables_, "$field_member$ = $default$;\n"); } void PrimitiveOneofFieldGenerator:: @@ -243,9 +241,8 @@ GenerateSwappingCode(io::Printer* printer) const { void PrimitiveOneofFieldGenerator:: GenerateConstructorCode(io::Printer* printer) const { - printer->Print( - variables_, - "_$classname$_default_instance_.$name$_ = $default$;\n"); + printer->Print(variables_, + "$ns$::_$classname$_default_instance_.$name$_ = $default$;\n"); } void PrimitiveOneofFieldGenerator:: @@ -254,7 +251,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { "clear_$oneof_name$();\n" "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" " $type$, $wire_format_field_type$>(\n" - " input, &$oneof_prefix$$name$_)));\n" + " input, &$field_member$)));\n" "set_has_$name$();\n"); } @@ -290,40 +287,46 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "$deprecated_attr$$type$ $name$(int index) const;\n" - "$deprecated_attr$void set_$name$(int index, $type$ value);\n" - "$deprecated_attr$void add_$name$($type$ value);\n"); + "$deprecated_attr$$type$ $name$(int index) const;\n"); + printer->Annotate("name", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$set_$name$$}$(int index, $type$ value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$add_$name$$}$($type$ value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$const ::google::protobuf::RepeatedField< $type$ >&\n" + " $name$() const;\n"); + printer->Annotate("name", descriptor_); printer->Print(variables_, - "$deprecated_attr$const ::google::protobuf::RepeatedField< $type$ >&\n" - " $name$() const;\n" - "$deprecated_attr$::google::protobuf::RepeatedField< $type$ >*\n" - " mutable_$name$();\n"); + "$deprecated_attr$::google::protobuf::RepeatedField< $type$ >*\n" + " ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedPrimitiveFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; - printer->Print(variables, - "$inline$$type$ $classname$::$name$(int index) const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + 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" + "}\n" + "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" @@ -382,7 +385,8 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { "$number$, " "::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, " "output);\n" - " output->WriteVarint32(_$name$_cached_byte_size_);\n"); + " output->WriteVarint32(static_cast< ::google::protobuf::uint32>(\n" + " _$name$_cached_byte_size_));\n"); if (FixedSize(descriptor_->type()) > 0) { // TODO(ckennelly): Use RepeatedField<T>::unsafe_data() via @@ -422,7 +426,8 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n" " target);\n" " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n" - " _$name$_cached_byte_size_, target);\n" + " static_cast< ::google::protobuf::int32>(\n" + " _$name$_cached_byte_size_), target);\n" " target = ::google::protobuf::internal::WireFormatLite::\n" " Write$declared_type$NoTagToArray(this->$name$_, target);\n" "}\n"); @@ -444,7 +449,7 @@ GenerateByteSize(io::Printer* printer) const { " $declared_type$Size(this->$name$_);\n"); } else { printer->Print(variables_, - "unsigned int count = this->$name$_size();\n" + "unsigned int count = static_cast<unsigned int>(this->$name$_size());\n" "size_t data_size = $fixed_size$UL * count;\n"); } @@ -452,7 +457,8 @@ GenerateByteSize(io::Printer* printer) const { printer->Print(variables_, "if (data_size > 0) {\n" " total_size += $tag_size$ +\n" - " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n" + " ::google::protobuf::internal::WireFormatLite::Int32Size(\n" + " static_cast< ::google::protobuf::int32>(data_size));\n" "}\n" "int cached_size = ::google::protobuf::internal::ToCachedSize(data_size);\n" "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h index 44c9ff3e..d52228e9 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h @@ -53,8 +53,7 @@ class PrimitiveFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; @@ -80,8 +79,7 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator { ~PrimitiveOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; @@ -100,8 +98,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) 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 7a849e2e..c9901e84 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -58,8 +58,8 @@ void SetStringVariables(const FieldDescriptor* descriptor, (*variables)["default_variable"] = descriptor->default_value_string().empty() ? "&::google::protobuf::internal::GetEmptyStringAlreadyInited()" - : "&" + (*variables)["classname"] + "::" + default_variable_string + - ".get()"; + : "&" + Namespace(descriptor) + "::" + (*variables)["classname"] + + "::" + default_variable_string + ".get()"; (*variables)["pointer_type"] = descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char"; (*variables)["null_check"] = "GOOGLE_DCHECK(value != NULL);\n"; @@ -71,6 +71,9 @@ void SetStringVariables(const FieldDescriptor* descriptor, (*variables)["full_name"] = descriptor->full_name(); (*variables)["string_piece"] = "::std::string"; + + (*variables)["lite"] = + HasDescriptorMethods(descriptor->file(), options) ? "" : "Lite"; } } // namespace @@ -79,7 +82,8 @@ void SetStringVariables(const FieldDescriptor* descriptor, StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor, const Options& options) - : FieldGenerator(options), descriptor_(descriptor) { + : FieldGenerator(options), descriptor_(descriptor), + lite_(!HasDescriptorMethods(descriptor->file(), options)) { SetStringVariables(descriptor, &variables_, options); } @@ -142,31 +146,55 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } printer->Print(variables_, - "$deprecated_attr$const ::std::string& $name$() const;\n" - "$deprecated_attr$void set_$name$(const ::std::string& value);\n"); + "$deprecated_attr$const ::std::string& $name$() const;\n"); + printer->Annotate("name", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$set_$name$$}$(const ::std::string& value);\n"); + printer->Annotate("{", "}", descriptor_); - if (!SupportsArenas(descriptor_)) { - printer->Print(variables_, - "#if LANG_CXX11\n" - "$deprecated_attr$void set_$name$(::std::string&& value);\n" - "#endif\n"); - } + printer->Print(variables_, + "#if LANG_CXX11\n" + "$deprecated_attr$void ${$set_$name$$}$(::std::string&& value);\n" + "#endif\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$set_$name$$}$(const char* value);\n"); + printer->Annotate("{", "}", descriptor_); printer->Print(variables_, - "$deprecated_attr$void set_$name$(const char* value);\n" - "$deprecated_attr$void set_$name$(const $pointer_type$* value, size_t size)" - ";\n" - "$deprecated_attr$::std::string* mutable_$name$();\n" - "$deprecated_attr$::std::string* $release_name$();\n" - "$deprecated_attr$void set_allocated_$name$(::std::string* $name$);\n"); + "$deprecated_attr$void ${$set_$name$$}$(const $pointer_type$* " + "value, size_t size)" + ";\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$::std::string* ${$mutable_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, "$deprecated_attr$::std::string* $release_name$();\n"); + printer->Annotate("release_name", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$set_allocated_$name$$}$(::std::string* $name$);\n"); + printer->Annotate("{", "}", descriptor_); if (SupportsArenas(descriptor_)) { - printer->Print(variables_, - "$deprecated_attr$::std::string* unsafe_arena_release_$name$();\n" - "$deprecated_attr$void unsafe_arena_set_allocated_$name$(\n" - " ::std::string* $name$);\n"); + printer->Print( + variables_, + "PROTOBUF_RUNTIME_DEPRECATED(\"The unsafe_arena_ accessors for\"\n" + "\" string fields are deprecated and will be removed in a\"\n" + "\" future release.\")\n" + "::std::string* ${$unsafe_arena_release_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "PROTOBUF_RUNTIME_DEPRECATED(\"The unsafe_arena_ accessors for\"\n" + "\" string fields are deprecated and will be removed in a\"\n" + "\" future release.\")\n" + "void ${$unsafe_arena_set_allocated_$name$$}$(\n" + " ::std::string* $name$);\n"); + printer->Annotate("{", "}", descriptor_); } - if (unknown_ctype) { printer->Outdent(); printer->Print(" public:\n"); @@ -175,57 +203,54 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } void StringFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const { - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; +GenerateInlineAccessorDefinitions(io::Printer* printer) const { if (SupportsArenas(descriptor_)) { printer->Print( - variables, - "$inline$const ::std::string& $classname$::$name$() const {\n" + variables_, + "inline const ::std::string& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.Get();\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" + " $name$_.Set$lite$($default_variable$, value, GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "$inline$void $classname$::set_$name$(const char* value) {\n" + "#if LANG_CXX11\n" + "inline void $classname$::set_$name$(::std::string&& value) {\n" + " $set_hasbit$\n" + " $name$_.Set$lite$(\n" + " $default_variable$, ::std::move(value), GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" + "}\n" + "#endif\n" + "inline void $classname$::set_$name$(const char* value) {\n" " $null_check$" " $set_hasbit$\n" - " $name$_.Set($default_variable$, $string_piece$(value),\n" + " $name$_.Set$lite$($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" - " $name$_.Set($default_variable$, $string_piece$(\n" + " $name$_.Set$lite$($default_variable$, $string_piece$(\n" " 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" " // @@protoc_insertion_point(field_release:$full_name$)\n" " $clear_hasbit$\n" " return $name$_.Release($default_variable$, GetArenaNoVirtual());\n" "}\n" - "$inline$::std::string* $classname$::unsafe_arena_release_$name$() {\n" - " // " - "@@protoc_insertion_point(field_unsafe_arena_release:$full_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" @@ -235,7 +260,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n" - "$inline$void $classname$::unsafe_arena_set_allocated_$name$(\n" + "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n" + " // " + "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n" + " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" + " $clear_hasbit$\n" + " return $name$_.UnsafeArenaRelease($default_variable$,\n" + " GetArenaNoVirtual());\n" + "}\n" + "inline void $classname$::unsafe_arena_set_allocated_$name$(\n" " ::std::string* $name$) {\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " if ($name$ != NULL) {\n" @@ -251,31 +284,31 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, } else { // No-arena case. printer->Print( - variables, - "$inline$const ::std::string& $classname$::$name$() const {\n" + variables_, + "inline const ::std::string& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.GetNoArena();\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" "#if LANG_CXX11\n" - "$inline$void $classname$::set_$name$(::std::string&& value) {\n" + "inline void $classname$::set_$name$(::std::string&& value) {\n" " $set_hasbit$\n" " $name$_.SetNoArena(\n" " $default_variable$, ::std::move(value));\n" " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" "}\n" "#endif\n" - "$inline$void $classname$::set_$name$(const char* value) {\n" + "inline void $classname$::set_$name$(const char* value) {\n" " $null_check$" " $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" @@ -283,17 +316,17 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, " $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" " // @@protoc_insertion_point(field_release:$full_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" @@ -369,11 +402,11 @@ GenerateMessageClearingCode(io::Printer* printer) const { // When Arenas are disabled and field presence has been checked, we can // safely treat the ArenaStringPtr as a string*. if (descriptor_->default_value_string().empty()) { - printer->Print(variables_, - "(*$name$_.UnsafeRawStringPointer())->clear();\n"); + printer->Print(variables_, "$name$_.UnsafeMutablePointer()->clear();\n"); } else { - printer->Print(variables_, - "(*$name$_.UnsafeRawStringPointer())->assign(*$default_variable$);\n"); + printer->Print( + variables_, + "$name$_.UnsafeMutablePointer()->assign(*$default_variable$);\n"); } } else { if (descriptor_->default_value_string().empty()) { @@ -426,7 +459,7 @@ GenerateCopyConstructorCode(io::Printer* printer) const { if (SupportsArenas(descriptor_) || descriptor_->containing_oneof() != NULL) { // TODO(gpike): improve this printer->Print(variables_, - "$name$_.Set($default_variable$, from.$name$(),\n" + "$name$_.Set$lite$($default_variable$, from.$name$(),\n" " GetArenaNoVirtual());\n"); } else { printer->Print(variables_, @@ -439,32 +472,21 @@ GenerateCopyConstructorCode(io::Printer* printer) const { void StringFieldGenerator:: GenerateDestructorCode(io::Printer* printer) const { - if (SupportsArenas(descriptor_)) { - // The variable |arena| is defined by the enclosing code. - // See MessageGenerator::GenerateSharedDestructorCode. - printer->Print(variables_, - "$name$_.Destroy($default_variable$, arena);\n"); - } else { - printer->Print(variables_, - "$name$_.DestroyNoArena($default_variable$);\n"); - } + printer->Print(variables_, + "$name$_.DestroyNoArena($default_variable$);\n"); } void StringFieldGenerator:: GenerateDefaultInstanceAllocator(io::Printer* printer) const { if (!descriptor_->default_value_string().empty()) { - printer->Print(variables_, - "$classname$::$default_variable_name$.DefaultConstruct();\n" - "*$classname$::$default_variable_name$.get_mutable() = " - "::std::string($default$, $default_length$);\n"); - } -} - -void StringFieldGenerator:: -GenerateShutdownCode(io::Printer* printer) const { - if (!descriptor_->default_value_string().empty()) { - printer->Print(variables_, - "$classname$::$default_variable_name$.Shutdown();\n"); + printer->Print( + variables_, + "$ns$::$classname$::$default_variable_name$.DefaultConstruct();\n" + "*$ns$::$classname$::$default_variable_name$.get_mutable() = " + "::std::string($default$, $default_length$);\n" + "::google::protobuf::internal::OnShutdownDestroyString(\n" + " $ns$::$classname$::$default_variable_name$.get_mutable());\n" + ); } } @@ -477,16 +499,23 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { if (descriptor_->type() == FieldDescriptor::TYPE_STRING) { GenerateUtf8CheckCodeForString( descriptor_, options_, true, variables_, - "this->$name$().data(), this->$name$().length(),\n", printer); + "this->$name$().data(), static_cast<int>(this->$name$().length()),\n", + printer); } } +bool StringFieldGenerator:: +MergeFromCodedStreamNeedsArena() const { + return false; +} + void StringFieldGenerator:: GenerateSerializeWithCachedSizes(io::Printer* printer) const { if (descriptor_->type() == FieldDescriptor::TYPE_STRING) { GenerateUtf8CheckCodeForString( descriptor_, options_, false, variables_, - "this->$name$().data(), this->$name$().length(),\n", printer); + "this->$name$().data(), static_cast<int>(this->$name$().length()),\n", + printer); } printer->Print(variables_, "::google::protobuf::internal::WireFormatLite::Write$declared_type$MaybeAliased(\n" @@ -498,7 +527,8 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { if (descriptor_->type() == FieldDescriptor::TYPE_STRING) { GenerateUtf8CheckCodeForString( descriptor_, options_, false, variables_, - "this->$name$().data(), this->$name$().length(),\n", printer); + "this->$name$().data(), static_cast<int>(this->$name$().length()),\n", + printer); } printer->Print(variables_, "target =\n" @@ -527,108 +557,119 @@ StringOneofFieldGenerator(const FieldDescriptor* descriptor, StringOneofFieldGenerator::~StringOneofFieldGenerator() {} void StringOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const { - std::map<string, string> variables(variables_); - variables["inline"] = is_inline ? "inline " : ""; +GenerateInlineAccessorDefinitions(io::Printer* printer) const { if (SupportsArenas(descriptor_)) { printer->Print( - variables, - "$inline$const ::std::string& $classname$::$name$() const {\n" + 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();\n" + " return $field_member$.Get();\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" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" - " $oneof_prefix$$name$_.Set($default_variable$, value,\n" + " $field_member$.Set$lite$($default_variable$, value,\n" " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "$inline$void $classname$::set_$name$(const char* value) {\n" + "#if LANG_CXX11\n" + "inline void $classname$::set_$name$(::std::string&& value) {\n" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $field_member$.Set$lite$(\n" + " $default_variable$, ::std::move(value), GetArenaNoVirtual());\n" + " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" + "}\n" + "#endif\n" + "inline void $classname$::set_$name$(const char* value) {\n" " $null_check$" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" - " $oneof_prefix$$name$_.Set($default_variable$,\n" + " $field_member$.Set$lite$($default_variable$,\n" " $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" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" - " $oneof_prefix$$name$_.Set($default_variable$, $string_piece$(\n" + " $field_member$.Set$lite$(\n" + " $default_variable$, $string_piece$(\n" " reinterpret_cast<const char*>(value), size),\n" " 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" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" - " return $oneof_prefix$$name$_.Mutable($default_variable$,\n" + " return $field_member$.Mutable($default_variable$,\n" " 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" " // @@protoc_insertion_point(field_release:$full_name$)\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " return $oneof_prefix$$name$_.Release($default_variable$,\n" + " return $field_member$.Release($default_variable$,\n" " GetArenaNoVirtual());\n" " } else {\n" " return NULL;\n" " }\n" "}\n" - "$inline$::std::string* $classname$::unsafe_arena_release_$name$() {\n" + "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + " if (!has_$name$()) {\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" + " }\n" + " clear_$oneof_name$();\n" + " if ($name$ != NULL) {\n" + " set_has_$name$();\n" + " $field_member$.SetAllocated($default_variable$, $name$,\n" + " GetArenaNoVirtual());\n" + " }\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n" + "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n" " // " "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " return $oneof_prefix$$name$_.UnsafeArenaRelease(\n" + " return $field_member$.UnsafeArenaRelease(\n" " $default_variable$, GetArenaNoVirtual());\n" " } else {\n" " return NULL;\n" " }\n" "}\n" - "$inline$void $classname$::set_allocated_$name$(::std::string* $name$) {\n" - " if (!has_$name$()) {\n" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" - " }\n" - " clear_$oneof_name$();\n" - " if ($name$ != NULL) {\n" - " set_has_$name$();\n" - " $oneof_prefix$$name$_.SetAllocated($default_variable$, $name$,\n" - " GetArenaNoVirtual());\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$(" "::std::string* $name$) {\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " if (!has_$name$()) {\n" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" " clear_$oneof_name$();\n" " if ($name$) {\n" " set_has_$name$();\n" - " $oneof_prefix$$name$_.UnsafeArenaSetAllocated($default_variable$, " + " $field_member$.UnsafeArenaSetAllocated($default_variable$, " "$name$, GetArenaNoVirtual());\n" " }\n" " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:" @@ -637,88 +678,85 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, } else { // No-arena case. printer->Print( - variables, - "$inline$const ::std::string& $classname$::$name$() const {\n" + 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();\n" + " return $field_member$.GetNoArena();\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" " set_has_$name$();\n" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" - " $oneof_prefix$$name$_.SetNoArena($default_variable$, value);\n" + " $field_member$.SetNoArena($default_variable$, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" "#if LANG_CXX11\n" - "$inline$void $classname$::set_$name$(::std::string&& value) {\n" + "inline void $classname$::set_$name$(::std::string&& value) {\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" - " $oneof_prefix$$name$_.SetNoArena(\n" - " $default_variable$, ::std::move(value));\n" + " $field_member$.SetNoArena($default_variable$, ::std::move(value));\n" " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" "}\n" "#endif\n" - "$inline$void $classname$::set_$name$(const char* value) {\n" + "inline void $classname$::set_$name$(const char* value) {\n" " $null_check$" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" - " $oneof_prefix$$name$_.SetNoArena($default_variable$,\n" + " $field_member$.SetNoArena($default_variable$,\n" " $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" " set_has_$name$();\n" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" - " $oneof_prefix$$name$_.SetNoArena($default_variable$, " - "$string_piece$(\n" + " $field_member$.SetNoArena($default_variable$, $string_piece$(\n" " 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" - " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" - " return $oneof_prefix$$name$_.MutableNoArena($default_variable$);\n" + " return $field_member$.MutableNoArena($default_variable$);\n" "}\n" - "$inline$::std::string* $classname$::$release_name$() {\n" + "inline ::std::string* $classname$::$release_name$() {\n" " // @@protoc_insertion_point(field_release:$full_name$)\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " return $oneof_prefix$$name$_.ReleaseNoArena($default_variable$);\n" + " return $field_member$.ReleaseNoArena($default_variable$);\n" " } else {\n" " 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" + " $field_member$.UnsafeSetDefault($default_variable$);\n" " }\n" " clear_$oneof_name$();\n" " if ($name$ != NULL) {\n" " set_has_$name$();\n" - " $oneof_prefix$$name$_.SetAllocatedNoArena($default_variable$,\n" - " $name$);\n" + " $field_member$.SetAllocatedNoArena($default_variable$, $name$);\n" " }\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n"); @@ -727,30 +765,13 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, void StringOneofFieldGenerator:: GenerateClearingCode(io::Printer* printer) const { - std::map<string, string> variables(variables_); - if (dependent_field_) { - variables["this_message"] = DependentBaseDownCast(); - // This clearing code may be in the dependent base class. If the default - // value is an empty string, then the $default_variable$ is a global - // singleton. If the default is not empty, we need to down-cast to get the - // default value's global singleton instance. See SetStringVariables() for - // possible values of default_variable. - if (!descriptor_->default_value_string().empty()) { - variables["default_variable"] = "&" + DependentBaseDownCast() + - variables["default_variable_name"] + - ".get()"; - } - } else { - variables["this_message"] = ""; - } if (SupportsArenas(descriptor_)) { - printer->Print(variables, - "$this_message$$oneof_prefix$$name$_.Destroy($default_variable$,\n" - " $this_message$GetArenaNoVirtual());\n"); + printer->Print(variables_, + "$field_member$.Destroy($default_variable$,\n" + " GetArenaNoVirtual());\n"); } else { - printer->Print(variables, - "$this_message$$oneof_prefix$$name$_." - "DestroyNoArena($default_variable$);\n"); + printer->Print(variables_, + "$field_member$.DestroyNoArena($default_variable$);\n"); } } @@ -768,24 +789,16 @@ void StringOneofFieldGenerator:: GenerateConstructorCode(io::Printer* printer) const { printer->Print( variables_, - "_$classname$_default_instance_.$name$_.UnsafeSetDefault(\n" + "$ns$::_$classname$_default_instance_.$name$_.UnsafeSetDefault(\n" " $default_variable$);\n"); } void StringOneofFieldGenerator:: GenerateDestructorCode(io::Printer* printer) const { - if (SupportsArenas(descriptor_)) { - printer->Print(variables_, - "if (has_$name$()) {\n" - " $oneof_prefix$$name$_.Destroy($default_variable$,\n" - " GetArenaNoVirtual());\n" - "}\n"); - } else { - printer->Print(variables_, - "if (has_$name$()) {\n" - " $oneof_prefix$$name$_.DestroyNoArena($default_variable$);\n" - "}\n"); - } + printer->Print(variables_, + "if (has_$name$()) {\n" + " $field_member$.DestroyNoArena($default_variable$);\n" + "}\n"); } void StringOneofFieldGenerator:: @@ -797,7 +810,8 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { if (descriptor_->type() == FieldDescriptor::TYPE_STRING) { GenerateUtf8CheckCodeForString( descriptor_, options_, true, variables_, - "this->$name$().data(), this->$name$().length(),\n", printer); + "this->$name$().data(), static_cast<int>(this->$name$().length()),\n", + printer); } } @@ -833,28 +847,62 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } printer->Print(variables_, - "$deprecated_attr$const ::std::string& $name$(int index) const;\n" - "$deprecated_attr$::std::string* mutable_$name$(int index);\n" - "$deprecated_attr$void set_$name$(int index, const ::std::string& value);\n" - "#if LANG_CXX11\n" - "$deprecated_attr$void set_$name$(int index, ::std::string&& value);\n" - "#endif\n" - "$deprecated_attr$void set_$name$(int index, const char* value);\n" - "" - "$deprecated_attr$void set_$name$(" - "int index, const $pointer_type$* value, size_t size);\n" - "$deprecated_attr$::std::string* add_$name$();\n" - "$deprecated_attr$void add_$name$(const ::std::string& value);\n" - "#if LANG_CXX11\n" - "$deprecated_attr$void add_$name$(::std::string&& value);\n" - "#endif\n" - "$deprecated_attr$void add_$name$(const char* value);\n" - "$deprecated_attr$void add_$name$(const $pointer_type$* value, size_t size)" - ";\n" - "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() " - "const;\n" - "$deprecated_attr$::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()" + "$deprecated_attr$const ::std::string& $name$(int index) const;\n"); + printer->Annotate("name", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$::std::string* ${$mutable_$name$$}$(int index);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$set_$name$$}$(int index, const " + "::std::string& value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "#if LANG_CXX11\n" + "$deprecated_attr$void ${$set_$name$$}$(int index, ::std::string&& value);\n" + "#endif\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$set_$name$$}$(int index, const " + "char* value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "" + "$deprecated_attr$void ${$set_$name$$}$(" + "int index, const $pointer_type$* value, size_t size);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$::std::string* ${$add_$name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$add_$name$$}$(const ::std::string& value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "#if LANG_CXX11\n" + "$deprecated_attr$void ${$add_$name$$}$(::std::string&& value);\n" + "#endif\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$void ${$add_$name$$}$(const char* value);\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecated_attr$void ${$add_$name$$}$(const $pointer_type$* " + "value, size_t size)" ";\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print( + variables_, + "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() " + "const;\n"); + printer->Annotate("name", descriptor_); + printer->Print(variables_, + "$deprecated_attr$::google::protobuf::RepeatedPtrField< ::std::string>* " + "${$mutable_$name$$}$()" + ";\n"); + printer->Annotate("{", "}", descriptor_); if (unknown_ctype) { printer->Outdent(); @@ -864,71 +912,78 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } void RepeatedStringFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const { - std::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" +GenerateInlineAccessorDefinitions(io::Printer* printer) const { + if (options_.safe_boundary_check) { + printer->Print(variables_, + "inline const ::std::string& $classname$::$name$(int index) const {\n" + " // @@protoc_insertion_point(field_get:$full_name$)\n" + " return $name$_.InternalCheckedGet(\n" + " index, ::google::protobuf::internal::GetEmptyStringAlreadyInited());\n" + "}\n"); + } else { + printer->Print(variables_, + "inline const ::std::string& $classname$::$name$(int index) const {\n" + " // @@protoc_insertion_point(field_get:$full_name$)\n" + " return $name$_.Get(index);\n" + "}\n"); + } + printer->Print(variables_, + "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" "#if LANG_CXX11\n" - "$inline$void $classname$::set_$name$(int index, ::std::string&& value) {\n" + "inline void $classname$::set_$name$(int index, ::std::string&& value) {\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" " $name$_.Mutable(index)->assign(std::move(value));\n" "}\n" "#endif\n" - "$inline$void $classname$::set_$name$(int index, const char* value) {\n" + "inline void $classname$::set_$name$(int index, const char* value) {\n" " $null_check$" " $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" " // @@protoc_insertion_point(field_add_mutable:$full_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" "#if LANG_CXX11\n" - "$inline$void $classname$::add_$name$(::std::string&& value) {\n" + "inline void $classname$::add_$name$(::std::string&& value) {\n" " $name$_.Add(std::move(value));\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n" "#endif\n" - "$inline$void $classname$::add_$name$(const char* value) {\n" + "inline void $classname$::add_$name$(const char* value) {\n" " $null_check$" " $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" - "$inline$const ::google::protobuf::RepeatedPtrField< ::std::string>&\n" + "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" @@ -947,7 +1002,8 @@ GenerateMergingCode(io::Printer* printer) const { void RepeatedStringFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n"); + printer->Print(variables_, + "$name$_.InternalSwap(CastToBase(&other->$name$_));\n"); } void RepeatedStringFieldGenerator:: @@ -969,7 +1025,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { GenerateUtf8CheckCodeForString( descriptor_, options_, true, variables_, "this->$name$(this->$name$_size() - 1).data(),\n" - "this->$name$(this->$name$_size() - 1).length(),\n", + "static_cast<int>(this->$name$(this->$name$_size() - 1).length()),\n", printer); } } @@ -982,7 +1038,8 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { if (descriptor_->type() == FieldDescriptor::TYPE_STRING) { GenerateUtf8CheckCodeForString( descriptor_, options_, false, variables_, - "this->$name$(i).data(), this->$name$(i).length(),\n", printer); + "this->$name$(i).data(), static_cast<int>(this->$name$(i).length()),\n", + printer); } printer->Outdent(); printer->Print(variables_, @@ -999,7 +1056,8 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { if (descriptor_->type() == FieldDescriptor::TYPE_STRING) { GenerateUtf8CheckCodeForString( descriptor_, options_, false, variables_, - "this->$name$(i).data(), this->$name$(i).length(),\n", printer); + "this->$name$(i).data(), static_cast<int>(this->$name$(i).length()),\n", + printer); } printer->Outdent(); printer->Print(variables_, diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h index af263c1a..0c6e9ced 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h @@ -54,8 +54,7 @@ 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, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMessageClearingCode(io::Printer* printer) const; @@ -65,15 +64,17 @@ class StringFieldGenerator : public FieldGenerator { void GenerateCopyConstructorCode(io::Printer* printer) const; void GenerateDestructorCode(io::Printer* printer) const; void GenerateDefaultInstanceAllocator(io::Printer* printer) const; - void GenerateShutdownCode(io::Printer* printer) const; void GenerateMergeFromCodedStream(io::Printer* printer) const; void GenerateSerializeWithCachedSizes(io::Printer* printer) const; void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; void GenerateByteSize(io::Printer* printer) const; + bool MergeFromCodedStreamNeedsArena() const; + protected: const FieldDescriptor* descriptor_; std::map<string, string> variables_; + const bool lite_; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); @@ -86,8 +87,7 @@ class StringOneofFieldGenerator : public StringFieldGenerator { ~StringOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; // StringFieldGenerator, from which we inherit, overrides this so we need to @@ -112,8 +112,7 @@ class RepeatedStringFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer, - bool is_inline) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer) 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_test_bad_identifiers.proto b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto index 4e25b2ea..7fe98759 100644 --- a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto +++ b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto @@ -151,6 +151,10 @@ enum ConflictingEnum { // NO_PROTO3 message DummyMessage {} +// Message names that could conflict. +message Shutdown {} +message TableStruct {} + service TestConflictingMethodNames { rpc Closure(DummyMessage) returns (DummyMessage); } diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index e56964c7..2ad7ea4e 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -576,12 +576,73 @@ TEST(GeneratedMessageTest, SwapWithOther) { EXPECT_EQ(unittest::TestAllTypes::BAR, message2.repeated_nested_enum(1)); } -TEST(GeneratedMessageTest, CopyConstructor) { - unittest::TestAllTypes message1; +TEST(GeneratedMessageTest, ADLSwap) { + unittest::TestAllTypes message1, message2; TestUtil::SetAllFields(&message1); - unittest::TestAllTypes message2(message1); + // Note the address of one of the repeated fields, to verify it was swapped + // rather than copied. + const int32* addr = &message1.repeated_int32().Get(0); + + using std::swap; + swap(message1, message2); + TestUtil::ExpectAllFieldsSet(message2); + TestUtil::ExpectClear(message1); + + EXPECT_EQ(addr, &message2.repeated_int32().Get(0)); +} + +TEST(GeneratedMessageTest, CopyConstructor) { + // All set. + { + unittest::TestAllTypes message1; + TestUtil::SetAllFields(&message1); + + unittest::TestAllTypes message2(message1); + TestUtil::ExpectAllFieldsSet(message2); + } + + // None set. + { + unittest::TestAllTypes message1; + unittest::TestAllTypes message2(message1); + + EXPECT_FALSE(message1.has_optional_string()); + EXPECT_FALSE(message2.has_optional_string()); + EXPECT_EQ(&message1.optional_string(), + &message2.optional_string()); + + EXPECT_FALSE(message1.has_optional_bytes()); + EXPECT_FALSE(message2.has_optional_bytes()); + EXPECT_EQ(&message1.optional_bytes(), + &message2.optional_bytes()); + + EXPECT_FALSE(message1.has_optional_nested_message()); + EXPECT_FALSE(message2.has_optional_nested_message()); + EXPECT_EQ(&message1.optional_nested_message(), + &message2.optional_nested_message()); + + EXPECT_FALSE(message1.has_optional_foreign_message()); + EXPECT_FALSE(message2.has_optional_foreign_message()); + EXPECT_EQ(&message1.optional_foreign_message(), + &message2.optional_foreign_message()); + + EXPECT_FALSE(message1.has_optional_import_message()); + EXPECT_FALSE(message2.has_optional_import_message()); + EXPECT_EQ(&message1.optional_import_message(), + &message2.optional_import_message()); + + EXPECT_FALSE(message1.has_optional_public_import_message()); + EXPECT_FALSE(message2.has_optional_public_import_message()); + EXPECT_EQ(&message1.optional_public_import_message(), + &message2.optional_public_import_message()); + + EXPECT_FALSE(message1.has_optional_lazy_message()); + EXPECT_FALSE(message2.has_optional_lazy_message()); + EXPECT_EQ(&message1.optional_lazy_message(), + &message2.optional_lazy_message()); + } } TEST(GeneratedMessageTest, CopyConstructorWithArenas) { @@ -683,21 +744,6 @@ TEST(GeneratedMessageTest, NonEmptyMergeFrom) { TestUtil::ExpectAllFieldsSet(message1); } -#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \ - !defined(GOOGLE_PROTOBUF_NO_RTTI) -#ifdef PROTOBUF_HAS_DEATH_TEST -#ifndef NDEBUG - -TEST(GeneratedMessageTest, MergeFromSelf) { - unittest::TestAllTypes message; - EXPECT_DEATH(message.MergeFrom(message), "pb[.]cc.*Check failed:"); - EXPECT_DEATH(message.MergeFrom(implicit_cast<const Message&>(message)), - "pb[.]cc.*Check failed:"); -} - -#endif // NDEBUG -#endif // PROTOBUF_HAS_DEATH_TEST -#endif // !PROTOBUF_TEST_NO_DESCRIPTORS || !GOOGLE_PROTOBUF_NO_RTTI // Test the generated SerializeWithCachedSizesToArray(), TEST(GeneratedMessageTest, SerializationToArray) { @@ -949,75 +995,76 @@ TEST(GeneratedMessageTest, TestEmbedOptimizedForSize) { TEST(GeneratedMessageTest, TestSpaceUsed) { unittest::TestAllTypes message1; - // sizeof provides a lower bound on SpaceUsed(). - EXPECT_LE(sizeof(unittest::TestAllTypes), message1.SpaceUsed()); - const int empty_message_size = message1.SpaceUsed(); + // sizeof provides a lower bound on SpaceUsedLong(). + EXPECT_LE(sizeof(unittest::TestAllTypes), message1.SpaceUsedLong()); + const size_t empty_message_size = message1.SpaceUsedLong(); // Setting primitive types shouldn't affect the space used. message1.set_optional_int32(123); message1.set_optional_int64(12345); message1.set_optional_uint32(123); message1.set_optional_uint64(12345); - EXPECT_EQ(empty_message_size, message1.SpaceUsed()); + EXPECT_EQ(empty_message_size, message1.SpaceUsedLong()); // On some STL implementations, setting the string to a small value should - // only increase SpaceUsed() by the size of a string object, though this is - // not true everywhere. + // only increase SpaceUsedLong() by the size of a string object, though this + // is not true everywhere. message1.set_optional_string("abc"); - EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsed()); + EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsedLong()); // Setting a string to a value larger than the string object itself should - // increase SpaceUsed(), because it cannot store the value internally. + // increase SpaceUsedLong(), because it cannot store the value internally. message1.set_optional_string(string(sizeof(string) + 1, 'x')); int min_expected_increase = message1.optional_string().capacity() + sizeof(string); EXPECT_LE(empty_message_size + min_expected_increase, - message1.SpaceUsed()); + message1.SpaceUsedLong()); - int previous_size = message1.SpaceUsed(); + size_t previous_size = message1.SpaceUsedLong(); // Adding an optional message should increase the size by the size of the // nested message type. NestedMessage is simple enough (1 int field) that it // is equal to sizeof(NestedMessage) message1.mutable_optional_nested_message(); ASSERT_EQ(sizeof(unittest::TestAllTypes::NestedMessage), - message1.optional_nested_message().SpaceUsed()); + message1.optional_nested_message().SpaceUsedLong()); EXPECT_EQ(previous_size + sizeof(unittest::TestAllTypes::NestedMessage), - message1.SpaceUsed()); + message1.SpaceUsedLong()); } TEST(GeneratedMessageTest, TestOneofSpaceUsed) { unittest::TestOneof2 message1; - EXPECT_LE(sizeof(unittest::TestOneof2), message1.SpaceUsed()); + EXPECT_LE(sizeof(unittest::TestOneof2), message1.SpaceUsedLong()); - const int empty_message_size = message1.SpaceUsed(); + const size_t empty_message_size = message1.SpaceUsedLong(); // Setting primitive types shouldn't affect the space used. message1.set_foo_int(123); message1.set_bar_int(12345); - EXPECT_EQ(empty_message_size, message1.SpaceUsed()); + EXPECT_EQ(empty_message_size, message1.SpaceUsedLong()); - // Setting a string in oneof to a small value should only increase SpaceUsed() - // by the size of a string object. + // Setting a string in oneof to a small value should only increase + // SpaceUsedLong() by the size of a string object. message1.set_foo_string("abc"); - EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsed()); + EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsedLong()); // Setting a string in oneof to a value larger than the string object itself - // should increase SpaceUsed(), because it cannot store the value internally. + // should increase SpaceUsedLong(), because it cannot store the value + // internally. message1.set_foo_string(string(sizeof(string) + 1, 'x')); int min_expected_increase = message1.foo_string().capacity() + sizeof(string); EXPECT_LE(empty_message_size + min_expected_increase, - message1.SpaceUsed()); + message1.SpaceUsedLong()); // Setting a message in oneof should delete the other fields and increase the // size by the size of the nested message type. NestedMessage is simple enough // that it is equal to sizeof(NestedMessage) message1.mutable_foo_message(); ASSERT_EQ(sizeof(unittest::TestOneof2::NestedMessage), - message1.foo_message().SpaceUsed()); + message1.foo_message().SpaceUsedLong()); EXPECT_EQ(empty_message_size + sizeof(unittest::TestOneof2::NestedMessage), - message1.SpaceUsed()); + message1.SpaceUsedLong()); } #endif // !PROTOBUF_TEST_NO_DESCRIPTORS @@ -1340,7 +1387,7 @@ class GeneratedServiceTest : public testing::Test { foo_(descriptor_->FindMethodByName("Foo")), bar_(descriptor_->FindMethodByName("Bar")), stub_(&mock_channel_), - done_(NewPermanentCallback(&DoNothing)) {} + done_(::google::protobuf::NewPermanentCallback(&DoNothing)) {} virtual void SetUp() { ASSERT_TRUE(foo_ != NULL); diff --git a/src/google/protobuf/compiler/cpp/metadata_test.cc b/src/google/protobuf/compiler/cpp/metadata_test.cc index 03f6b12b..456784c6 100644 --- a/src/google/protobuf/compiler/cpp/metadata_test.cc +++ b/src/google/protobuf/compiler/cpp/metadata_test.cc @@ -35,10 +35,8 @@ #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/compiler/cpp/cpp_generator.h> +#include <google/protobuf/compiler/annotation_test_util.h> #include <google/protobuf/compiler/command_line_interface.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl_lite.h> -#include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/testing/file.h> @@ -47,37 +45,15 @@ #include <gtest/gtest.h> namespace google { +namespace atu = ::google::protobuf::compiler::annotation_test_util; + namespace protobuf { namespace compiler { namespace cpp { namespace { -// A CodeGenerator that captures the FileDescriptor it's passed as a -// FileDescriptorProto. -class DescriptorCapturingGenerator : public CodeGenerator { - public: - // Does not own file; file must outlive the Generator. - explicit DescriptorCapturingGenerator(FileDescriptorProto* file) - : file_(file) {} - - virtual bool Generate(const FileDescriptor* file, const string& parameter, - GeneratorContext* context, string* error) const { - file->CopyTo(file_); - return true; - } - - private: - FileDescriptorProto* file_; -}; - class CppMetadataTest : public ::testing::Test { public: - // Adds a file with name `filename` and content `data`. - void AddFile(const string& filename, const string& data) { - GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/" + filename, data, - true)); - } - // Tries to capture a FileDescriptorProto, GeneratedCodeInfo, and output // code from the previously added file with name `filename`. Returns true on // success. If pb_h is non-null, expects a .pb.h and a .pb.h.meta (copied to @@ -87,26 +63,19 @@ class CppMetadataTest : public ::testing::Test { string* proto_h, GeneratedCodeInfo* proto_h_info, string* pb_cc) { google::protobuf::compiler::CommandLineInterface cli; - cli.SetInputsAreProtoPathRelative(true); - CppGenerator cpp_generator; - DescriptorCapturingGenerator capturing_generator(file); cli.RegisterGenerator("--cpp_out", &cpp_generator, ""); - cli.RegisterGenerator("--capture_out", &capturing_generator, ""); - - string proto_path = "-I" + TestTempDir(); string cpp_out = "--cpp_out=annotate_headers=true," "annotation_pragma_name=pragma_name," "annotation_guard_name=guard_name:" + TestTempDir(); - string capture_out = "--capture_out=" + TestTempDir(); - const char* argv[] = {"protoc", proto_path.c_str(), cpp_out.c_str(), - capture_out.c_str(), filename.c_str()}; + const bool result = + atu::RunProtoCompiler(filename, cpp_out, &cli, file); - if (cli.Run(5, argv) != 0) { - return false; + if (!result) { + return result; } string output_base = TestTempDir() + "/" + StripProto(filename); @@ -119,7 +88,7 @@ class CppMetadataTest : public ::testing::Test { if (pb_h != NULL && pb_h_info != NULL) { GOOGLE_CHECK_OK( File::GetContents(output_base + ".pb.h", pb_h, true)); - if (!DecodeMetadata(output_base + ".pb.h.meta", pb_h_info)) { + if (!atu::DecodeMetadata(output_base + ".pb.h.meta", pb_h_info)) { return false; } } @@ -127,23 +96,13 @@ class CppMetadataTest : public ::testing::Test { if (proto_h != NULL && proto_h_info != NULL) { GOOGLE_CHECK_OK(File::GetContents(output_base + ".proto.h", proto_h, true)); - if (!DecodeMetadata(output_base + ".proto.h.meta", proto_h_info)) { + if (!atu::DecodeMetadata(output_base + ".proto.h.meta", proto_h_info)) { return false; } } return true; } - - private: - // Decodes GeneratedCodeInfo stored in path and copies it to info. - // Returns true on success. - bool DecodeMetadata(const string& path, GeneratedCodeInfo* info) { - string data; - GOOGLE_CHECK_OK(File::GetContents(path, &data, true)); - io::ArrayInputStream input(data.data(), data.size()); - return info->ParseFromZeroCopyStream(&input); - } }; const char kSmallTestFile[] = @@ -152,48 +111,11 @@ const char kSmallTestFile[] = "enum Enum { VALUE = 0; }\n" "message Message { }\n"; -// Finds the Annotation for a given source file and path (or returns null if it -// couldn't). -const GeneratedCodeInfo::Annotation* FindAnnotationOnPath( - const GeneratedCodeInfo& info, const string& source_file, - const std::vector<int>& path) { - for (int i = 0; i < info.annotation_size(); ++i) { - const GeneratedCodeInfo::Annotation* annotation = &info.annotation(i); - if (annotation->source_file() != source_file || - annotation->path_size() != path.size()) { - continue; - } - int node = 0; - for (; node < path.size(); ++node) { - if (annotation->path(node) != path[node]) { - break; - } - } - if (node == path.size()) { - return annotation; - } - } - return NULL; -} - -// Returns true if the provided annotation covers a given substring in -// file_content. -bool AnnotationMatchesSubstring(const string& file_content, - const GeneratedCodeInfo::Annotation* annotation, - const string& expected_text) { - uint32 begin = annotation->begin(); - uint32 end = annotation->end(); - if (end < begin || end > file_content.size()) { - return false; - } - return file_content.substr(begin, end - begin) == expected_text; -} - TEST_F(CppMetadataTest, CapturesEnumNames) { FileDescriptorProto file; GeneratedCodeInfo info; string pb_h; - AddFile("test.proto", kSmallTestFile); + atu::AddFile("test.proto", kSmallTestFile); EXPECT_TRUE( CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL)); EXPECT_EQ("Enum", file.enum_type(0).name()); @@ -201,16 +123,16 @@ TEST_F(CppMetadataTest, CapturesEnumNames) { enum_path.push_back(FileDescriptorProto::kEnumTypeFieldNumber); enum_path.push_back(0); const GeneratedCodeInfo::Annotation* enum_annotation = - FindAnnotationOnPath(info, "test.proto", enum_path); + atu::FindAnnotationOnPath(info, "test.proto", enum_path); EXPECT_TRUE(NULL != enum_annotation); - EXPECT_TRUE(AnnotationMatchesSubstring(pb_h, enum_annotation, "Enum")); + EXPECT_TRUE(atu::AnnotationMatchesSubstring(pb_h, enum_annotation, "Enum")); } TEST_F(CppMetadataTest, AddsPragma) { FileDescriptorProto file; GeneratedCodeInfo info; string pb_h; - AddFile("test.proto", kSmallTestFile); + atu::AddFile("test.proto", kSmallTestFile); EXPECT_TRUE( CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL)); EXPECT_TRUE(pb_h.find("#ifdef guard_name") != string::npos); @@ -222,7 +144,7 @@ TEST_F(CppMetadataTest, CapturesMessageNames) { FileDescriptorProto file; GeneratedCodeInfo info; string pb_h; - AddFile("test.proto", kSmallTestFile); + atu::AddFile("test.proto", kSmallTestFile); EXPECT_TRUE( CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL)); EXPECT_EQ("Message", file.message_type(0).name()); @@ -230,9 +152,10 @@ TEST_F(CppMetadataTest, CapturesMessageNames) { message_path.push_back(FileDescriptorProto::kMessageTypeFieldNumber); message_path.push_back(0); const GeneratedCodeInfo::Annotation* message_annotation = - FindAnnotationOnPath(info, "test.proto", message_path); + atu::FindAnnotationOnPath(info, "test.proto", message_path); EXPECT_TRUE(NULL != message_annotation); - EXPECT_TRUE(AnnotationMatchesSubstring(pb_h, message_annotation, "Message")); + EXPECT_TRUE( + atu::AnnotationMatchesSubstring(pb_h, message_annotation, "Message")); } } // namespace diff --git a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc index 4e44b578..8c38e52f 100644 --- a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc @@ -134,6 +134,14 @@ class GenerateAndTest { }; TEST(CsharpBootstrapTest, GeneratedCsharpDescriptorMatches) { + // Skip this whole test if the csharp directory doesn't exist (i.e., a C++11 + // only distribution). + string descriptor_file_name = + "../csharp/src/Google.Protobuf/Reflection/Descriptor.cs"; + if (!File::Exists(TestSourceDir() + "/" + descriptor_file_name)) { + return; + } + MockErrorCollector error_collector; DiskSourceTree source_tree; Importer importer(&source_tree, &error_collector); @@ -176,11 +184,6 @@ TEST(CsharpBootstrapTest, GeneratedCsharpDescriptorMatches) { "../csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs"); generate_test.SetParameter(""); - source_tree.MapPath("", TestSourceDir() + "/../examples"); - generate_test.Run(importer.Import("addressbook.proto"), - "Addressbook.cs", - "../csharp/src/AddressBook/Addressbook.cs"); - source_tree.MapPath("", TestSourceDir() + "/../conformance"); generate_test.Run(importer.Import("conformance.proto"), "Conformance.cs", diff --git a/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc b/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc index 636a76a0..a21dc0a4 100644 --- a/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc +++ b/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc @@ -56,7 +56,7 @@ void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) { // node of a summary element, not part of an attribute. comments = StringReplace(comments, "&", "&", true); comments = StringReplace(comments, "<", "<", true); - vector<string> lines = Split(comments, "\n", false /* skip_empty */); + std::vector<string> lines = Split(comments, "\n", false /* skip_empty */); // TODO: We really should work out which part to put in the summary and which to put in the remarks... // but that needs to be part of a bigger effort to understand the markdown better anyway. printer->Print("/// <summary>\n"); diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc index 67c0b596..9ceffa8c 100644 --- a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc @@ -89,6 +89,10 @@ EnumOneofFieldGenerator::EnumOneofFieldGenerator( EnumOneofFieldGenerator::~EnumOneofFieldGenerator() { } +void EnumOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) { + printer->Print(variables_, "$property_name$ = other.$property_name$;\n"); +} + void EnumOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { // TODO(jonskeet): What about if we read the default value? printer->Print( diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_enum_field.h index 9b7669ba..631632bc 100644 --- a/src/google/protobuf/compiler/csharp/csharp_enum_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.h @@ -64,6 +64,7 @@ class EnumOneofFieldGenerator : public PrimitiveOneofFieldGenerator { const Options *options); ~EnumOneofFieldGenerator(); + virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); virtual void GenerateSerializationCode(io::Printer* printer); virtual void GenerateSerializedSizeCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index ebb8fbc2..ecf29ece 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -54,7 +54,7 @@ namespace compiler { namespace csharp { void FieldGeneratorBase::SetCommonFieldVariables( - map<string, string>* variables) { + std::map<string, string>* variables) { // Note: this will be valid even though the tag emitted for packed and unpacked versions of // repeated fields varies by wire format. The wire format is encoded in the bottom 3 bits, which // never effects the tag size. @@ -92,7 +92,7 @@ void FieldGeneratorBase::SetCommonFieldVariables( } void FieldGeneratorBase::SetCommonOneofFieldVariables( - map<string, string>* variables) { + std::map<string, string>* variables) { (*variables)["oneof_name"] = oneof_name(); (*variables)["has_property_check"] = oneof_name() + "Case_ == " + oneof_property_name() + diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h index 4109f3ca..df26853b 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.h +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h @@ -66,14 +66,14 @@ class FieldGeneratorBase : public SourceGeneratorBase { protected: const FieldDescriptor* descriptor_; const int fieldOrdinal_; - map<string, string> variables_; + std::map<string, string> variables_; void AddDeprecatedFlag(io::Printer* printer); void AddNullCheck(io::Printer* printer); void AddNullCheck(io::Printer* printer, const std::string& name); void AddPublicMemberAttributes(io::Printer* printer); - void SetCommonOneofFieldVariables(map<string, string>* variables); + void SetCommonOneofFieldVariables(std::map<string, string>* variables); std::string oneof_property_name(); std::string oneof_name(); @@ -89,7 +89,7 @@ class FieldGeneratorBase : public SourceGeneratorBase { std::string capitalized_type_name(); private: - void SetCommonFieldVariables(map<string, string>* variables); + void SetCommonFieldVariables(std::map<string, string>* variables); std::string GetStringDefaultValueInternal(); std::string GetBytesDefaultValueInternal(); diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.cc b/src/google/protobuf/compiler/csharp/csharp_generator.cc index c13ed65b..5418127f 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator.cc +++ b/src/google/protobuf/compiler/csharp/csharp_generator.cc @@ -64,7 +64,7 @@ bool Generator::Generate( GeneratorContext* generator_context, string* error) const { - vector<pair<string, string> > options; + std::vector<std::pair<string, string> > options; ParseGeneratorParameter(parameter, &options); // We only support proto3 - but we make an exception for descriptor.proto. diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index 0f00a438..17b4a071 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -105,13 +105,13 @@ void MessageGenerator::AddDeprecatedFlag(io::Printer* printer) { } void MessageGenerator::Generate(io::Printer* printer) { - map<string, string> vars; + std::map<string, string> vars; vars["class_name"] = class_name(); vars["access_level"] = class_access_level(); WriteMessageDocComment(printer, descriptor_); AddDeprecatedFlag(printer); - + printer->Print( vars, "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name$> {\n"); @@ -119,14 +119,17 @@ void MessageGenerator::Generate(io::Printer* printer) { // All static fields and properties printer->Print( - vars, - "private static readonly pb::MessageParser<$class_name$> _parser = new pb::MessageParser<$class_name$>(() => new $class_name$());\n"); + vars, + "private static readonly pb::MessageParser<$class_name$> _parser = new pb::MessageParser<$class_name$>(() => new $class_name$());\n"); + + printer->Print( + "private pb::UnknownFieldSet _unknownFields;\n"); WriteGeneratedCodeAttributes(printer); printer->Print( - vars, - "public static pb::MessageParser<$class_name$> Parser { get { return _parser; } }\n\n"); + vars, + "public static pb::MessageParser<$class_name$> Parser { get { return _parser; } }\n\n"); // Access the message descriptor via the relevant file descriptor or containing message descriptor. if (!descriptor_->containing_type()) { @@ -139,14 +142,14 @@ void MessageGenerator::Generate(io::Printer* printer) { WriteGeneratedCodeAttributes(printer); printer->Print( - vars, - "public static pbr::MessageDescriptor Descriptor {\n" - " get { return $descriptor_accessor$; }\n" - "}\n" - "\n"); + vars, + "public static pbr::MessageDescriptor Descriptor {\n" + " get { return $descriptor_accessor$; }\n" + "}\n" + "\n"); WriteGeneratedCodeAttributes(printer); printer->Print( - vars, + vars, "pbr::MessageDescriptor pb::IMessage.Descriptor {\n" " get { return Descriptor; }\n" "}\n" @@ -209,18 +212,18 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Print("}\n"); // TODO: Should we put the oneof .proto comments here? // It's unclear exactly where they should go. - printer->Print( - vars, - "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, - "public $property_name$OneofCase $property_name$Case {\n" - " get { return $name$Case_; }\n" - "}\n\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, + printer->Print( + vars, + "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n"); + WriteGeneratedCodeAttributes(printer); + printer->Print( + vars, + "public $property_name$OneofCase $property_name$Case {\n" + " get { return $name$Case_; }\n" + "}\n\n"); + WriteGeneratedCodeAttributes(printer); + printer->Print( + vars, "public void Clear$property_name$() {\n" " $name$Case_ = $property_name$OneofCase.None;\n" " $name$_ = null;\n" @@ -280,7 +283,7 @@ bool MessageGenerator::HasNestedGeneratedTypes() } void MessageGenerator::GenerateCloningCode(io::Printer* printer) { - map<string, string> vars; + std::map<string, string> vars; WriteGeneratedCodeAttributes(printer); vars["class_name"] = class_name(); printer->Print( @@ -317,6 +320,9 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) { printer->Outdent(); printer->Print("}\n\n"); } + // Clone unknown fields + printer->Print( + "_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);\n"); printer->Outdent(); printer->Print("}\n\n"); @@ -333,19 +339,19 @@ void MessageGenerator::GenerateFreezingCode(io::Printer* printer) { } void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { - map<string, string> vars; + std::map<string, string> vars; vars["class_name"] = class_name(); // Equality - WriteGeneratedCodeAttributes(printer); + WriteGeneratedCodeAttributes(printer); printer->Print( vars, "public override bool Equals(object other) {\n" " return Equals(other as $class_name$);\n" "}\n\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, + WriteGeneratedCodeAttributes(printer); + printer->Print( + vars, "public bool Equals($class_name$ other) {\n" " if (ReferenceEquals(other, null)) {\n" " return false;\n" @@ -365,13 +371,13 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { } printer->Outdent(); printer->Print( - " return true;\n" + " return Equals(_unknownFields, other._unknownFields);\n" "}\n\n"); // GetHashCode // Start with a non-zero value to easily distinguish between null and "empty" messages. - WriteGeneratedCodeAttributes(printer); - printer->Print( + WriteGeneratedCodeAttributes(printer); + printer->Print( "public override int GetHashCode() {\n" " int hash = 1;\n"); printer->Indent(); @@ -384,12 +390,16 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { printer->Print("hash ^= (int) $name$Case_;\n", "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false)); } - printer->Print("return hash;\n"); + printer->Print( + "if (_unknownFields != null) {\n" + " hash ^= _unknownFields.GetHashCode();\n" + "}\n" + "return hash;\n"); printer->Outdent(); printer->Print("}\n\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print( + WriteGeneratedCodeAttributes(printer); + printer->Print( "public override string ToString() {\n" " return pb::JsonFormatter.ToDiagnosticString(this);\n" "}\n\n"); @@ -408,11 +418,17 @@ void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) generator->GenerateSerializationCode(printer); } + // Serialize unknown fields + printer->Print( + "if (_unknownFields != null) {\n" + " _unknownFields.WriteTo(output);\n" + "}\n"); + // TODO(jonskeet): Memoize size of frozen messages? printer->Outdent(); printer->Print( - "}\n" - "\n"); + "}\n" + "\n"); WriteGeneratedCodeAttributes(printer); printer->Print( "public int CalculateSize() {\n"); @@ -423,6 +439,12 @@ void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) CreateFieldGeneratorInternal(descriptor_->field(i))); generator->GenerateSerializedSizeCode(printer); } + + printer->Print( + "if (_unknownFields != null) {\n" + " size += _unknownFields.CalculateSize();\n" + "}\n"); + printer->Print("return size;\n"); printer->Outdent(); printer->Print("}\n\n"); @@ -432,7 +454,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { // Note: These are separate from GenerateMessageSerializationMethods() // because they need to be generated even for messages that are optimized // for code size. - map<string, string> vars; + std::map<string, string> vars; vars["class_name"] = class_name(); WriteGeneratedCodeAttributes(printer); @@ -463,15 +485,24 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { vars["field_property_name"] = GetPropertyName(field); printer->Print( vars, - "case $property_name$OneofCase.$field_property_name$:\n" - " $field_property_name$ = other.$field_property_name$;\n" - " break;\n"); + "case $property_name$OneofCase.$field_property_name$:\n"); + printer->Indent(); + scoped_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field)); + generator->GenerateMergingCode(printer); + printer->Print("break;\n"); + printer->Outdent(); } printer->Outdent(); printer->Print("}\n\n"); } + // Merge unknown fields. + printer->Print( + "_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);\n"); + printer->Outdent(); printer->Print("}\n\n"); + + WriteGeneratedCodeAttributes(printer); printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n"); printer->Indent(); @@ -483,14 +514,14 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { printer->Indent(); // Option messages need to store unknown fields so that options can be parsed later. if (IsDescriptorOptionMessage(descriptor_)) { - printer->Print( + printer->Print( "default:\n" " CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);\n" " break;\n"); } else { printer->Print( "default:\n" - " input.SkipLastField();\n" // We're not storing the data, but we still need to consume it. + " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);\n" " break;\n"); } for (int i = 0; i < fields_by_number().size(); i++) { diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc index 438f3102..59b7edfb 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -171,6 +171,14 @@ void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) { "}\n"); } +void MessageOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) { + printer->Print(variables_, + "if ($property_name$ == null) {\n" + " $property_name$ = new $type_name$();\n" + "}\n" + "$property_name$.MergeFrom(other.$property_name$);\n"); +} + void MessageOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { // TODO(jonskeet): We may be able to do better than this printer->Print( diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.h b/src/google/protobuf/compiler/csharp/csharp_message_field.h index 7d614756..c41ee88a 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.h @@ -74,6 +74,7 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer); + virtual void GenerateMergingCode(io::Printer* printer); virtual void WriteToString(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc index 169122e6..c3003e3d 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc @@ -137,14 +137,22 @@ void PrimitiveFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { } void PrimitiveFieldGenerator::WriteHash(io::Printer* printer) { - printer->Print( - variables_, - "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n"); + const char *text = "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n"; + if (descriptor_->type() == FieldDescriptor::TYPE_FLOAT) { + text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode($property_name$);\n"; + } else if (descriptor_->type() == FieldDescriptor::TYPE_DOUBLE) { + text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode($property_name$);\n"; + } + printer->Print(variables_, text); } void PrimitiveFieldGenerator::WriteEquals(io::Printer* printer) { - printer->Print( - variables_, - "if ($property_name$ != other.$property_name$) return false;\n"); + const char *text = "if ($property_name$ != other.$property_name$) return false;\n"; + if (descriptor_->type() == FieldDescriptor::TYPE_FLOAT) { + text = "if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n"; + } else if (descriptor_->type() == FieldDescriptor::TYPE_DOUBLE) { + text = "if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n"; + } + printer->Print(variables_, text); } void PrimitiveFieldGenerator::WriteToString(io::Printer* printer) { printer->Print( @@ -196,6 +204,10 @@ void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) { "}\n"); } +void PrimitiveOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) { + printer->Print(variables_, "$property_name$ = other.$property_name$;\n"); +} + void PrimitiveOneofFieldGenerator::WriteToString(io::Printer* printer) { printer->Print(variables_, "PrintField(\"$descriptor_name$\", $has_property_check$, $oneof_name$_, writer);\n"); diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h index 5f466fc4..ca7b8b3d 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h @@ -78,6 +78,7 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator { virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer); + virtual void GenerateMergingCode(io::Printer* printer); virtual void WriteToString(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc index bac9aef7..5ddd616e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc +++ b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc @@ -104,8 +104,10 @@ void ReflectionClassGenerator::Generate(io::Printer* printer) { void ReflectionClassGenerator::WriteIntroduction(io::Printer* printer) { printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// source: $file_name$\n" + "// <auto-generated>\n" + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $file_name$\n" + "// </auto-generated>\n" "#pragma warning disable 1591, 0612, 3021\n" "#region Designer generated code\n" "\n" diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc index 797d498e..047edf73 100644 --- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc @@ -120,15 +120,25 @@ void WrapperFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { } void WrapperFieldGenerator::WriteHash(io::Printer* printer) { - printer->Print( - variables_, - "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n"); + const char *text = "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n"; + if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_FLOAT) { + text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseNullableSingleEqualityComparer.GetHashCode($property_name$);\n"; + } + else if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_DOUBLE) { + text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseNullableDoubleEqualityComparer.GetHashCode($property_name$);\n"; + } + printer->Print(variables_, text); } void WrapperFieldGenerator::WriteEquals(io::Printer* printer) { - printer->Print( - variables_, - "if ($property_name$ != other.$property_name$) return false;\n"); + const char *text = "if ($property_name$ != other.$property_name$) return false;\n"; + if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_FLOAT) { + text = "if (!pbc::ProtobufEqualityComparers.BitwiseNullableSingleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n"; + } + else if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_DOUBLE) { + text = "if (!pbc::ProtobufEqualityComparers.BitwiseNullableDoubleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n"; + } + printer->Print(variables_, text); } void WrapperFieldGenerator::WriteToString(io::Printer* printer) { @@ -181,6 +191,10 @@ void WrapperOneofFieldGenerator::GenerateMembers(io::Printer* printer) { "}\n"); } +void WrapperOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) { + printer->Print(variables_, "$property_name$ = other.$property_name$;\n"); +} + void WrapperOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { printer->Print( variables_, diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h index 250dfd25..452531fb 100644 --- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h @@ -75,6 +75,7 @@ class WrapperOneofFieldGenerator : public WrapperFieldGenerator { ~WrapperOneofFieldGenerator(); virtual void GenerateMembers(io::Printer* printer); + virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); virtual void GenerateSerializationCode(io::Printer* printer); virtual void GenerateSerializedSizeCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc index 844edc1c..a5341e0d 100644 --- a/src/google/protobuf/compiler/importer.cc +++ b/src/google/protobuf/compiler/importer.cc @@ -32,8 +32,9 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. + #ifdef _MSC_VER -#include <io.h> +#include <direct.h> #else #include <unistd.h> #endif @@ -54,16 +55,21 @@ #include <google/protobuf/io/tokenizer.h> #include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/io_win32.h> + +#ifdef _WIN32 +#include <ctype.h> +#endif namespace google { namespace protobuf { namespace compiler { #ifdef _WIN32 -#ifndef F_OK -#define F_OK 00 // not defined by MSVC for whatever reason -#endif -#include <ctype.h> +// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import +// them like we do below. +using google::protobuf::internal::win32::access; +using google::protobuf::internal::win32::open; #endif // Returns true if the text looks like a Windows-style absolute path, starting @@ -295,10 +301,8 @@ static string CanonicalizePath(string path) { } static inline bool ContainsParentReference(const string& path) { - return path == ".." || - HasPrefixString(path, "../") || - HasSuffixString(path, "/..") || - path.find("/../") != string::npos; + return path == ".." || HasPrefixString(path, "../") || + HasSuffixString(path, "/..") || path.find("/../") != string::npos; } // Maps a file from an old location to a new one. Typically, old_prefix is @@ -328,8 +332,7 @@ static bool ApplyMapping(const string& filename, // We do not allow the file name to use "..". return false; } - if (HasPrefixString(filename, "/") || - IsWindowsAbsolutePath(filename)) { + if (HasPrefixString(filename, "/") || IsWindowsAbsolutePath(filename)) { // This is an absolute path, so it isn't matched by the empty string. return false; } diff --git a/src/google/protobuf/compiler/java/java_context.cc b/src/google/protobuf/compiler/java/java_context.cc index b82fb3dd..0771d5e1 100644 --- a/src/google/protobuf/compiler/java/java_context.cc +++ b/src/google/protobuf/compiler/java/java_context.cc @@ -50,7 +50,7 @@ Context::Context(const FileDescriptor* file, const Options& options) Context::~Context() { } -ClassNameResolver* Context::GetNameResolver() { +ClassNameResolver* Context::GetNameResolver() const { return name_resolver_.get(); } @@ -154,7 +154,7 @@ void Context::InitializeFieldGeneratorInfoForFields( for (int i = 0; i < fields.size(); ++i) { const FieldDescriptor* field = fields[i]; FieldGeneratorInfo info; - info.name = UnderscoresToCamelCase(field); + info.name = CamelCaseFieldName(field); info.capitalized_name = UnderscoresToCapitalizedCamelCase(field); // For fields conflicting with some other fields, we append the field // number to their field names in generated code to avoid conflicts. diff --git a/src/google/protobuf/compiler/java/java_context.h b/src/google/protobuf/compiler/java/java_context.h index b22e7e3a..9a74c430 100644 --- a/src/google/protobuf/compiler/java/java_context.h +++ b/src/google/protobuf/compiler/java/java_context.h @@ -70,7 +70,7 @@ class Context { // Get the name resolver associated with this context. The resolver // can be used to map descriptors to Java class names. - ClassNameResolver* GetNameResolver(); + ClassNameResolver* GetNameResolver() const; // Get the FieldGeneratorInfo for a given field. const FieldGeneratorInfo* GetFieldGeneratorInfo( diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc index b9ee00ff..d125ebe5 100644 --- a/src/google/protobuf/compiler/java/java_enum.cc +++ b/src/google/protobuf/compiler/java/java_enum.cc @@ -109,14 +109,16 @@ void EnumGenerator::Generate(io::Printer* printer) { printer->Print(vars, "$name$($index$, $number$),\n"); } + printer->Annotate("name", canonical_values_[i]); } if (SupportUnknownEnumValue(descriptor_->file())) { if (ordinal_is_index) { - printer->Print("UNRECOGNIZED(-1),\n"); + printer->Print("${$UNRECOGNIZED$}$(-1),\n", "{", "", "}", ""); } else { - printer->Print("UNRECOGNIZED(-1, -1),\n"); + printer->Print("${$UNRECOGNIZED$}$(-1, -1),\n", "{", "", "}", ""); } + printer->Annotate("{", "}", descriptor_); } printer->Print( @@ -133,15 +135,19 @@ void EnumGenerator::Generate(io::Printer* printer) { WriteEnumValueDocComment(printer, aliases_[i].value); printer->Print(vars, "public static final $classname$ $name$ = $canonical_name$;\n"); + printer->Annotate("name", aliases_[i].value); } for (int i = 0; i < descriptor_->value_count(); i++) { std::map<string, string> vars; vars["name"] = descriptor_->value(i)->name(); vars["number"] = SimpleItoa(descriptor_->value(i)->number()); + vars["{"] = ""; + vars["}"] = ""; WriteEnumValueDocComment(printer, descriptor_->value(i)); printer->Print(vars, - "public static final int $name$_VALUE = $number$;\n"); + "public static final int ${$$name$_VALUE$}$ = $number$;\n"); + printer->Annotate("{", "}", descriptor_->value(i)); } printer->Print("\n"); diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc index 279b9da4..642cdd36 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/src/google/protobuf/compiler/java/java_enum_field.cc @@ -80,7 +80,7 @@ void SetEnumVariables(const FieldDescriptor* descriptor, // Use deprecated valueOf() method to be compatible with old generated code // for v2.5.0/v2.6.1. // TODO(xiaofeng): Use "forNumber" when we no longer support compatibility - // with v2.5.0/v2.6.1. + // with v2.5.0/v2.6.1, and remove the @SuppressWarnings annotations. (*variables)["for_number"] = "valueOf"; if (SupportFieldPresence(descriptor->file())) { @@ -183,23 +183,27 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " @SuppressWarnings(\"deprecation\")\n" " $type$ result = $type$.$for_number$($name$_);\n" " return result == null ? $unknown$ : result;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumFieldGenerator:: @@ -209,33 +213,39 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_builder$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" " $name$_ = value;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " @SuppressWarnings(\"deprecation\")\n" " $type$ result = $type$.$for_number$($name$_);\n" " return result == null ? $unknown$ : result;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" " }\n" @@ -244,14 +254,16 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $clear_has_field_bit_builder$\n" " $name$_ = $default_number$;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumFieldGenerator:: @@ -310,13 +322,10 @@ GenerateParsingCode(io::Printer* printer) const { } else { printer->Print(variables_, "int rawValue = input.readEnum();\n" + " @SuppressWarnings(\"deprecation\")\n" "$type$ value = $type$.$for_number$(rawValue);\n" - "if (value == null) {\n"); - if (PreserveUnknownFields(descriptor_->containing_type())) { - printer->Print(variables_, - " unknownFields.mergeVarintField($number$, rawValue);\n"); - } - printer->Print(variables_, + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" "} else {\n" " $set_has_field_bit_message$\n" " $name$_ = rawValue;\n" @@ -386,30 +395,34 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " if ($has_oneof_case_message$) {\n" " return (java.lang.Integer) $oneof_name$_;\n" " }\n" " return $default_number$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" + " @SuppressWarnings(\"deprecation\")\n" " $type$ result = $type$.$for_number$(\n" " (java.lang.Integer) $oneof_name$_);\n" " return result == null ? $unknown$ : result;\n" " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumOneofFieldGenerator:: @@ -417,41 +430,47 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ((java.lang.Integer) $oneof_name$_).intValue();\n" " }\n" " return $default_number$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = value;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" + " @SuppressWarnings(\"deprecation\")\n" " $type$ result = $type$.$for_number$(\n" " (java.lang.Integer) $oneof_name$_);\n" " return result == null ? $unknown$ : result;\n" " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" " }\n" @@ -460,9 +479,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" " $oneof_name$_ = null;\n" @@ -470,6 +490,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumOneofFieldGenerator:: @@ -501,13 +522,10 @@ GenerateParsingCode(io::Printer* printer) const { } else { printer->Print(variables_, "int rawValue = input.readEnum();\n" + "@SuppressWarnings(\"deprecation\")\n" "$type$ value = $type$.$for_number$(rawValue);\n" - "if (value == null) {\n"); - if (PreserveUnknownFields(descriptor_->containing_type())) { - printer->Print(variables_, - " unknownFields.mergeVarintField($number$, rawValue);\n"); - } - printer->Print(variables_, + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" "} else {\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = rawValue;\n" @@ -614,6 +632,7 @@ GenerateMembers(io::Printer* printer) const { " new com.google.protobuf.Internal.ListAdapter.Converter<\n" " java.lang.Integer, $type$>() {\n" " public $type$ convert(java.lang.Integer from) {\n" + " @SuppressWarnings(\"deprecation\")\n" " $type$ result = $type$.$for_number$(from);\n" " return result == null ? $unknown$ : result;\n" " }\n" @@ -621,32 +640,38 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return new com.google.protobuf.Internal.ListAdapter<\n" " java.lang.Integer, $type$>($name$_, $name$_converter_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_converter_.convert($name$_.get(index));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<java.lang.Integer>\n" - "get$capitalized_name$ValueList() {\n" + "${$get$capitalized_name$ValueList$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value(int index) {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (descriptor_->is_packed() && @@ -684,23 +709,27 @@ GenerateBuilderMembers(io::Printer* printer) const { // could hold on to the returned list and modify it after the message // has been built, thus mutating the message which is supposed to be // immutable. - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return new com.google.protobuf.Internal.ListAdapter<\n" " java.lang.Integer, $type$>($name$_, $name$_converter_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_converter_.convert($name$_.get(index));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" @@ -710,9 +739,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" " }\n" @@ -721,9 +751,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $type$> values) {\n" " ensure$capitalized_name$IsMutable();\n" " for ($type$ value : values) {\n" @@ -732,47 +763,54 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $name$_ = java.util.Collections.emptyList();\n" " $clear_mutable_bit_builder$;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<java.lang.Integer>\n" - "get$capitalized_name$ValueList() {\n" + "${$get$capitalized_name$ValueList$}$() {\n" " return java.util.Collections.unmodifiableList($name$_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value(int index) {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(\n" + "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n" " int index, int value) {\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.set(index, value);\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$add$capitalized_name$Value$}$(int value) {\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.add(value);\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$Value(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n" " java.lang.Iterable<java.lang.Integer> values) {\n" " ensure$capitalized_name$IsMutable();\n" " for (int value : values) {\n" @@ -781,6 +819,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -847,13 +886,10 @@ GenerateParsingCode(io::Printer* printer) const { } else { printer->Print(variables_, "int rawValue = input.readEnum();\n" + "@SuppressWarnings(\"deprecation\")\n" "$type$ value = $type$.$for_number$(rawValue);\n" - "if (value == null) {\n"); - if (PreserveUnknownFields(descriptor_->containing_type())) { - printer->Print(variables_, - " unknownFields.mergeVarintField($number$, rawValue);\n"); - } - printer->Print(variables_, + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" "} else {\n" " if (!$get_mutable_bit_parser$) {\n" " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n" diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc index 1eefdcfc..a4de1e23 100644 --- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc @@ -165,23 +165,26 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " $type$ result = $type$.forNumber($name$_);\n" " return result == null ? $unknown$ : result;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Generate private setters for the builder to proxy into. if (SupportUnknownEnumValue(descriptor_->file())) { @@ -214,43 +217,50 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return instance.get$capitalized_name$Value();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$Value(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumFieldLiteGenerator:: @@ -296,12 +306,8 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "int rawValue = input.readEnum();\n" "$type$ value = $type$.forNumber(rawValue);\n" - "if (value == null) {\n"); - if (PreserveUnknownFields(descriptor_->containing_type())) { - printer->Print(variables_, - " super.mergeVarintField($number$, rawValue);\n"); - } - printer->Print(variables_, + "if (value == null) {\n" + " super.mergeVarintField($number$, rawValue);\n" "} else {\n" " $set_has_field_bit_message$\n" " $name$_ = rawValue;\n" @@ -372,29 +378,32 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " if ($has_oneof_case_message$) {\n" " return (java.lang.Integer) $oneof_name$_;\n" " }\n" " return $default_number$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $type$ result = $type$.forNumber((java.lang.Integer) $oneof_name$_);\n" " return result == null ? $unknown$ : result;\n" " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Generate private setters for the builder to proxy into. if (SupportUnknownEnumValue(descriptor_->file())) { @@ -430,43 +439,50 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value() {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " return instance.get$capitalized_name$Value();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$Value(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableEnumOneofFieldLiteGenerator:: @@ -487,12 +503,8 @@ GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, "int rawValue = input.readEnum();\n" "$type$ value = $type$.forNumber(rawValue);\n" - "if (value == null) {\n"); - if (PreserveUnknownFields(descriptor_->containing_type())) { - printer->Print(variables_, - " super.mergeVarintField($number$, rawValue);\n"); - } - printer->Print(variables_, + "if (value == null) {\n" + " super.mergeVarintField($number$, rawValue);\n" "} else {\n" " $set_oneof_case_message$;\n" " $oneof_name$_ = rawValue;\n" @@ -607,35 +619,41 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return new com.google.protobuf.Internal.ListAdapter<\n" " java.lang.Integer, $type$>($name$_, $name$_converter_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_converter_.convert($name$_.getInt(index));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<java.lang.Integer>\n" - "get$capitalized_name$ValueList() {\n" + "${$get$capitalized_name$ValueList$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value(int index) {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$(int index) {\n" " return $name$_.getInt(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } - if (descriptor_->options().packed() && + if (descriptor_->is_packed() && context_->HasGeneratedMethods(descriptor_->containing_type())) { printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n"); @@ -714,85 +732,99 @@ void RepeatedImmutableEnumFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return instance.get$capitalized_name$List();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $type$> values) {\n" " copyOnWrite();\n" " instance.addAll$capitalized_name$(values);" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<java.lang.Integer>\n" - "get$capitalized_name$ValueList() {\n" + "${$get$capitalized_name$ValueList$}$() {\n" " return java.util.Collections.unmodifiableList(\n" " instance.get$capitalized_name$ValueList());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Value(int index) {\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$(int index) {\n" " return instance.get$capitalized_name$Value(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Value(\n" + "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n" " int index, int value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$Value(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$Value(int value) {\n" + "$deprecation$public Builder " + "${$add$capitalized_name$Value$}$(int value) {\n" " instance.add$capitalized_name$Value(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$Value(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n" " java.lang.Iterable<java.lang.Integer> values) {\n" " copyOnWrite();\n" " instance.addAll$capitalized_name$Value(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -889,7 +921,7 @@ GenerateParsingDoneCode(io::Printer* printer) const { void RepeatedImmutableEnumFieldLiteGenerator:: GenerateSerializationCode(io::Printer* printer) const { - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (get$capitalized_name$List().size() > 0) {\n" " output.writeUInt32NoTag($tag$);\n" @@ -920,7 +952,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "}\n"); printer->Print( "size += dataSize;\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (!get$capitalized_name$List().isEmpty()) {" " size += $tag_size$;\n" @@ -933,7 +965,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } // cache the data size for packed fields. - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n"); } diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc index 38b054e7..ab3b3323 100644 --- a/src/google/protobuf/compiler/java/java_enum_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_lite.cc @@ -93,10 +93,12 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { } printer->Print(vars, "$name$($number$),\n"); + printer->Annotate("name", canonical_values_[i]); } if (SupportUnknownEnumValue(descriptor_->file())) { - printer->Print("UNRECOGNIZED(-1),\n"); + printer->Print("${$UNRECOGNIZED$}$(-1),\n", "{", "", "}", ""); + printer->Annotate("{", "}", descriptor_); } printer->Print( @@ -113,15 +115,19 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { WriteEnumValueDocComment(printer, aliases_[i].value); printer->Print(vars, "public static final $classname$ $name$ = $canonical_name$;\n"); + printer->Annotate("name", aliases_[i].value); } for (int i = 0; i < descriptor_->value_count(); i++) { std::map<string, string> vars; vars["name"] = descriptor_->value(i)->name(); vars["number"] = SimpleItoa(descriptor_->value(i)->number()); + vars["{"] = ""; + vars["}"] = ""; WriteEnumValueDocComment(printer, descriptor_->value(i)); printer->Print(vars, - "public static final int $name$_VALUE = $number$;\n"); + "public static final int ${$$name$_VALUE$}$ = $number$;\n"); + printer->Annotate("{", "}", descriptor_->value(i)); } printer->Print("\n"); diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc index cb237bf6..9b9be55b 100644 --- a/src/google/protobuf/compiler/java/java_extension.cc +++ b/src/google/protobuf/compiler/java/java_extension.cc @@ -75,7 +75,7 @@ void ExtensionGenerator::InitTemplateVars( vars["default"] = descriptor->is_repeated() ? "" : DefaultValue(descriptor, immutable, name_resolver); vars["type_constant"] = FieldTypeName(GetType(descriptor)); - vars["packed"] = descriptor->options().packed() ? "true" : "false"; + vars["packed"] = descriptor->is_packed() ? "true" : "false"; vars["enum_map"] = "null"; vars["prototype"] = "null"; diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc index 04917296..1ab18629 100644 --- a/src/google/protobuf/compiler/java/java_field.cc +++ b/src/google/protobuf/compiler/java/java_field.cc @@ -45,8 +45,6 @@ #include <google/protobuf/compiler/java/java_enum_field.h> #include <google/protobuf/compiler/java/java_enum_field_lite.h> #include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/compiler/java/java_lazy_message_field.h> -#include <google/protobuf/compiler/java/java_lazy_message_field_lite.h> #include <google/protobuf/compiler/java/java_map_field.h> #include <google/protobuf/compiler/java/java_map_field_lite.h> #include <google/protobuf/compiler/java/java_message_field.h> @@ -77,13 +75,8 @@ ImmutableFieldGenerator* MakeImmutableGenerator( return new ImmutableMapFieldGenerator( field, messageBitIndex, builderBitIndex, context); } else { - if (IsLazy(field, context->EnforceLite())) { - return new RepeatedImmutableLazyMessageFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new RepeatedImmutableMessageFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new RepeatedImmutableMessageFieldGenerator( + field, messageBitIndex, builderBitIndex, context); } case JAVATYPE_ENUM: return new RepeatedImmutableEnumFieldGenerator( @@ -99,13 +92,8 @@ ImmutableFieldGenerator* MakeImmutableGenerator( if (field->containing_oneof()) { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: - if (IsLazy(field, context->EnforceLite())) { - return new ImmutableLazyMessageOneofFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new ImmutableMessageOneofFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new ImmutableMessageOneofFieldGenerator( + field, messageBitIndex, builderBitIndex, context); case JAVATYPE_ENUM: return new ImmutableEnumOneofFieldGenerator( field, messageBitIndex, builderBitIndex, context); @@ -119,13 +107,8 @@ ImmutableFieldGenerator* MakeImmutableGenerator( } else { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: - if (IsLazy(field, context->EnforceLite())) { - return new ImmutableLazyMessageFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new ImmutableMessageFieldGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new ImmutableMessageFieldGenerator( + field, messageBitIndex, builderBitIndex, context); case JAVATYPE_ENUM: return new ImmutableEnumFieldGenerator( field, messageBitIndex, builderBitIndex, context); @@ -150,13 +133,8 @@ ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator( return new ImmutableMapFieldLiteGenerator( field, messageBitIndex, builderBitIndex, context); } else { - if (IsLazy(field, context->EnforceLite())) { - return new RepeatedImmutableLazyMessageFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new RepeatedImmutableMessageFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new RepeatedImmutableMessageFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); } case JAVATYPE_ENUM: return new RepeatedImmutableEnumFieldLiteGenerator( @@ -172,13 +150,8 @@ ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator( if (field->containing_oneof()) { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: - if (IsLazy(field, context->EnforceLite())) { - return new ImmutableLazyMessageOneofFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new ImmutableMessageOneofFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new ImmutableMessageOneofFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); case JAVATYPE_ENUM: return new ImmutableEnumOneofFieldLiteGenerator( field, messageBitIndex, builderBitIndex, context); @@ -192,13 +165,8 @@ ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator( } else { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: - if (IsLazy(field, context->EnforceLite())) { - return new ImmutableLazyMessageFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } else { - return new ImmutableMessageFieldLiteGenerator( - field, messageBitIndex, builderBitIndex, context); - } + return new ImmutableMessageFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); case JAVATYPE_ENUM: return new ImmutableEnumFieldLiteGenerator( field, messageBitIndex, builderBitIndex, context); @@ -293,10 +261,17 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, std::map<string, string>* variables) { (*variables)["field_name"] = descriptor->name(); (*variables)["name"] = info->name; + (*variables)["classname"] = descriptor->containing_type()->name(); (*variables)["capitalized_name"] = info->capitalized_name; (*variables)["disambiguated_reason"] = info->disambiguated_reason; (*variables)["constant_name"] = FieldConstantName(descriptor); (*variables)["number"] = SimpleItoa(descriptor->number()); + // These variables are placeholders to pick out the beginning and ends of + // identifiers for annotations (when doing so with existing variables would + // be ambiguous or impossible). They should never be set to anything but the + // empty string. + (*variables)["{"] = ""; + (*variables)["}"] = ""; } void SetCommonOneofVariables(const FieldDescriptor* descriptor, diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index 0fda166d..21133a15 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -248,9 +248,12 @@ void FileGenerator::Generate(io::Printer* printer) { PrintGeneratedAnnotation( printer, '$', options_.annotate_code ? classname_ + ".java.pb.meta" : ""); printer->Print( - "public final class $classname$ {\n" + "$deprecation$public final class $classname$ {\n" " private $ctor$() {}\n", - "classname", classname_, "ctor", classname_); + "deprecation", file_->options().deprecated() ? + "@java.lang.Deprecated " : "", + "classname", classname_, + "ctor", classname_); printer->Annotate("classname", file_->name()); printer->Indent(); @@ -499,19 +502,57 @@ void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer* // Try to load immutable messages' outer class. Its initialization code // will take care of interpreting custom options. printer->Print( - "try {\n" - // Note that we have to load the immutable class dynamically here as - // we want the mutable code to be independent from the immutable code - // at compile time. It is required to implement dual-compile for - // mutable and immutable API in blaze. - " java.lang.Class immutableClass = java.lang.Class.forName(\n" - " \"$immutable_classname$\");\n" - "} catch (java.lang.ClassNotFoundException e) {\n" - // The immutable class can not be found. Custom options are left - // as unknown fields. - // TODO(xiaofeng): inform the user with a warning? - "}\n", - "immutable_classname", name_resolver_->GetImmutableClassName(file_)); + "try {\n" + // Note that we have to load the immutable class dynamically here as + // we want the mutable code to be independent from the immutable code + // at compile time. It is required to implement dual-compile for + // mutable and immutable API in blaze. + " java.lang.Class immutableClass = java.lang.Class.forName(\n" + " \"$immutable_classname$\");\n" + "} catch (java.lang.ClassNotFoundException e) {\n", + "immutable_classname", name_resolver_->GetImmutableClassName(file_)); + printer->Indent(); + + // The immutable class can not be found. We try our best to collect all + // custom option extensions to interpret the custom options. + printer->Print( + "com.google.protobuf.ExtensionRegistry registry =\n" + " com.google.protobuf.ExtensionRegistry.newInstance();\n" + "com.google.protobuf.MessageLite defaultExtensionInstance = null;\n"); + FieldDescriptorSet::iterator it; + for (it = extensions.begin(); it != extensions.end(); it++) { + const FieldDescriptor* field = *it; + string scope; + if (field->extension_scope() != NULL) { + scope = name_resolver_->GetMutableClassName(field->extension_scope()) + + ".getDescriptor()"; + } else { + scope = FileJavaPackage(field->file(), true) + "." + + name_resolver_->GetDescriptorClassName(field->file()) + + ".descriptor"; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer->Print( + "defaultExtensionInstance = com.google.protobuf.Internal\n" + " .getDefaultInstance(\"$class$\");\n" + "if (defaultExtensionInstance != null) {\n" + " registry.add(\n" + " $scope$.getExtensions().get($index$),\n" + " (com.google.protobuf.Message) defaultExtensionInstance);\n" + "}\n", + "scope", scope, "index", SimpleItoa(field->index()), "class", + name_resolver_->GetImmutableClassName(field->message_type())); + } else { + printer->Print("registry.add($scope$.getExtensions().get($index$));\n", + "scope", scope, "index", SimpleItoa(field->index())); + } + } + printer->Print( + "com.google.protobuf.Descriptors.FileDescriptor\n" + " .internalUpdateFileDescriptor(descriptor, registry);\n"); + + printer->Outdent(); + printer->Print("}\n"); } // Force descriptor initialization of all dependencies. diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc index 02141210..84a3b90d 100644 --- a/src/google/protobuf/compiler/java/java_generator.cc +++ b/src/google/protobuf/compiler/java/java_generator.cc @@ -42,6 +42,7 @@ #include <google/protobuf/compiler/java/java_file.h> #include <google/protobuf/compiler/java/java_generator_factory.h> #include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/compiler/java/java_options.h> #include <google/protobuf/compiler/java/java_shared_code_generator.h> #include <google/protobuf/io/printer.h> diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc index 8469740f..dbb86b87 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -37,12 +37,15 @@ #include <limits> #include <vector> +#include <google/protobuf/stubs/stringprintf.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> + + #include <google/protobuf/stubs/hash.h> // for hash<T *> namespace google { @@ -167,6 +170,14 @@ string UniqueFileScopeIdentifier(const Descriptor* descriptor) { return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); } +string CamelCaseFieldName(const FieldDescriptor* field) { + string fieldName = UnderscoresToCamelCase(field); + if ('0' <= fieldName[0] && fieldName[0] <= '9') { + return '_' + fieldName; + } + return fieldName; +} + string StripProto(const string& filename) { if (HasSuffixString(filename, ".protodevel")) { return StripSuffixString(filename, ".protodevel"); @@ -773,6 +784,137 @@ bool HasRepeatedFields(const Descriptor* descriptor) { return false; } +// Encode an unsigned 32-bit value into a sequence of UTF-16 characters. +// +// If the value is in [0x0000, 0xD7FF], we encode it with a single character +// with the same numeric value. +// +// If the value is larger than 0xD7FF, we encode its lowest 13 bits into a +// character in the range [0xE000, 0xFFFF] by combining these 13 bits with +// 0xE000 using logic-or. Then we shift the value to the right by 13 bits, and +// encode the remaining value by repeating this same process until we get to +// a value in [0x0000, 0xD7FF] where we will encode it using a character with +// the same numeric value. +// +// Note that we only use code points in [0x0000, 0xD7FF] and [0xE000, 0xFFFF]. +// There will be no surrogate pairs in the encoded character sequence. +void WriteUInt32ToUtf16CharSequence(uint32 number, + std::vector<uint16>* output) { + // For values in [0x0000, 0xD7FF], only use one char to encode it. + if (number < 0xD800) { + output->push_back(static_cast<uint16>(number)); + return; + } + // Encode into multiple chars. All except the last char will be in the range + // [0xE000, 0xFFFF], and the last char will be in the range [0x0000, 0xD7FF]. + // Note that we don't use any value in range [0xD800, 0xDFFF] because they + // have to come in pairs and the encoding is just more space-efficient w/o + // them. + while (number >= 0xD800) { + // [0xE000, 0xFFFF] can represent 13 bits of info. + output->push_back(static_cast<uint16>(0xE000 | (number & 0x1FFF))); + number >>= 13; + } + output->push_back(static_cast<uint16>(number)); +} + +int GetExperimentalJavaFieldTypeForSingular(const FieldDescriptor* field) { + // j/c/g/protobuf/FieldType.java lists field types in a slightly different + // order from FieldDescriptor::Type so we can't do a simple cast. + // + // TODO(xiaofeng): Make j/c/g/protobuf/FieldType.java follow the same order. + int result = field->type(); + if (result == FieldDescriptor::TYPE_GROUP) { + return 17; + } else if (result < FieldDescriptor::TYPE_GROUP) { + return result - 1; + } else { + return result - 2; + } +} + +int GetExperimentalJavaFieldTypeForRepeated(const FieldDescriptor* field) { + if (field->type() == FieldDescriptor::TYPE_GROUP) { + return 49; + } else { + return GetExperimentalJavaFieldTypeForSingular(field) + 18; + } +} + +int GetExperimentalJavaFieldTypeForPacked(const FieldDescriptor* field) { + int result = field->type(); + if (result < FieldDescriptor::TYPE_STRING) { + return result + 34; + } else if (result > FieldDescriptor::TYPE_BYTES) { + return result + 30; + } else { + GOOGLE_LOG(FATAL) << field->full_name() << " can't be packed."; + return 0; + } +} + +int GetExperimentalJavaFieldType(const FieldDescriptor* field) { + static const int kMapFieldType = 50; + static const int kOneofFieldTypeOffset = 51; + static const int kRequiredBit = 0x100; + static const int kUtf8CheckBit = 0x200; + static const int kCheckInitialized = 0x400; + static const int kMapWithProto2EnumValue = 0x800; + int extra_bits = field->is_required() ? kRequiredBit : 0; + if (field->type() == FieldDescriptor::TYPE_STRING && CheckUtf8(field)) { + extra_bits |= kUtf8CheckBit; + } + if (field->is_required() || (GetJavaType(field) == JAVATYPE_MESSAGE && + HasRequiredFields(field->message_type()))) { + extra_bits |= kCheckInitialized; + } + + if (field->is_map()) { + if (SupportFieldPresence(field->file())) { + const FieldDescriptor* value = + field->message_type()->FindFieldByName("value"); + if (GetJavaType(value) == JAVATYPE_ENUM) { + extra_bits |= kMapWithProto2EnumValue; + } + } + return kMapFieldType | extra_bits; + } else if (field->is_packed()) { + return GetExperimentalJavaFieldTypeForPacked(field); + } else if (field->is_repeated()) { + return GetExperimentalJavaFieldTypeForRepeated(field) | extra_bits; + } else if (field->containing_oneof() != NULL) { + return (GetExperimentalJavaFieldTypeForSingular(field) + + kOneofFieldTypeOffset) | + extra_bits; + } else { + return GetExperimentalJavaFieldTypeForSingular(field) | extra_bits; + } +} + +// Escape a UTF-16 character to be embedded in a Java string. +void EscapeUtf16ToString(uint16 code, string* output) { + if (code == '\t') { + output->append("\\t"); + } else if (code == '\b') { + output->append("\\b"); + } else if (code == '\n') { + output->append("\\n"); + } else if (code == '\r') { + output->append("\\r"); + } else if (code == '\f') { + output->append("\\f"); + } else if (code == '\'') { + output->append("\\'"); + } else if (code == '\"') { + output->append("\\\""); + } else if (code == '\\') { + output->append("\\\\"); + } else if (code >= 0x20 && code <= 0x7f) { + output->push_back(static_cast<char>(code)); + } else { + output->append(StringPrintf("\\u%04x", code)); + } +} } // namespace java } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h index 829ec3d7..00d683db 100644 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ b/src/google/protobuf/compiler/java/java_helpers.h @@ -74,6 +74,10 @@ string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field); // of lower-casing the first letter of the name.) string UnderscoresToCamelCase(const MethodDescriptor* method); +// Similar to UnderscoresToCamelCase, but guarentees that the result is a +// complete Java identifier by adding a _ if needed. +string CamelCaseFieldName(const FieldDescriptor* field); + // Get an identifier that uniquely identifies this type within the file. // This is used to declare static variables related to this type at the // outermost file scope. @@ -132,6 +136,13 @@ inline string ShortMutableJavaClassName(const Descriptor* descriptor) { return descriptor->name(); } +// Whether the given descriptor is for one of the core descriptor protos. We +// cannot currently use the new runtime with core protos since there is a +// bootstrapping problem with obtaining their descriptors. +inline bool IsDescriptorProto(const Descriptor* descriptor) { + return descriptor->file()->name() == "google/protobuf/descriptor.proto"; +} + // Whether we should generate multiple java files for messages. inline bool MultipleJavaFiles( @@ -242,15 +253,6 @@ inline bool HasGenericServices(const FileDescriptor *file, bool enforce_lite) { file->options().java_generic_services(); } -inline bool IsLazy(const FieldDescriptor* descriptor, bool enforce_lite) { - // Currently, the proto-lite version supports lazy field. - // TODO(niwasaki): Support lazy fields also for other proto runtimes. - if (HasDescriptorMethods(descriptor->file(), enforce_lite)) { - return false; - } - return descriptor->options().lazy(); -} - // Methods for shared bitfields. // Gets the name of the shared bitfield for the given index. @@ -372,14 +374,14 @@ inline bool IsMapField(const FieldDescriptor* descriptor) { return descriptor->is_map(); } -inline bool PreserveUnknownFields(const Descriptor* descriptor) { - return descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3; -} - inline bool IsAnyMessage(const Descriptor* descriptor) { return descriptor->full_name() == "google.protobuf.Any"; } +inline bool IsWrappersProtoFile(const FileDescriptor* descriptor) { + return descriptor->name() == "google/protobuf/wrappers.proto"; +} + inline bool CheckUtf8(const FieldDescriptor* descriptor) { return descriptor->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || descriptor->file()->options().java_string_check_utf8(); @@ -388,6 +390,30 @@ inline bool CheckUtf8(const FieldDescriptor* descriptor) { inline string GeneratedCodeVersionSuffix() { return "V3"; } + +inline bool EnableExperimentalRuntime(Context* context) { + return false; +} + +void WriteUInt32ToUtf16CharSequence(uint32 number, std::vector<uint16>* output); + +inline void WriteIntToUtf16CharSequence(int value, + std::vector<uint16>* output) { + WriteUInt32ToUtf16CharSequence(static_cast<uint32>(value), output); +} + +// Escape a UTF-16 character so it can be embedded in a Java string literal. +void EscapeUtf16ToString(uint16 code, string* output); + +// Only the lowest two bytes of the return value are used. The lowest byte +// is the integer value of a j/c/g/protobuf/FieldType enum. For the other +// byte: +// bit 0: whether the field is required. +// bit 1: whether the field requires UTF-8 validation. +// bit 2: whether the field needs isInitialized check. +// bit 3: whether the field is a map field with proto2 enum value. +// bits 4-7: unused +int GetExperimentalJavaFieldType(const FieldDescriptor* field); } // namespace java } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc index 608b5378..b22a2199 100644 --- a/src/google/protobuf/compiler/java/java_map_field.cc +++ b/src/google/protobuf/compiler/java/java_map_field.cc @@ -183,12 +183,14 @@ GenerateInterfaceMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$int get$capitalized_name$Count();\n"); + "$deprecation$int ${$get$capitalized_name$Count$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$boolean contains$capitalized_name$(\n" + "$deprecation$boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -197,23 +199,27 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$();\n"); + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$Map();\n"); + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$$value_enum_type$ get$capitalized_name$OrDefault(\n" + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_enum_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$$value_enum_type$ get$capitalized_name$OrThrow(\n" + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -222,25 +228,29 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$type_parameters$>\n" - "get$capitalized_name$Value();\n"); + "${$get$capitalized_name$Value$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$ValueMap();\n"); + "${$get$capitalized_name$ValueMap$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$ValueOrDefault(\n" + "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$ValueOrThrow(\n" + "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -250,25 +260,29 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$type_parameters$>\n" - "get$capitalized_name$();\n"); + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$Map();\n"); + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$OrDefault(\n" + "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$OrThrow(\n" + "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -349,23 +363,27 @@ GenerateBuilderMembers(io::Printer* printer) const { " return $name$_;\n" "}\n"); GenerateMapGetters(printer); - printer->Print(variables_, - "$deprecation$\n" - "public Builder clear$capitalized_name$() {\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .clear();\n" - " return this;\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$\n" + "public Builder ${$clear$capitalized_name$$}$() {\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .clear();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$\n" - "public Builder remove$capitalized_name$(\n" - " $key_type$ key) {\n" - " $key_null_check$\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .remove(key);\n" - " return this;\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$\n" + "public Builder ${$remove$capitalized_name$$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .remove(key);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -374,13 +392,14 @@ GenerateBuilderMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "getMutable$capitalized_name$() {\n" + "${$getMutable$capitalized_name$$}$() {\n" " return internalGetAdapted$capitalized_name$Map(\n" " internalGetMutable$capitalized_name$().getMutableMap());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder put$capitalized_name$(\n" + "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" " $key_type$ key,\n" " $value_enum_type$ value) {\n" " $key_null_check$\n" @@ -389,16 +408,18 @@ GenerateBuilderMembers(io::Printer* printer) const { " .put(key, $name$ValueConverter.doBackward(value));\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder putAll$capitalized_name$(\n" + "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" " internalGetAdapted$capitalized_name$Map(\n" " internalGetMutable$capitalized_name$().getMutableMap())\n" " .putAll(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -407,13 +428,14 @@ GenerateBuilderMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "getMutable$capitalized_name$Value() {\n" + "${$getMutable$capitalized_name$Value$}$() {\n" " return internalGetMutable$capitalized_name$().getMutableMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder put$capitalized_name$Value(\n" + "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n" " $key_type$ key,\n" " $value_type$ value) {\n" " $key_null_check$\n" @@ -421,15 +443,17 @@ GenerateBuilderMembers(io::Printer* printer) const { " .put(key, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder putAll$capitalized_name$Value(\n" + "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" " internalGetMutable$capitalized_name$().getMutableMap()\n" " .putAll(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -439,30 +463,35 @@ GenerateBuilderMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$type_parameters$>\n" - "getMutable$capitalized_name$() {\n" + "${$getMutable$capitalized_name$$}$() {\n" " return internalGetMutable$capitalized_name$().getMutableMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$" - "public Builder put$capitalized_name$(\n" - " $key_type$ key,\n" - " $value_type$ value) {\n" - " $key_null_check$\n" - " $value_null_check$\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .put(key, value);\n" - " return this;\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$" + "public Builder ${$put$capitalized_name$$}$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .put(key, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$\n" - "public Builder putAll$capitalized_name$(\n" - " java.util.Map<$type_parameters$> values) {\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .putAll(values);\n" - " return this;\n" - "}\n"); + printer->Print( + variables_, + "$deprecation$\n" + "public Builder ${$putAll$capitalized_name$$}$(\n" + " java.util.Map<$type_parameters$> values) {\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .putAll(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -471,18 +500,20 @@ GenerateMapGetters(io::Printer* printer) const { printer->Print( variables_, "$deprecation$\n" - "public int get$capitalized_name$Count() {\n" + "public int ${$get$capitalized_name$Count$}$() {\n" " return internalGet$capitalized_name$().getMap().size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public boolean contains$capitalized_name$(\n" + "public boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " return internalGet$capitalized_name$().getMap().containsKey(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -491,22 +522,25 @@ GenerateMapGetters(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$() {\n" + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$\n" - "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$Map() {\n" - " return internalGetAdapted$capitalized_name$Map(\n" - " internalGet$capitalized_name$().getMap());" - "}\n"); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$Map$}$() {\n" + " return internalGetAdapted$capitalized_name$Map(\n" + " internalGet$capitalized_name$().getMap());" + "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrDefault(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_enum_type$ defaultValue) {\n" " $key_null_check$\n" @@ -516,11 +550,12 @@ GenerateMapGetters(io::Printer* printer) const { " ? $name$ValueConverter.doForward(map.get(key))\n" " : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrThrow(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -530,6 +565,7 @@ GenerateMapGetters(io::Printer* printer) const { " }\n" " return $name$ValueConverter.doForward(map.get(key));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -538,22 +574,24 @@ GenerateMapGetters(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$Value() {\n" + "${$get$capitalized_name$Value$}$() {\n" " return get$capitalized_name$ValueMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$ValueMap() {\n" + "${$get$capitalized_name$ValueMap$}$() {\n" " return internalGet$capitalized_name$().getMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrDefault(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -561,11 +599,12 @@ GenerateMapGetters(io::Printer* printer) const { " internalGet$capitalized_name$().getMap();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrThrow(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -575,6 +614,7 @@ GenerateMapGetters(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -583,21 +623,25 @@ GenerateMapGetters(io::Printer* printer) const { " * Use {@link #get$capitalized_name$Map()} instead.\n" " */\n" "@java.lang.Deprecated\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$Map$}$() {\n" " return internalGet$capitalized_name$().getMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrDefault(\n" + "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -605,11 +649,12 @@ GenerateMapGetters(io::Printer* printer) const { " internalGet$capitalized_name$().getMap();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrThrow(\n" + "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$type_parameters$> map =\n" @@ -619,6 +664,7 @@ GenerateMapGetters(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.cc b/src/google/protobuf/compiler/java/java_map_field_lite.cc index 073d1cfc..f19ec271 100644 --- a/src/google/protobuf/compiler/java/java_map_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc @@ -166,12 +166,14 @@ GenerateInterfaceMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$int get$capitalized_name$Count();\n"); + "$deprecation$int ${$get$capitalized_name$Count$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$boolean contains$capitalized_name$(\n" + "$deprecation$boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -180,23 +182,27 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$();\n"); + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$Map();\n"); + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$$value_enum_type$ get$capitalized_name$OrDefault(\n" + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_enum_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$$value_enum_type$ get$capitalized_name$OrThrow(\n" + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -205,25 +211,29 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$type_parameters$>\n" - "get$capitalized_name$Value();\n"); + "${$get$capitalized_name$Value$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$ValueMap();\n"); + "${$get$capitalized_name$ValueMap$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$ValueOrDefault(\n" + "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$ValueOrThrow(\n" + "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -233,25 +243,29 @@ GenerateInterfaceMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "java.util.Map<$type_parameters$>\n" - "get$capitalized_name$();\n"); + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$java.util.Map<$type_parameters$>\n" - "get$capitalized_name$Map();\n"); + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$OrDefault(\n" + "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "$value_type$ get$capitalized_name$OrThrow(\n" + "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -288,18 +302,20 @@ GenerateMembers(io::Printer* printer) const { printer->Print( variables_, "$deprecation$\n" - "public int get$capitalized_name$Count() {\n" + "public int ${$get$capitalized_name$Count$}$() {\n" " return internalGet$capitalized_name$().size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public boolean contains$capitalized_name$(\n" + "public boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " return internalGet$capitalized_name$().containsKey(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -316,26 +332,28 @@ GenerateMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$() {\n" + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$Map() {\n" + "${$get$capitalized_name$Map$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " new com.google.protobuf.Internal.MapAdapter<\n" " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" " internalGet$capitalized_name$(),\n" " $name$ValueConverter));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrDefault(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_enum_type$ defaultValue) {\n" " $key_null_check$\n" @@ -345,11 +363,12 @@ GenerateMembers(io::Printer* printer) const { " ? $name$ValueConverter.doForward(map.get(key))\n" " : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrThrow(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -359,6 +378,7 @@ GenerateMembers(io::Printer* printer) const { " }\n" " return $name$ValueConverter.doForward(map.get(key));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -367,23 +387,25 @@ GenerateMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$Value() {\n" + "${$get$capitalized_name$Value$}$() {\n" " return get$capitalized_name$ValueMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$ValueMap() {\n" + "${$get$capitalized_name$ValueMap$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " internalGet$capitalized_name$());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrDefault(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -391,11 +413,12 @@ GenerateMembers(io::Printer* printer) const { " internalGet$capitalized_name$();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrThrow(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -405,6 +428,7 @@ GenerateMembers(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -413,22 +437,26 @@ GenerateMembers(io::Printer* printer) const { " * Use {@link #get$capitalized_name$Map()} instead.\n" " */\n" "@java.lang.Deprecated\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$Map$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " internalGet$capitalized_name$());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrDefault(\n" + "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -436,11 +464,12 @@ GenerateMembers(io::Printer* printer) const { " internalGet$capitalized_name$();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrThrow(\n" + "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$type_parameters$> map =\n" @@ -450,6 +479,7 @@ GenerateMembers(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } // Generate private setters for the builder to proxy into. @@ -490,37 +520,41 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print( variables_, "$deprecation$\n" - "public int get$capitalized_name$Count() {\n" + "public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Map().size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public boolean contains$capitalized_name$(\n" + "public boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " return instance.get$capitalized_name$Map().containsKey(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); printer->Print( variables_, "$deprecation$\n" - "public Builder clear$capitalized_name$() {\n" + "public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.getMutable$capitalized_name$Map().clear();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public Builder remove$capitalized_name$(\n" + "public Builder ${$remove$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " copyOnWrite();\n" " instance.getMutable$capitalized_name$Map().remove(key);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -529,23 +563,25 @@ GenerateBuilderMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$() {\n" + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - "get$capitalized_name$Map() {\n" + "${$get$capitalized_name$Map$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " instance.get$capitalized_name$Map());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrDefault(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_enum_type$ defaultValue) {\n" " $key_null_check$\n" @@ -555,11 +591,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " ? map.get(key)\n" " : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_enum_type$ get$capitalized_name$OrThrow(\n" + "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n" @@ -569,10 +606,11 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder put$capitalized_name$(\n" + "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" " $key_type$ key,\n" " $value_enum_type$ value) {\n" " $key_null_check$\n" @@ -581,15 +619,17 @@ GenerateBuilderMembers(io::Printer* printer) const { " instance.getMutable$capitalized_name$Map().put(key, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder putAll$capitalized_name$(\n" + "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" " copyOnWrite();\n" " instance.getMutable$capitalized_name$Map().putAll(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (SupportUnknownEnumValue(descriptor_->file())) { printer->Print( variables_, @@ -598,23 +638,25 @@ GenerateBuilderMembers(io::Printer* printer) const { " */\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$Value() {\n" + "${$get$capitalized_name$Value$}$() {\n" " return get$capitalized_name$ValueMap();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "get$capitalized_name$ValueMap() {\n" + "${$get$capitalized_name$ValueMap$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " instance.get$capitalized_name$ValueMap());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrDefault(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -622,11 +664,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " instance.get$capitalized_name$ValueMap();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$ValueOrThrow(\n" + "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" @@ -636,10 +679,11 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder put$capitalized_name$Value(\n" + "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n" " $key_type$ key,\n" " $value_type$ value) {\n" " $key_null_check$\n" @@ -647,15 +691,17 @@ GenerateBuilderMembers(io::Printer* printer) const { " instance.getMutable$capitalized_name$ValueMap().put(key, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, - "$deprecation$public Builder putAll$capitalized_name$Value(\n" + "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n" " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" " copyOnWrite();\n" " instance.getMutable$capitalized_name$ValueMap().putAll(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } else { printer->Print( @@ -664,22 +710,26 @@ GenerateBuilderMembers(io::Printer* printer) const { " * Use {@link #get$capitalized_name$Map()} instead.\n" " */\n" "@java.lang.Deprecated\n" - "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$$}$() {\n" " return get$capitalized_name$Map();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$" - "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$Map$}$() {\n" " return java.util.Collections.unmodifiableMap(\n" " instance.get$capitalized_name$Map());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrDefault(\n" + "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" " $value_type$ defaultValue) {\n" " $key_null_check$\n" @@ -687,11 +737,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " instance.get$capitalized_name$Map();\n" " return map.containsKey(key) ? map.get(key) : defaultValue;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$\n" - "public $value_type$ get$capitalized_name$OrThrow(\n" + "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" " java.util.Map<$type_parameters$> map =\n" @@ -701,11 +752,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return map.get(key);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$" - "public Builder put$capitalized_name$(\n" + "public Builder ${$put$capitalized_name$$}$(\n" " $key_type$ key,\n" " $value_type$ value) {\n" " $key_null_check$\n" @@ -714,16 +766,18 @@ GenerateBuilderMembers(io::Printer* printer) const { " instance.getMutable$capitalized_name$Map().put(key, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, "$deprecation$" - "public Builder putAll$capitalized_name$(\n" + "public Builder ${$putAll$capitalized_name$$}$(\n" " java.util.Map<$type_parameters$> values) {\n" " copyOnWrite();\n" " instance.getMutable$capitalized_name$Map().putAll(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 6e3b4a75..8964f632 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -56,8 +56,9 @@ #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/stubs/strutil.h> + namespace google { namespace protobuf { @@ -253,7 +254,7 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { /* immutable = */ true, "OrBuilder"); if (descriptor_->extension_range_count() > 0) { printer->Print( - "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.GeneratedMessage$ver$.\n" " ExtendableMessageOrBuilder<$classname$> {\n", @@ -261,19 +262,19 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), - "idend", "", "ver", GeneratedCodeVersionSuffix()); + "{", "", "}", "", "ver", GeneratedCodeVersionSuffix()); } else { printer->Print( - "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.MessageOrBuilder {\n", "deprecation", descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), - "idend", ""); + "{", "", "}", ""); } - printer->Annotate("classname", "idend", descriptor_); + printer->Annotate("{", "}", descriptor_); printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { @@ -345,6 +346,9 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { "com.google.protobuf.GeneratedMessage$0.Builder<?>", GeneratedCodeVersionSuffix()); } + printer->Print( + "private static final long serialVersionUID = 0L;\n"); + printer->Indent(); // Using builder_type, instead of Builder, prevents the Builder class from // being loaded into PermGen space when the default instance is created. @@ -367,22 +371,19 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { "}\n" "\n"); + printer->Print( "@java.lang.Override\n" "public final com.google.protobuf.UnknownFieldSet\n" - "getUnknownFields() {\n"); - if (PreserveUnknownFields(descriptor_)) { - printer->Print( - " return this.unknownFields;\n"); - } else { - printer->Print( - " return com.google.protobuf.UnknownFieldSet.getDefaultInstance();\n"); - } - printer->Print( + "getUnknownFields() {\n" + " return this.unknownFields;\n" "}\n"); if (context_->HasGeneratedMethods(descriptor_)) { - GenerateParsingConstructor(printer); + if (!EnableExperimentalRuntime(context_) || + IsDescriptorProto(descriptor_)) { + GenerateParsingConstructor(printer); + } } GenerateDescriptorMethods(printer); @@ -436,11 +437,10 @@ void ImmutableMessageGenerator::Generate(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( - "$field_name$($field_number$),\n", - "field_name", - ToUpper(field->name()), - "field_number", - SimpleItoa(field->number())); + "$deprecation$$field_name$($field_number$),\n", + "deprecation", field->options().deprecated() ? "@java.lang.Deprecated " : "", + "field_name", ToUpper(field->name()), + "field_number", SimpleItoa(field->number())); } printer->Print( "$cap_oneof_name$_NOT_SET(0);\n", @@ -540,9 +540,21 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); + // 'of' method for Wrappers + if (IsWrappersProtoFile(descriptor_->file())) { + printer->Print( + "public static $classname$ of($field_type$ value) {\n" + " return newBuilder().setValue(value).build();\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0)))); + } + GenerateParser(printer); printer->Print( + "@java.lang.Override\n" "public $classname$ getDefaultInstanceForType() {\n" " return DEFAULT_INSTANCE;\n" "}\n" @@ -576,107 +588,110 @@ GenerateMessageSerializationMethods(io::Printer* printer) { std::sort(sorted_extensions.begin(), sorted_extensions.end(), ExtensionRangeOrdering()); printer->Print( + "@java.lang.Override\n" "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" " throws java.io.IOException {\n"); printer->Indent(); - 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$ver$\n" - " .ExtendableMessage<$classname$>.ExtensionWriter\n" - " extensionWriter = newMessageSetExtensionWriter();\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_), - "ver", GeneratedCodeVersionSuffix()); - } else { - printer->Print( - "com.google.protobuf.GeneratedMessage$ver$\n" - " .ExtendableMessage<$classname$>.ExtensionWriter\n" - " extensionWriter = newExtensionWriter();\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_), - "ver", GeneratedCodeVersionSuffix()); + if (EnableExperimentalRuntime(context_) && !IsDescriptorProto(descriptor_)) { + printer->Print("writeToInternal(output);\n"); + } else { + 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"); } - } - // Merge the fields and the extension ranges, both sorted by field number. - for (int i = 0, j = 0; - i < descriptor_->field_count() || j < sorted_extensions.size(); - ) { - if (i == descriptor_->field_count()) { - GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); - } else if (j == sorted_extensions.size()) { - GenerateSerializeOneField(printer, sorted_fields[i++]); - } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) { - GenerateSerializeOneField(printer, sorted_fields[i++]); - } else { - GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); + if (descriptor_->extension_range_count() > 0) { + if (descriptor_->options().message_set_wire_format()) { + printer->Print( + "com.google.protobuf.GeneratedMessage$ver$\n" + " .ExtendableMessage<$classname$>.ExtensionWriter\n" + " extensionWriter = newMessageSetExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "ver", GeneratedCodeVersionSuffix()); + } else { + printer->Print( + "com.google.protobuf.GeneratedMessage$ver$\n" + " .ExtendableMessage<$classname$>.ExtensionWriter\n" + " extensionWriter = newExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "ver", GeneratedCodeVersionSuffix()); + } + } + + // Merge the fields and the extension ranges, both sorted by field number. + for (int i = 0, j = 0; + i < descriptor_->field_count() || j < sorted_extensions.size();) { + if (i == descriptor_->field_count()) { + GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); + } else if (j == sorted_extensions.size()) { + GenerateSerializeOneField(printer, sorted_fields[i++]); + } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) { + GenerateSerializeOneField(printer, sorted_fields[i++]); + } else { + GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); + } } - } - if (PreserveUnknownFields(descriptor_)) { if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "unknownFields.writeAsMessageSetTo(output);\n"); + printer->Print("unknownFields.writeAsMessageSetTo(output);\n"); } else { - printer->Print( - "unknownFields.writeTo(output);\n"); + printer->Print("unknownFields.writeTo(output);\n"); } } printer->Outdent(); printer->Print( - "}\n" - "\n" - "public int getSerializedSize() {\n" - " int size = memoizedSize;\n" - " if (size != -1) return size;\n" - "\n" - " size = 0;\n"); + "}\n" + "\n" + "@java.lang.Override\n" + "public int getSerializedSize() {\n" + " int size = memoizedSize;\n" + " if (size != -1) return size;\n" + "\n"); printer->Indent(); + if (EnableExperimentalRuntime(context_) && !IsDescriptorProto(descriptor_)) { + printer->Print( + "memoizedSize = getSerializedSizeInternal();\n" + "return memoizedSize;\n"); + } else { - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); - } + printer->Print("size = 0;\n"); - if (descriptor_->extension_range_count() > 0) { - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "size += extensionsSerializedSizeAsMessageSet();\n"); - } else { - printer->Print( - "size += extensionsSerializedSize();\n"); + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(sorted_fields[i]) + .GenerateSerializedSizeCode(printer); + } + + if (descriptor_->extension_range_count() > 0) { + if (descriptor_->options().message_set_wire_format()) { + printer->Print("size += extensionsSerializedSizeAsMessageSet();\n"); + } else { + printer->Print("size += extensionsSerializedSize();\n"); + } } - } - if (PreserveUnknownFields(descriptor_)) { if (descriptor_->options().message_set_wire_format()) { printer->Print( - "size += unknownFields.getSerializedSizeAsMessageSet();\n"); + "size += unknownFields.getSerializedSizeAsMessageSet();\n"); } else { - printer->Print( - "size += unknownFields.getSerializedSize();\n"); + printer->Print("size += unknownFields.getSerializedSize();\n"); } + + printer->Print( + "memoizedSize = size;\n" + "return size;\n"); } printer->Outdent(); printer->Print( - " memoizedSize = size;\n" - " return size;\n" "}\n" "\n"); - - printer->Print( - "private static final long serialVersionUID = 0L;\n"); } void ImmutableMessageGenerator:: @@ -776,6 +791,7 @@ void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange( void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) { // LITE_RUNTIME implements this at the GeneratedMessageLite level. printer->Print( + "@java.lang.Override\n" "public Builder newBuilderForType() { return newBuilder(); }\n"); printer->Print( @@ -785,6 +801,7 @@ void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) { "public static Builder newBuilder($classname$ prototype) {\n" " return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n" "}\n" + "@java.lang.Override\n" "public Builder toBuilder() {\n" " return this == DEFAULT_INSTANCE\n" " ? new Builder() : new Builder().mergeFrom(this);\n" @@ -828,6 +845,7 @@ GenerateDescriptorMethods(io::Printer* printer) { if (!map_fields.empty()) { printer->Print( "@SuppressWarnings({\"rawtypes\"})\n" + "@java.lang.Override\n" "protected com.google.protobuf.MapField internalGetMapField(\n" " int number) {\n" " switch (number) {\n"); @@ -853,6 +871,7 @@ GenerateDescriptorMethods(io::Printer* printer) { "}\n"); } printer->Print( + "@java.lang.Override\n" "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n" " internalGetFieldAccessorTable() {\n" " return $fileclass$.internal_$identifier$_fieldAccessorTable\n" @@ -876,6 +895,7 @@ void ImmutableMessageGenerator::GenerateIsInitialized( printer->Print( "private byte memoizedIsInitialized = -1;\n"); printer->Print( + "@java.lang.Override\n" "public final boolean isInitialized() {\n"); printer->Indent(); @@ -1078,13 +1098,11 @@ GenerateEqualsAndHashCode(io::Printer* printer) { printer->Print("}\n"); } - if (PreserveUnknownFields(descriptor_)) { - // Always consider unknown fields for equality. This will sometimes return - // false for non-canonical ordering when running in LITE_RUNTIME but it's - // the best we can do. - printer->Print( + // Always consider unknown fields for equality. This will sometimes return + // false for non-canonical ordering when running in LITE_RUNTIME but it's + // the best we can do. + printer->Print( "result = result && unknownFields.equals(other.unknownFields);\n"); - } if (descriptor_->extension_range_count() > 0) { printer->Print( "result = result &&\n" @@ -1211,7 +1229,10 @@ GenerateParsingConstructor(io::Printer* printer) { // Initialize all fields to default. printer->Print( - "this();\n"); + "this();\n" + "if (extensionRegistry == null) {\n" + " throw new java.lang.NullPointerException();\n" + "}\n"); // Use builder bits to track mutable repeated fields. int totalBuilderBits = 0; @@ -1226,11 +1247,9 @@ GenerateParsingConstructor(io::Printer* printer) { "bit_field_name", GetBitFieldName(i)); } - if (PreserveUnknownFields(descriptor_)) { - printer->Print( + printer->Print( "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n" " com.google.protobuf.UnknownFieldSet.newBuilder();\n"); - } printer->Print( "try {\n"); @@ -1247,28 +1266,9 @@ GenerateParsingConstructor(io::Printer* printer) { printer->Indent(); printer->Print( - "case 0:\n" // zero signals EOF / limit reached - " done = true;\n" - " break;\n"); - - if (PreserveUnknownFields(descriptor_)) { - printer->Print( - "default: {\n" - " if (!parseUnknownField(input, unknownFields,\n" - " extensionRegistry, tag)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - } else { - printer->Print( - "default: {\n" - " if (!input.skipField(tag)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - } + "case 0:\n" // zero signals EOF / limit reached + " done = true;\n" + " break;\n"); for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = sorted_fields[i]; @@ -1306,6 +1306,18 @@ GenerateParsingConstructor(io::Printer* printer) { } } + printer->Print( + "default: {\n" + " if (!parseUnknownField$suffix$(\n" + " input, unknownFields, extensionRegistry, tag)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n", + "suffix", + descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ? "Proto3" + : ""); + printer->Outdent(); printer->Outdent(); printer->Print( @@ -1328,10 +1340,8 @@ GenerateParsingConstructor(io::Printer* printer) { field_generators_.get(field).GenerateParsingDoneCode(printer); } - if (PreserveUnknownFields(descriptor_)) { - // Make unknown fields immutable. - printer->Print("this.unknownFields = unknownFields.build();\n"); - } + // Make unknown fields immutable. + printer->Print("this.unknownFields = unknownFields.build();\n"); // Make extensions immutable. printer->Print( @@ -1355,15 +1365,24 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { "classname", descriptor_->name()); printer->Indent(); printer->Print( + "@java.lang.Override\n" "public $classname$ parsePartialFrom(\n" " com.google.protobuf.CodedInputStream input,\n" " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" " throws com.google.protobuf.InvalidProtocolBufferException {\n", "classname", descriptor_->name()); - if (context_->HasGeneratedMethods(descriptor_)) { + if (EnableExperimentalRuntime(context_) && !IsDescriptorProto(descriptor_)) { + printer->Indent(); printer->Print( - " return new $classname$(input, extensionRegistry);\n", + "$classname$ msg = new $classname$();\n" + "msg.mergeFromInternal(input, extensionRegistry);\n" + "msg.makeImmutableInternal();\n" + "return msg;\n", "classname", descriptor_->name()); + printer->Outdent(); + } else if (context_->HasGeneratedMethods(descriptor_)) { + printer->Print(" return new $classname$(input, extensionRegistry);\n", + "classname", descriptor_->name()); } else { // When parsing constructor isn't generated, use builder to parse // messages. Note, will fallback to use reflection based mergeFieldFrom() diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc index f5643abc..43c39b4a 100644 --- a/src/google/protobuf/compiler/java/java_message_builder.cc +++ b/src/google/protobuf/compiler/java/java_message_builder.cc @@ -54,8 +54,9 @@ #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/stubs/strutil.h> + namespace google { namespace protobuf { @@ -171,36 +172,27 @@ Generate(io::Printer* printer) { .GenerateBuilderMembers(printer); } - if (!PreserveUnknownFields(descriptor_)) { - printer->Print( - "public final Builder setUnknownFields(\n" - " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" - " return this;\n" - "}\n" - "\n" - "public final Builder mergeUnknownFields(\n" - " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" - " return this;\n" - "}\n" - "\n"); - } else { + bool is_proto3 = + descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; // Override methods declared in GeneratedMessage to return the concrete // generated type so callsites won't depend on GeneratedMessage. This // is needed to keep binary compatibility when we change generated code // to subclass a different GeneratedMessage class (e.g., in v3.0.0 release // we changed all generated code to subclass GeneratedMessageV3). - printer->Print( - "public final Builder setUnknownFields(\n" - " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" - " return super.setUnknownFields(unknownFields);\n" - "}\n" - "\n" - "public final Builder mergeUnknownFields(\n" - " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" - " return super.mergeUnknownFields(unknownFields);\n" - "}\n" - "\n"); - } + printer->Print( + "@java.lang.Override\n" + "public final Builder setUnknownFields(\n" + " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" + " return super.setUnknownFields$suffix$(unknownFields);\n" + "}\n" + "\n" + "@java.lang.Override\n" + "public final Builder mergeUnknownFields(\n" + " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" + " return super.mergeUnknownFields(unknownFields);\n" + "}\n" + "\n", + "suffix", is_proto3 ? "Proto3" : ""); printer->Print( "\n" @@ -287,6 +279,7 @@ GenerateDescriptorMethods(io::Printer* printer) { "}\n"); } printer->Print( + "@java.lang.Override\n" "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n" " internalGetFieldAccessorTable() {\n" " return $fileclass$.internal_$identifier$_fieldAccessorTable\n" @@ -343,6 +336,7 @@ GenerateCommonBuilderMethods(io::Printer* printer) { "}\n"); printer->Print( + "@java.lang.Override\n" "public Builder clear() {\n" " super.clear();\n"); @@ -371,6 +365,7 @@ GenerateCommonBuilderMethods(io::Printer* printer) { "\n"); printer->Print( + "@java.lang.Override\n" "public com.google.protobuf.Descriptors.Descriptor\n" " getDescriptorForType() {\n" " return $fileclass$.internal_$identifier$_descriptor;\n" @@ -381,6 +376,7 @@ GenerateCommonBuilderMethods(io::Printer* printer) { // LITE runtime implements this in GeneratedMessageLite. printer->Print( + "@java.lang.Override\n" "public $classname$ getDefaultInstanceForType() {\n" " return $classname$.getDefaultInstance();\n" "}\n" @@ -388,6 +384,7 @@ GenerateCommonBuilderMethods(io::Printer* printer) { "classname", name_resolver_->GetImmutableClassName(descriptor_)); printer->Print( + "@java.lang.Override\n" "public $classname$ build() {\n" " $classname$ result = buildPartial();\n" " if (!result.isInitialized()) {\n" @@ -399,6 +396,7 @@ GenerateCommonBuilderMethods(io::Printer* printer) { "classname", name_resolver_->GetImmutableClassName(descriptor_)); printer->Print( + "@java.lang.Override\n" "public $classname$ buildPartial() {\n" " $classname$ result = new $classname$(this);\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); @@ -467,53 +465,63 @@ GenerateCommonBuilderMethods(io::Printer* printer) { // to subclass a different GeneratedMessage class (e.g., in v3.0.0 release // we changed all generated code to subclass GeneratedMessageV3). printer->Print( + "@java.lang.Override\n" "public Builder clone() {\n" " return (Builder) super.clone();\n" "}\n" + "@java.lang.Override\n" "public Builder setField(\n" " com.google.protobuf.Descriptors.FieldDescriptor field,\n" - " Object value) {\n" + " java.lang.Object value) {\n" " return (Builder) super.setField(field, value);\n" "}\n" + "@java.lang.Override\n" "public Builder clearField(\n" " com.google.protobuf.Descriptors.FieldDescriptor field) {\n" " return (Builder) super.clearField(field);\n" "}\n" + "@java.lang.Override\n" "public Builder clearOneof(\n" " com.google.protobuf.Descriptors.OneofDescriptor oneof) {\n" " return (Builder) super.clearOneof(oneof);\n" "}\n" + "@java.lang.Override\n" "public Builder setRepeatedField(\n" " com.google.protobuf.Descriptors.FieldDescriptor field,\n" - " int index, Object value) {\n" + " int index, java.lang.Object value) {\n" " return (Builder) super.setRepeatedField(field, index, value);\n" "}\n" + "@java.lang.Override\n" "public Builder addRepeatedField(\n" " com.google.protobuf.Descriptors.FieldDescriptor field,\n" - " Object value) {\n" + " java.lang.Object value) {\n" " return (Builder) super.addRepeatedField(field, value);\n" "}\n"); if (descriptor_->extension_range_count() > 0) { printer->Print( + "@java.lang.Override\n" "public <Type> Builder setExtension(\n" " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" " $classname$, Type> extension,\n" " Type value) {\n" " return (Builder) super.setExtension(extension, value);\n" "}\n" + "@java.lang.Override\n" "public <Type> Builder setExtension(\n" " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" " $classname$, java.util.List<Type>> extension,\n" " int index, Type value) {\n" " return (Builder) super.setExtension(extension, index, value);\n" "}\n" + "@java.lang.Override\n" "public <Type> Builder addExtension(\n" " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" " $classname$, java.util.List<Type>> extension,\n" " Type value) {\n" " return (Builder) super.addExtension(extension, value);\n" "}\n" + "@java.lang.Override\n" "public <Type> Builder clearExtension(\n" " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" " $classname$, ?> extension) {\n" @@ -526,6 +534,7 @@ GenerateCommonBuilderMethods(io::Printer* printer) { if (context_->HasGeneratedMethods(descriptor_)) { printer->Print( + "@java.lang.Override\n" "public Builder mergeFrom(com.google.protobuf.Message other) {\n" " if (other instanceof $classname$) {\n" " return mergeFrom(($classname$)other);\n" @@ -594,10 +603,8 @@ GenerateCommonBuilderMethods(io::Printer* printer) { " this.mergeExtensionFields(other);\n"); } - if (PreserveUnknownFields(descriptor_)) { - printer->Print( - " this.mergeUnknownFields(other.unknownFields);\n"); - } + printer->Print( + " this.mergeUnknownFields(other.unknownFields);\n"); printer->Print( " onChanged();\n"); @@ -614,6 +621,7 @@ GenerateCommonBuilderMethods(io::Printer* printer) { void MessageBuilderGenerator:: GenerateBuilderParsingMethods(io::Printer* printer) { printer->Print( + "@java.lang.Override\n" "public Builder mergeFrom(\n" " com.google.protobuf.CodedInputStream input,\n" " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" @@ -639,6 +647,7 @@ GenerateBuilderParsingMethods(io::Printer* printer) { void MessageBuilderGenerator::GenerateIsInitialized( io::Printer* printer) { printer->Print( + "@java.lang.Override\n" "public final boolean isInitialized() {\n"); printer->Indent(); diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc index ae84db1c..baa7f872 100644 --- a/src/google/protobuf/compiler/java/java_message_field.cc +++ b/src/google/protobuf/compiler/java/java_message_field.cc @@ -150,12 +150,9 @@ GenerateInterfaceMembers(io::Printer* printer) const { // interface so that builders can choose dynamically to either return a // message or a nested builder, so that asking for the interface doesn't // cause a message to ever be built. - if (SupportFieldPresence(descriptor_->file()) || - descriptor_->containing_oneof() == NULL) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$boolean has$capitalized_name$();\n"); - } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); @@ -174,39 +171,45 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$OrBuilder " - "get$capitalized_name$OrBuilder() {\n" + "${$get$capitalized_name$OrBuilder$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } else { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $name$_ != null;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public $type$OrBuilder " - "get$capitalized_name$OrBuilder() {\n" + "${$get$capitalized_name$OrBuilder$}$() {\n" " return get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } } @@ -232,6 +235,7 @@ void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction( const char* nested_builder_case, const char* trailing_code) const { printer->Print(variables_, method_prototype); + printer->Annotate("{", "}", descriptor_); printer->Print(" {\n"); printer->Indent(); PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); @@ -267,20 +271,22 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); if (support_field_presence) { printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_builder$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } else { printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $name$Builder_ != null || $name$_ != null;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } // Field getField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public $type$ get$capitalized_name$()", + "$deprecation$public $type$ ${$get$capitalized_name$$}$()", "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n", "return $name$Builder_.getMessage();\n", NULL); @@ -288,7 +294,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$($type$ value)", + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)", "if (value == null) {\n" " throw new NullPointerException();\n" @@ -304,7 +310,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder setField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " $type$.Builder builderForValue)", "$name$_ = builderForValue.build();\n" @@ -318,7 +324,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder merge$capitalized_name$($type$ value)", + "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)", support_field_presence ? "if ($get_has_field_bit_builder$ &&\n" @@ -346,7 +352,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder clearField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder clear$capitalized_name$()", + "$deprecation$public Builder ${$clear$capitalized_name$$}$()", "$name$_ = null;\n" "$on_changed$\n", @@ -361,14 +367,17 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" + "$deprecation$public $type$.Builder " + "${$get$capitalized_name$Builder$}$() {\n" " $set_has_field_bit_builder$\n" " $on_changed$\n" " return get$capitalized_name$FieldBuilder().getBuilder();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" " if ($name$Builder_ != null) {\n" " return $name$Builder_.getMessageOrBuilder();\n" " } else {\n" @@ -376,6 +385,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " $type$.getDefaultInstance() : $name$_;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "private com.google.protobuf.SingleFieldBuilder$ver$<\n" @@ -530,30 +540,32 @@ ImmutableMessageOneofFieldGenerator:: void ImmutableMessageOneofFieldGenerator:: GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $has_oneof_case_message$;\n" - "}\n"); - } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" " }\n" " return $type$.getDefaultInstance();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" " }\n" " return $type$.getDefaultInstance();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableMessageOneofFieldGenerator:: @@ -571,19 +583,18 @@ GenerateBuilderMembers(io::Printer* printer) const { // The comments above the methods below are based on a hypothetical // field of type "Field" called "Field". - if (SupportFieldPresence(descriptor_->file())) { - // boolean hasField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $has_oneof_case_message$;\n" - "}\n"); - } + // boolean hasField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); // Field getField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public $type$ get$capitalized_name$()", + "$deprecation$public $type$ ${$get$capitalized_name$$}$()", "if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" @@ -600,7 +611,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$($type$ value)", + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)", "if (value == null) {\n" " throw new NullPointerException();\n" @@ -616,7 +627,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder setField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " $type$.Builder builderForValue)", "$oneof_name$_ = builderForValue.build();\n" @@ -630,7 +641,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder merge$capitalized_name$($type$ value)", + "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)", "if ($has_oneof_case_message$ &&\n" " $oneof_name$_ != $type$.getDefaultInstance()) {\n" @@ -652,7 +663,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field.Builder clearField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder clear$capitalized_name$()", + "$deprecation$public Builder ${$clear$capitalized_name$$}$()", "if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" @@ -670,12 +681,15 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" + "$deprecation$public $type$.Builder " + "${$get$capitalized_name$Builder$}$() {\n" " return get$capitalized_name$FieldBuilder().getBuilder();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" " if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n" " return $name$Builder_.getMessageOrBuilder();\n" " } else {\n" @@ -685,11 +699,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " return $type$.getDefaultInstance();\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "private com.google.protobuf.SingleFieldBuilder$ver$<\n" " $type$, $type$.Builder, $type$OrBuilder> \n" - " get$capitalized_name$FieldBuilder() {\n" + " ${$get$capitalized_name$FieldBuilder$}$() {\n" " if ($name$Builder_ == null) {\n" " if (!($has_oneof_case_message$)) {\n" " $oneof_name$_ = $type$.getDefaultInstance();\n" @@ -705,6 +720,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$;\n" " return $name$Builder_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableMessageOneofFieldGenerator:: @@ -833,31 +849,38 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" - " get$capitalized_name$OrBuilderList() {\n" + " ${$get$capitalized_name$OrBuilderList$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$(\n" " int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } @@ -883,6 +906,7 @@ void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction( const char* nested_builder_case, const char* trailing_code) const { printer->Print(variables_, method_prototype); + printer->Annotate("{", "}", descriptor_); printer->Print(" {\n"); printer->Indent(); PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); @@ -934,7 +958,8 @@ GenerateBuilderMembers(io::Printer* printer) const { // List<Field> getRepeatedFieldList() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List()", + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$()", "return java.util.Collections.unmodifiableList($name$_);\n", "return $name$Builder_.getMessageList();\n", @@ -944,7 +969,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // int getRepeatedFieldCount() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public int get$capitalized_name$Count()", + "$deprecation$public int ${$get$capitalized_name$Count$}$()", "return $name$_.size();\n", "return $name$Builder_.getCount();\n", @@ -954,7 +979,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Field getRepeatedField(int index) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public $type$ get$capitalized_name$(int index)", + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index)", "return $name$_.get(index);\n", @@ -965,7 +990,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder setRepeatedField(int index, Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value)", "if (value == null) {\n" " throw new NullPointerException();\n" @@ -979,7 +1004,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder setRepeatedField(int index, Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$.Builder builderForValue)", "ensure$capitalized_name$IsMutable();\n" @@ -993,7 +1018,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder addRepeatedField(Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$($type$ value)", + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value)", "if (value == null) {\n" " throw new NullPointerException();\n" @@ -1010,7 +1035,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder addRepeatedField(int index, Field value) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " int index, $type$ value)", "if (value == null) {\n" @@ -1027,7 +1052,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder addRepeatedField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " $type$.Builder builderForValue)", "ensure$capitalized_name$IsMutable();\n" @@ -1041,7 +1066,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder addRepeatedField(int index, Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " int index, $type$.Builder builderForValue)", "ensure$capitalized_name$IsMutable();\n" @@ -1055,7 +1080,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder addAllRepeatedField(Iterable<Field> values) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $type$> values)", "ensure$capitalized_name$IsMutable();\n" @@ -1070,7 +1095,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder clearAllRepeatedField() WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder clear$capitalized_name$()", + "$deprecation$public Builder ${$clear$capitalized_name$$}$()", "$name$_ = java.util.Collections.emptyList();\n" "$clear_mutable_bit_builder$;\n" @@ -1083,7 +1108,7 @@ GenerateBuilderMembers(io::Printer* printer) const { // Builder removeRepeatedField(int index) WriteFieldDocComment(printer, descriptor_); PrintNestedBuilderFunction(printer, - "$deprecation$public Builder remove$capitalized_name$(int index)", + "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)", "ensure$capitalized_name$IsMutable();\n" "$name$_.remove(index);\n" @@ -1095,14 +1120,16 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n" + "$deprecation$public $type$.Builder ${$get$capitalized_name$Builder$}$(\n" " int index) {\n" " return get$capitalized_name$FieldBuilder().getBuilder(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$(\n" " int index) {\n" " if ($name$Builder_ == null) {\n" " return $name$_.get(index);" @@ -1110,35 +1137,40 @@ GenerateBuilderMembers(io::Printer* printer) const { " return $name$Builder_.getMessageOrBuilder(index);\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" - " get$capitalized_name$OrBuilderList() {\n" + " ${$get$capitalized_name$OrBuilderList$}$() {\n" " if ($name$Builder_ != null) {\n" " return $name$Builder_.getMessageOrBuilderList();\n" " } else {\n" " return java.util.Collections.unmodifiableList($name$_);\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n" + "$deprecation$public $type$.Builder " + "${$add$capitalized_name$Builder$}$() {\n" " return get$capitalized_name$FieldBuilder().addBuilder(\n" " $type$.getDefaultInstance());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n" + "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n" " int index) {\n" " return get$capitalized_name$FieldBuilder().addBuilder(\n" " index, $type$.getDefaultInstance());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$type$.Builder> \n" - " get$capitalized_name$BuilderList() {\n" + " ${$get$capitalized_name$BuilderList$}$() {\n" " return get$capitalized_name$FieldBuilder().getBuilderList();\n" "}\n" "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n" @@ -1155,6 +1187,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return $name$Builder_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutableMessageFieldGenerator:: diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.cc b/src/google/protobuf/compiler/java/java_message_field_lite.cc index c71e9101..df3e80d4 100644 --- a/src/google/protobuf/compiler/java/java_message_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc @@ -129,16 +129,9 @@ int ImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const { void ImmutableMessageFieldLiteGenerator:: GenerateInterfaceMembers(io::Printer* printer) const { - // TODO(jonp): In the future, consider having a method specific to the - // interface so that builders can choose dynamically to either return a - // message or a nested builder, so that asking for the interface doesn't - // cause a message to ever be built. - if (SupportFieldPresence(descriptor_->file()) || - descriptor_->containing_oneof() == NULL) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$boolean has$capitalized_name$();\n"); - } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); @@ -154,25 +147,29 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } else { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $name$_ != null;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } // Field.Builder setField(Field value) @@ -226,53 +223,60 @@ GenerateBuilderMembers(io::Printer* printer) const { // boolean hasField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field getField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" " }\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder setField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " $type$.Builder builderForValue) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(builderForValue);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder " + "${$merge$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.merge$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder clearField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableMessageFieldLiteGenerator:: @@ -390,21 +394,21 @@ ImmutableMessageOneofFieldLiteGenerator:: void ImmutableMessageOneofFieldLiteGenerator:: GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $has_oneof_case_message$;\n" - "}\n"); - } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" " }\n" " return $type$.getDefaultInstance();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_); @@ -457,58 +461,63 @@ GenerateBuilderMembers(io::Printer* printer) const { // The comments above the methods below are based on a hypothetical // field of type "Field" called "Field". - if (SupportFieldPresence(descriptor_->file())) { - // boolean hasField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return instance.has$capitalized_name$();\n" - "}\n"); - } + // boolean hasField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); // Field getField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder setField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " $type$.Builder builderForValue) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(builderForValue);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder " + "${$merge$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.merge$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Field.Builder clearField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableMessageOneofFieldLiteGenerator:: @@ -615,31 +624,38 @@ GenerateMembers(io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" - " get$capitalized_name$OrBuilderList() {\n" + " ${$get$capitalized_name$OrBuilderList$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$(\n" " int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); printer->Print(variables_, "private void ensure$capitalized_name$IsMutable() {\n" @@ -745,110 +761,123 @@ GenerateBuilderMembers(io::Printer* printer) const { // List<Field> getRepeatedFieldList() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList(\n" " instance.get$capitalized_name$List());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // int getRepeatedFieldCount() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}"); + printer->Annotate("{", "}", descriptor_); // Field getRepeatedField(int index) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder setRepeatedField(int index, Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder setRepeatedField(int index, Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$.Builder builderForValue) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(index, builderForValue);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder addRepeatedField(Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder addRepeatedField(int index, Field value) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder addRepeatedField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " $type$.Builder builderForValue) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(builderForValue);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder addRepeatedField(int index, Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " int index, $type$.Builder builderForValue) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(index, builderForValue);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder addAllRepeatedField(Iterable<Field> values) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $type$> values) {\n" " copyOnWrite();\n" " instance.addAll$capitalized_name$(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder clearAllRepeatedField() WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); // Builder removeRepeatedField(int index) WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder remove$capitalized_name$(int index) {\n" + "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index) {\n" " copyOnWrite();\n" " instance.remove$capitalized_name$(index);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutableMessageFieldLiteGenerator:: diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index 5007ecee..108504c7 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -56,8 +56,9 @@ #include <google/protobuf/io/printer.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/stubs/strutil.h> + namespace google { namespace protobuf { @@ -68,6 +69,14 @@ using internal::WireFormat; using internal::WireFormatLite; namespace { +bool EnableExperimentalRuntimeForLite() { +#ifdef PROTOBUF_EXPERIMENT + return PROTOBUF_EXPERIMENT; +#else // PROTOBUF_EXPERIMENT + return false; +#endif // !PROTOBUF_EXPERIMENT +} + bool GenerateHasBits(const Descriptor* descriptor) { return SupportFieldPresence(descriptor->file()) || HasRepeatedFields(descriptor); @@ -124,7 +133,7 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { /* immutable = */ true, "OrBuilder"); if (descriptor_->extension_range_count() > 0) { printer->Print( - "$deprecation$public interface $classname$OrBuilder$idend$ extends \n" + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends \n" " $extra_interfaces$\n" " com.google.protobuf.GeneratedMessageLite.\n" " ExtendableMessageOrBuilder<\n" @@ -133,19 +142,19 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), - "idend", ""); + "{", "", "}", ""); } else { printer->Print( - "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.MessageLiteOrBuilder {\n", "deprecation", descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), - "idend", ""); + "{", "", "}", ""); } - printer->Annotate("classname", "idend", descriptor_); + printer->Annotate("{", "}", descriptor_); printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { @@ -331,41 +340,43 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { printer->Print("\n"); } - GenerateMessageSerializationMethods(printer); + if (!EnableExperimentalRuntime(context_)) { + GenerateMessageSerializationMethods(printer); + } GenerateParseFromMethods(printer); GenerateBuilder(printer); if (HasRequiredFields(descriptor_)) { // Memoizes whether the protocol buffer is fully initialized (has all - // required fields). -1 means not yet computed. 0 means false and 1 means - // true. + // required fields). 0 means false, 1 means true, and all other values + // mean not yet computed. printer->Print( - "private byte memoizedIsInitialized = -1;\n"); + "private byte memoizedIsInitialized = 2;\n"); } printer->Print( - "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n" - "protected final Object dynamicMethod(\n" - " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" - " Object arg0, Object arg1) {\n" - " switch (method) {\n" - " case NEW_MUTABLE_INSTANCE: {\n" - " return new $classname$();\n" - " }\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n" + "protected final java.lang.Object dynamicMethod(\n" + " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" + " java.lang.Object arg0, java.lang.Object arg1) {\n" + " switch (method) {\n" + " case NEW_MUTABLE_INSTANCE: {\n" + " return new $classname$();\n" + " }\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); printer->Indent(); printer->Indent(); - printer->Print( - "case IS_INITIALIZED: {\n"); + printer->Print("case IS_INITIALIZED: {\n"); printer->Indent(); GenerateDynamicMethodIsInitialized(printer); printer->Outdent(); + printer->Print("}\n"); + printer->Print( - "}\n" "case MAKE_IMMUTABLE: {\n"); printer->Indent(); @@ -380,13 +391,15 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { GenerateDynamicMethodNewBuilder(printer); printer->Outdent(); - printer->Print( - "}\n" - "case VISIT: {\n"); + if (!EnableExperimentalRuntimeForLite()) { + printer->Print( + "}\n" + "case VISIT: {\n"); - printer->Indent(); - GenerateDynamicMethodVisit(printer); - printer->Outdent(); + printer->Indent(); + GenerateDynamicMethodVisit(printer); + printer->Outdent(); + } printer->Print( "}\n" @@ -414,13 +427,33 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { " }\n" " }\n" " }\n" - " return PARSER;\n" - "}\n", + " return PARSER;\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); printer->Outdent(); - printer->Outdent(); + if (HasRequiredFields(descriptor_)) { + printer->Print( + "}\n" + "case GET_MEMOIZED_IS_INITIALIZED: {\n" + " return memoizedIsInitialized;\n" + "}\n" + "case SET_MEMOIZED_IS_INITIALIZED: {\n" + " memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);\n" + " return null;\n" + "}\n"); + } else { + printer->Print( + "}\n" + "case GET_MEMOIZED_IS_INITIALIZED: {\n" + " return (byte) 1;\n" + "}\n" + "case SET_MEMOIZED_IS_INITIALIZED: {\n" + " return null;\n" + "}\n"); + } + + printer->Outdent(); printer->Print( " }\n" " throw new UnsupportedOperationException();\n" @@ -447,6 +480,17 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { "}\n" "\n", "classname", descriptor_->name()); + if (EnableExperimentalRuntimeForLite()) { + // Register the default instance in a map. This map will be used by + // experimental runtime to lookup default instance given a class instance + // without using Java reflection. + printer->Print( + "static {\n" + " com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(\n" + " $classname$.class, DEFAULT_INSTANCE);\n" + "}\n", + "classname", descriptor_->name()); + } printer->Print( "public static $classname$ getDefaultInstance() {\n" " return DEFAULT_INSTANCE;\n" @@ -454,6 +498,17 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); + // 'of' method for Wrappers + if (IsWrappersProtoFile(descriptor_->file())) { + printer->Print( + "public static $classname$ of($field_type$ value) {\n" + " return newBuilder().setValue(value).build();\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0)))); + } + GenerateParser(printer); // Extensions must be declared after the DEFAULT_INSTANCE is initialized @@ -468,6 +523,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { printer->Print("}\n\n"); } + // =================================================================== void ImmutableMessageLiteGenerator:: @@ -489,36 +545,34 @@ GenerateMessageSerializationMethods(io::Printer* printer) { 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"); + // 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.GeneratedMessageLite\n" - " .ExtendableMessage<$classname$, $classname$.Builder>\n" - " .ExtensionWriter extensionWriter =\n" - " newMessageSetExtensionWriter();\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + "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.GeneratedMessageLite\n" - " .ExtendableMessage<$classname$, $classname$.Builder>\n" - " .ExtensionWriter extensionWriter =\n" - " newExtensionWriter();\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + "com.google.protobuf.GeneratedMessageLite\n" + " .ExtendableMessage<$classname$, $classname$.Builder>\n" + " .ExtensionWriter extensionWriter =\n" + " newExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); } } // Merge the fields and the extension ranges, both sorted by field number. for (int i = 0, j = 0; - i < descriptor_->field_count() || j < sorted_extensions.size(); - ) { + i < descriptor_->field_count() || j < sorted_extensions.size();) { if (i == descriptor_->field_count()) { GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); } else if (j == sorted_extensions.size()) { @@ -530,26 +584,23 @@ GenerateMessageSerializationMethods(io::Printer* printer) { } } - if (PreserveUnknownFields(descriptor_)) { - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "unknownFields.writeAsMessageSetTo(output);\n"); - } else { - printer->Print( - "unknownFields.writeTo(output);\n"); - } + if (descriptor_->options().message_set_wire_format()) { + printer->Print("unknownFields.writeAsMessageSetTo(output);\n"); + } else { + printer->Print("unknownFields.writeTo(output);\n"); } printer->Outdent(); printer->Print( - "}\n" - "\n" - "public int getSerializedSize() {\n" - " int size = memoizedSerializedSize;\n" - " if (size != -1) return size;\n" - "\n" - " size = 0;\n"); + "}\n" + "\n" + "public int getSerializedSize() {\n" + " int size = memoizedSerializedSize;\n" + " if (size != -1) return size;\n" + "\n"); printer->Indent(); + printer->Print( + "size = 0;\n"); for (int i = 0; i < descriptor_->field_count(); i++) { field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); @@ -557,28 +608,24 @@ GenerateMessageSerializationMethods(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "size += extensionsSerializedSizeAsMessageSet();\n"); + printer->Print("size += extensionsSerializedSizeAsMessageSet();\n"); } else { - printer->Print( - "size += extensionsSerializedSize();\n"); + printer->Print("size += extensionsSerializedSize();\n"); } } - if (PreserveUnknownFields(descriptor_)) { - if (descriptor_->options().message_set_wire_format()) { - printer->Print( - "size += unknownFields.getSerializedSizeAsMessageSet();\n"); - } else { - printer->Print( - "size += unknownFields.getSerializedSize();\n"); - } + if (descriptor_->options().message_set_wire_format()) { + printer->Print("size += unknownFields.getSerializedSizeAsMessageSet();\n"); + } else { + printer->Print("size += unknownFields.getSerializedSize();\n"); } + printer->Print( + "memoizedSerializedSize = size;\n" + "return size;\n"); + printer->Outdent(); printer->Print( - " memoizedSerializedSize = size;\n" - " return size;\n" "}\n" "\n"); } @@ -683,10 +730,10 @@ void ImmutableMessageLiteGenerator::GenerateSerializeOneExtensionRange( void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) { printer->Print( "public static Builder newBuilder() {\n" - " return DEFAULT_INSTANCE.toBuilder();\n" + " return (Builder) DEFAULT_INSTANCE.createBuilder();\n" "}\n" "public static Builder newBuilder($classname$ prototype) {\n" - " return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n" + " return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);\n" "}\n" "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); @@ -705,7 +752,10 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized( return; } - // Don't directly compare to -1 to avoid an Android x86 JIT bug. + // TODO(xiaofeng): Remove this when b/64445758 is fixed. We don't need to + // check memoizedIsInitialized here because the caller does that already, + // but right now proguard proto shrinker asserts on the bytecode layout of + // this code so it can't be removed until proguard is updated. printer->Print( "byte isInitialized = memoizedIsInitialized;\n" "if (isInitialized == 1) return DEFAULT_INSTANCE;\n" @@ -723,9 +773,6 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized( if (field->is_required()) { printer->Print( "if (!has$name$()) {\n" - " if (shouldMemoize) {\n" - " memoizedIsInitialized = 0;\n" - " }\n" " return null;\n" "}\n", "name", info->capitalized_name); @@ -742,9 +789,6 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized( case FieldDescriptor::LABEL_REQUIRED: printer->Print( "if (!get$name$().isInitialized()) {\n" - " if (shouldMemoize) {\n" - " memoizedIsInitialized = 0;\n" - " }\n" " return null;\n" "}\n", "type", name_resolver_->GetImmutableClassName( @@ -768,9 +812,6 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized( } printer->Print( " if (!get$name$().isInitialized()) {\n" - " if (shouldMemoize) {\n" - " memoizedIsInitialized = 0;\n" - " }\n" " return null;\n" " }\n" "}\n", @@ -781,9 +822,6 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized( printer->Print( "for ($type$ item : get$name$Map().values()) {\n" " if (!item.isInitialized()) {\n" - " if (shouldMemoize) {\n" - " memoizedIsInitialized = 0;\n" - " }\n" " return null;\n" " }\n" "}\n", @@ -794,9 +832,6 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized( printer->Print( "for (int i = 0; i < get$name$Count(); i++) {\n" " if (!get$name$(i).isInitialized()) {\n" - " if (shouldMemoize) {\n" - " memoizedIsInitialized = 0;\n" - " }\n" " return null;\n" " }\n" "}\n", @@ -812,17 +847,11 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized( if (descriptor_->extension_range_count() > 0) { printer->Print( "if (!extensionsAreInitialized()) {\n" - " if (shouldMemoize) {\n" - " memoizedIsInitialized = 0;\n" - " }\n" " return null;\n" "}\n"); } printer->Print( - "if (shouldMemoize) memoizedIsInitialized = 1;\n"); - - printer->Print( "return DEFAULT_INSTANCE;\n" "\n"); } @@ -949,26 +978,70 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFromStream( "com.google.protobuf.CodedInputStream input =\n" " (com.google.protobuf.CodedInputStream) arg0;\n" "com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n" - " (com.google.protobuf.ExtensionRegistryLite) arg1;\n"); + " (com.google.protobuf.ExtensionRegistryLite) arg1;\n" + "if (extensionRegistry == null) {\n" + " throw new java.lang.NullPointerException();\n" + "}\n"); printer->Print( "try {\n"); printer->Indent(); - printer->Print( - "boolean done = false;\n" - "while (!done) {\n"); - printer->Indent(); + if (EnableExperimentalRuntime(context_)) { + printer->Print( + "mergeFromInternal(input, extensionRegistry);\n" + "return DEFAULT_INSTANCE;\n"); + } else { + printer->Print( + "boolean done = false;\n" + "while (!done) {\n"); + printer->Indent(); - printer->Print( - "int tag = input.readTag();\n" - "switch (tag) {\n"); - printer->Indent(); + printer->Print( + "int tag = input.readTag();\n" + "switch (tag) {\n"); + printer->Indent(); - printer->Print( - "case 0:\n" // zero signals EOF / limit reached - " done = true;\n" - " break;\n"); + printer->Print( + "case 0:\n" // zero signals EOF / limit reached + " done = true;\n" + " break;\n"); + + google::protobuf::scoped_array<const FieldDescriptor* > sorted_fields( + SortFieldsByNumber(descriptor_)); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = sorted_fields[i]; + uint32 tag = WireFormatLite::MakeTag( + field->number(), WireFormat::WireTypeForFieldType(field->type())); + + printer->Print("case $tag$: {\n", "tag", + SimpleItoa(static_cast<int32>(tag))); + printer->Indent(); + + field_generators_.get(field).GenerateParsingCode(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "}\n"); + + if (field->is_packable()) { + // To make packed = true wire compatible, we generate parsing code from + // a packed version of this field regardless of + // field->options().packed(). + uint32 packed_tag = WireFormatLite::MakeTag( + field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + printer->Print("case $tag$: {\n", "tag", + SimpleItoa(static_cast<int32>(packed_tag))); + printer->Indent(); + + field_generators_.get(field).GenerateParsingCodeFromPacked(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "}\n"); + } + } - if (PreserveUnknownFields(descriptor_)) { if (descriptor_->extension_range_count() > 0) { if (descriptor_->options().message_set_wire_format()) { printer->Print( @@ -992,68 +1065,22 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFromStream( } } else { printer->Print( - "default: {\n" - " if (!parseUnknownField(tag, input)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); + "default: {\n" + " if (!parseUnknownField(tag, input)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n"); } - } else { - printer->Print( - "default: {\n" - " if (!input.skipField(tag)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - } - - google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields( - SortFieldsByNumber(descriptor_)); - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = sorted_fields[i]; - uint32 tag = WireFormatLite::MakeTag(field->number(), - WireFormat::WireTypeForFieldType(field->type())); - - printer->Print( - "case $tag$: {\n", - "tag", SimpleItoa(static_cast<int32>(tag))); - printer->Indent(); - - field_generators_.get(field).GenerateParsingCode(printer); printer->Outdent(); + printer->Outdent(); printer->Print( - " break;\n" - "}\n"); - - if (field->is_packable()) { - // To make packed = true wire compatible, we generate parsing code from a - // packed version of this field regardless of field->options().packed(). - uint32 packed_tag = WireFormatLite::MakeTag(field->number(), - WireFormatLite::WIRETYPE_LENGTH_DELIMITED); - printer->Print( - "case $tag$: {\n", - "tag", SimpleItoa(static_cast<int32>(packed_tag))); - printer->Indent(); - - field_generators_.get(field).GenerateParsingCodeFromPacked(printer); - - printer->Outdent(); - printer->Print( - " break;\n" - "}\n"); - } + " }\n" // switch (tag) + "}\n"); // while (!done) } printer->Outdent(); - printer->Outdent(); - printer->Print( - " }\n" // switch (tag) - "}\n"); // while (!done) - - printer->Outdent(); printer->Print( "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" " throw new RuntimeException(e.setUnfinishedMessage(this));\n" diff --git a/src/google/protobuf/compiler/java/java_name_resolver.cc b/src/google/protobuf/compiler/java/java_name_resolver.cc index bffe4f16..1673b4ee 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.cc +++ b/src/google/protobuf/compiler/java/java_name_resolver.cc @@ -33,6 +33,7 @@ #include <map> #include <string> + #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/stubs/substitute.h> diff --git a/src/google/protobuf/compiler/java/java_options.h b/src/google/protobuf/compiler/java/java_options.h index 7bce1447..e4e7d5e2 100644 --- a/src/google/protobuf/compiler/java/java_options.h +++ b/src/google/protobuf/compiler/java/java_options.h @@ -59,10 +59,10 @@ struct Options { bool annotate_code; // Name of a file where we will write a list of generated .meta file names, // one per line. - string annotation_list_file; + std::string annotation_list_file; // Name of a file where we will write a list of generated file names, one // per line. - string output_list_file; + std::string output_list_file; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index 840252e7..074a6be8 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -190,16 +190,18 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutablePrimitiveFieldGenerator:: @@ -210,31 +212,35 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_builder$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" "$null_check$" " $set_has_field_bit_builder$\n" " $name$_ = value;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $clear_has_field_bit_builder$\n"); + printer->Annotate("{", "}", descriptor_); JavaType type = GetJavaType(descriptor_); if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) { // The default value is not a simple literal so we want to avoid executing @@ -441,19 +447,21 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($boxed_type$) $oneof_name$_;\n" " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } @@ -462,33 +470,36 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($boxed_type$) $oneof_name$_;\n" " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" "$null_check$" " $set_oneof_case_message$;\n" " $oneof_name$_ = value;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" " $oneof_name$_ = null;\n" @@ -496,6 +507,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutablePrimitiveOneofFieldGenerator:: @@ -604,19 +616,22 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$boxed_type$>\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); if (descriptor_->is_packed() && context_->HasGeneratedMethods(descriptor_->containing_type())) { @@ -654,22 +669,25 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$boxed_type$>\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList($name$_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" "$null_check$" " ensure$capitalized_name$IsMutable();\n" @@ -677,18 +695,20 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n" "$null_check$" " ensure$capitalized_name$IsMutable();\n" " $name$_.add(value);\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $boxed_type$> values) {\n" " ensure$capitalized_name$IsMutable();\n" " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" @@ -696,14 +716,16 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $name$_ = $empty_list$;\n" " $clear_mutable_bit_builder$;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutablePrimitiveFieldGenerator:: diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc index 0e8e492f..f9293171 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc @@ -222,16 +222,18 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -264,32 +266,36 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutablePrimitiveFieldLiteGenerator:: @@ -482,19 +488,21 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($boxed_type$) $oneof_name$_;\n" " }\n" " return $default$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -520,32 +528,36 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutablePrimitiveOneofFieldLiteGenerator:: @@ -634,21 +646,24 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$boxed_type$>\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $repeated_get$(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); - if (descriptor_->options().packed() && + if (descriptor_->is_packed() && context_->HasGeneratedMethods(descriptor_->containing_type())) { printer->Print(variables_, "private int $name$MemoizedSerializedSize = -1;\n"); @@ -697,50 +712,57 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public java.util.List<$boxed_type$>\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList(\n" " instance.get$capitalized_name$List());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<? extends $boxed_type$> values) {\n" " copyOnWrite();\n" " instance.addAll$capitalized_name$(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutablePrimitiveFieldLiteGenerator:: @@ -829,7 +851,7 @@ GenerateParsingDoneCode(io::Printer* printer) const { void RepeatedImmutablePrimitiveFieldLiteGenerator:: GenerateSerializationCode(io::Printer* printer) const { - if (descriptor_->options().packed()) { + if (descriptor_->is_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. @@ -870,7 +892,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print( "size += dataSize;\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (!get$capitalized_name$List().isEmpty()) {\n" " size += $tag_size$;\n" @@ -883,7 +905,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } // cache the data size for packed fields. - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\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 7bd5ad7a..9a42aba9 100644 --- a/src/google/protobuf/compiler/java/java_shared_code_generator.cc +++ b/src/google/protobuf/compiler/java/java_shared_code_generator.cc @@ -140,13 +140,16 @@ void SharedCodeGenerator::GenerateDescriptors(io::Printer* printer) { "java.lang.String[] descriptorData = {\n"); printer->Indent(); - // Only write 40 bytes per line. + // Limit the number of bytes per line. static const int kBytesPerLine = 40; + // Limit the number of lines per string part. + static const int kLinesPerPart = 400; + // Every block of bytes, start a new string literal, in order to avoid the + // 64k length limit. Note that this value needs to be <64k. + static const int kBytesPerPart = kBytesPerLine * kLinesPerPart; for (int i = 0; i < file_data.size(); i += kBytesPerLine) { if (i > 0) { - // Every 400 lines, start a new string literal, in order to avoid the - // 64k length limit. - if (i % 400 == 0) { + if (i % kBytesPerPart == 0) { printer->Print(",\n"); } else { printer->Print(" +\n"); @@ -182,10 +185,16 @@ void SharedCodeGenerator::GenerateDescriptors(io::Printer* printer) { std::vector<std::pair<string, string> > dependencies; for (int i = 0; i < file_->dependency_count(); i++) { string filename = file_->dependency(i)->name(); - string classname = FileJavaPackage(file_->dependency(i)) + "." + - name_resolver_->GetDescriptorClassName( - file_->dependency(i)); - dependencies.push_back(std::make_pair(filename, classname)); + string package = FileJavaPackage(file_->dependency(i)); + string classname = name_resolver_->GetDescriptorClassName( + file_->dependency(i)); + string full_name; + if (package.empty()) { + full_name = classname; + } else { + full_name = package + "." + classname; + } + dependencies.push_back(std::make_pair(filename, full_name)); } // ----------------------------------------------------------------- diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc index 5c2900ce..2b6e9381 100644 --- a/src/google/protobuf/compiler/java/java_string_field.cc +++ b/src/google/protobuf/compiler/java/java_string_field.cc @@ -217,14 +217,15 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.Object ref = $name$_;\n" " if (ref instanceof java.lang.String) {\n" " return (java.lang.String) ref;\n" @@ -232,6 +233,7 @@ GenerateMembers(io::Printer* printer) const { " com.google.protobuf.ByteString bs = \n" " (com.google.protobuf.ByteString) ref;\n" " java.lang.String s = bs.toStringUtf8();\n"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " $name$_ = s;\n"); @@ -248,7 +250,7 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.Object ref = $name$_;\n" " if (ref instanceof java.lang.String) {\n" " com.google.protobuf.ByteString b = \n" @@ -260,6 +262,7 @@ GenerateMembers(io::Printer* printer) const { " return (com.google.protobuf.ByteString) ref;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableStringFieldGenerator:: @@ -269,19 +272,21 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_builder$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.Object ref = $name$_;\n" " if (!(ref instanceof java.lang.String)) {\n" " com.google.protobuf.ByteString bs =\n" " (com.google.protobuf.ByteString) ref;\n" " java.lang.String s = bs.toStringUtf8();\n"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " $name$_ = s;\n"); @@ -301,7 +306,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.Object ref = $name$_;\n" " if (ref instanceof String) {\n" " com.google.protobuf.ByteString b = \n" @@ -313,10 +318,11 @@ GenerateBuilderMembers(io::Printer* printer) const { " return (com.google.protobuf.ByteString) ref;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" "$null_check$" " $set_has_field_bit_builder$\n" @@ -324,10 +330,12 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $clear_has_field_bit_builder$\n"); + printer->Annotate("{", "}", descriptor_); // The default value is not a simple literal so we want to avoid executing // it multiple times. Instead, get the default out of the default instance. printer->Print(variables_, @@ -339,9 +347,10 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" "$null_check$"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); @@ -482,14 +491,15 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.Object ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = $oneof_name$_;\n" @@ -500,6 +510,7 @@ GenerateMembers(io::Printer* printer) const { " com.google.protobuf.ByteString bs = \n" " (com.google.protobuf.ByteString) ref;\n" " java.lang.String s = bs.toStringUtf8();\n"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " if ($has_oneof_case_message$) {\n" @@ -519,7 +530,7 @@ GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.Object ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = $oneof_name$_;\n" @@ -536,6 +547,7 @@ GenerateMembers(io::Printer* printer) const { " return (com.google.protobuf.ByteString) ref;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableStringOneofFieldGenerator:: @@ -543,14 +555,15 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.Object ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = $oneof_name$_;\n" @@ -560,6 +573,7 @@ GenerateBuilderMembers(io::Printer* printer) const { " (com.google.protobuf.ByteString) ref;\n" " java.lang.String s = bs.toStringUtf8();\n" " if ($has_oneof_case_message$) {\n"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " $oneof_name$_ = s;\n"); @@ -580,7 +594,7 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.Object ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = $oneof_name$_;\n" @@ -597,10 +611,11 @@ GenerateBuilderMembers(io::Printer* printer) const { " return (com.google.protobuf.ByteString) ref;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" "$null_check$" " $set_oneof_case_message$;\n" @@ -608,9 +623,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" " $oneof_name$_ = null;\n" @@ -618,12 +634,14 @@ GenerateBuilderMembers(io::Printer* printer) const { " }\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" "$null_check$"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); @@ -744,25 +762,30 @@ GenerateMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ProtocolStringList\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes(int index) {\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" " return $name$_.getByteString(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutableStringFieldGenerator:: @@ -794,28 +817,33 @@ GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ProtocolStringList\n" - " get$capitalized_name$List() {\n" + " ${$get$capitalized_name$List$}$() {\n" " return $name$_.getUnmodifiableView();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes(int index) {\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" " return $name$_.getByteString(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, java.lang.String value) {\n" "$null_check$" " ensure$capitalized_name$IsMutable();\n" @@ -823,9 +851,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " java.lang.String value) {\n" "$null_check$" " ensure$capitalized_name$IsMutable();\n" @@ -833,9 +862,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<java.lang.String> values) {\n" " ensure$capitalized_name$IsMutable();\n" " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" @@ -843,20 +873,23 @@ GenerateBuilderMembers(io::Printer* printer) const { " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $name$_ = $empty_list$;\n" " $clear_mutable_bit_builder$;\n" " $on_changed$\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" "$null_check$"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc index 7e3ad1d0..adda307c 100644 --- a/src/google/protobuf/compiler/java/java_string_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc @@ -71,7 +71,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); (*variables)["default_init"] = "= " + ImmutableDefaultValue(descriptor, name_resolver); - (*variables)["capitalized_type"] = "String"; + (*variables)["capitalized_type"] = "java.lang.String"; (*variables)["tag"] = SimpleItoa(static_cast<int32>(WireFormat::MakeTag(descriptor))); (*variables)["tag_size"] = SimpleItoa( @@ -192,22 +192,25 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " return com.google.protobuf.ByteString.copyFromUtf8($name$_);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -246,48 +249,54 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " return instance.get$capitalized_name$Bytes();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$Bytes(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableStringFieldLiteGenerator:: @@ -324,7 +333,7 @@ void ImmutableStringFieldLiteGenerator:: GenerateParsingCode(io::Printer* printer) const { if (CheckUtf8(descriptor_)) { printer->Print(variables_, - "String s = input.readStringRequireUtf8();\n" + "java.lang.String s = input.readStringRequireUtf8();\n" "$set_has_field_bit_message$\n" "$name$_ = s;\n"); } else { @@ -333,7 +342,7 @@ GenerateParsingCode(io::Printer* printer) const { // spurious intermediary ByteString allocations, cutting overall allocations // in half. printer->Print(variables_, - "String s = input.readString();\n" + "java.lang.String s = input.readString();\n" "$set_has_field_bit_message$\n" "$name$_ = s;\n"); } @@ -410,54 +419,60 @@ GenerateMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.String ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = (java.lang.String) $oneof_name$_;\n" " }\n" " return ref;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.String ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" " ref = (java.lang.String) $oneof_name$_;\n" " }\n" " return com.google.protobuf.ByteString.copyFromUtf8(ref);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "private void set$capitalized_name$(\n" + "private void ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" "$null_check$" " $set_oneof_case_message$;\n" " $oneof_name$_ = value;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "private void clear$capitalized_name$() {\n" + "private void ${$clear$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " $clear_oneof_case_message$;\n" " $oneof_name$_ = null;\n" " }\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "private void set$capitalized_name$Bytes(\n" + "private void ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" "$null_check$"); + printer->Annotate("{", "}", descriptor_); if (CheckUtf8(descriptor_)) { printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); @@ -474,48 +489,54 @@ GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return instance.has$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$() {\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " return instance.get$capitalized_name$();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes() {\n" + " ${$get$capitalized_name$Bytes$}$() {\n" " return instance.get$capitalized_name$Bytes();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " java.lang.String value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$Bytes(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void ImmutableStringOneofFieldLiteGenerator:: @@ -529,7 +550,7 @@ void ImmutableStringOneofFieldLiteGenerator:: GenerateParsingCode(io::Printer* printer) const { if (CheckUtf8(descriptor_)) { printer->Print(variables_, - "String s = input.readStringRequireUtf8();\n" + "java.lang.String s = input.readStringRequireUtf8();\n" "$set_oneof_case_message$;\n" "$oneof_name$_ = s;\n"); } else { @@ -538,7 +559,7 @@ GenerateParsingCode(io::Printer* printer) const { // spurious intermediary ByteString allocations, cutting overall allocations // in half. printer->Print(variables_, - "String s = input.readString();\n" + "java.lang.String s = input.readString();\n" "$set_oneof_case_message$;\n" "$oneof_name$_ = s;\n"); } @@ -597,7 +618,7 @@ void RepeatedImmutableStringFieldLiteGenerator:: GenerateInterfaceMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$java.util.List<String>\n" + "$deprecation$java.util.List<java.lang.String>\n" " get$capitalized_name$List();\n"); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -615,30 +636,37 @@ GenerateInterfaceMembers(io::Printer* printer) const { void RepeatedImmutableStringFieldLiteGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, - "private com.google.protobuf.Internal.ProtobufList<String> $name$_;\n"); + "private com.google.protobuf.Internal.ProtobufList<java.lang.String> " + "$name$_;\n"); PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<String> get$capitalized_name$List() {\n" - " return $name$_;\n" // note: unmodifiable list + "$deprecation$public java.util.List<java.lang.String> " + "${$get$capitalized_name$List$}$() {\n" + " return $name$_;\n" // note: unmodifiable list "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes(int index) {\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" " return com.google.protobuf.ByteString.copyFromUtf8(\n" " $name$_.get(index));\n" "}\n"); + printer->Annotate("{", "}", descriptor_); printer->Print(variables_, "private void ensure$capitalized_name$IsMutable() {\n" @@ -697,67 +725,77 @@ void RepeatedImmutableStringFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.util.List<String>\n" - " get$capitalized_name$List() {\n" + "$deprecation$public java.util.List<java.lang.String>\n" + " ${$get$capitalized_name$List$}$() {\n" " return java.util.Collections.unmodifiableList(\n" " instance.get$capitalized_name$List());\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return instance.get$capitalized_name$Count();\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" " return instance.get$capitalized_name$(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$public com.google.protobuf.ByteString\n" - " get$capitalized_name$Bytes(int index) {\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" " return instance.get$capitalized_name$Bytes(index);\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, java.lang.String value) {\n" " copyOnWrite();\n" " instance.set$capitalized_name$(index, value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" " java.lang.String value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable<java.lang.String> values) {\n" " copyOnWrite();\n" " instance.addAll$capitalized_name$(values);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " copyOnWrite();\n" " instance.clear$capitalized_name$();\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$Bytes(\n" + "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n" " com.google.protobuf.ByteString value) {\n" " copyOnWrite();\n" " instance.add$capitalized_name$Bytes(value);\n" " return this;\n" "}\n"); + printer->Annotate("{", "}", descriptor_); } void RepeatedImmutableStringFieldLiteGenerator:: @@ -787,14 +825,14 @@ void RepeatedImmutableStringFieldLiteGenerator:: GenerateParsingCode(io::Printer* printer) const { if (CheckUtf8(descriptor_)) { printer->Print(variables_, - "String s = input.readStringRequireUtf8();\n"); + "java.lang.String s = input.readStringRequireUtf8();\n"); } else { // Lite runtime should attempt to reduce allocations by attempting to // construct the string directly from the input stream buffer. This avoids // spurious intermediary ByteString allocations, cutting overall allocations // in half. printer->Print(variables_, - "String s = input.readString();\n"); + "java.lang.String s = input.readString();\n"); } printer->Print(variables_, "if (!$is_mutable$) {\n" @@ -868,7 +906,7 @@ GenerateHashCode(io::Printer* printer) const { } string RepeatedImmutableStringFieldLiteGenerator::GetBoxedType() const { - return "String"; + return "java.lang.String"; } } // namespace java diff --git a/src/google/protobuf/compiler/javanano/javanano_enum.h b/src/google/protobuf/compiler/javanano/javanano_enum.h index 10dd3648..82e098fc 100644 --- a/src/google/protobuf/compiler/javanano/javanano_enum.h +++ b/src/google/protobuf/compiler/javanano/javanano_enum.h @@ -68,13 +68,13 @@ class EnumGenerator { // considered equivalent. We treat the first defined constant for any // given numeric value as "canonical" and the rest as aliases of that // canonical value. - vector<const EnumValueDescriptor*> canonical_values_; + std::vector<const EnumValueDescriptor*> canonical_values_; struct Alias { const EnumValueDescriptor* value; const EnumValueDescriptor* canonical_value; }; - vector<Alias> aliases_; + std::vector<Alias> aliases_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); }; diff --git a/src/google/protobuf/compiler/javanano/javanano_enum_field.cc b/src/google/protobuf/compiler/javanano/javanano_enum_field.cc index 7666db38..ea67a810 100644 --- a/src/google/protobuf/compiler/javanano/javanano_enum_field.cc +++ b/src/google/protobuf/compiler/javanano/javanano_enum_field.cc @@ -52,7 +52,7 @@ namespace { // TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of // repeat code between this and the other field types. void SetEnumVariables(const Params& params, - const FieldDescriptor* descriptor, map<string, string>* variables) { + const FieldDescriptor* descriptor, std::map<string, string>* variables) { (*variables)["name"] = RenameJavaKeywords(UnderscoresToCamelCase(descriptor)); (*variables)["capitalized_name"] = @@ -83,7 +83,7 @@ void SetEnumVariables(const Params& params, } void LoadEnumValues(const Params& params, - const EnumDescriptor* enum_descriptor, vector<string>* canonical_values) { + const EnumDescriptor* enum_descriptor, std::vector<string>* canonical_values) { string enum_class_name = ClassName(params, enum_descriptor); for (int i = 0; i < enum_descriptor->value_count(); i++) { const EnumValueDescriptor* value = enum_descriptor->value(i); @@ -97,7 +97,7 @@ void LoadEnumValues(const Params& params, } void PrintCaseLabels( - io::Printer* printer, const vector<string>& canonical_values) { + io::Printer* printer, const std::vector<string>& canonical_values) { for (int i = 0; i < canonical_values.size(); i++) { printer->Print( " case $value$:\n", diff --git a/src/google/protobuf/compiler/javanano/javanano_enum_field.h b/src/google/protobuf/compiler/javanano/javanano_enum_field.h index b94790d6..8cd0e248 100644 --- a/src/google/protobuf/compiler/javanano/javanano_enum_field.h +++ b/src/google/protobuf/compiler/javanano/javanano_enum_field.h @@ -62,8 +62,8 @@ class EnumFieldGenerator : public FieldGenerator { private: const FieldDescriptor* descriptor_; - map<string, string> variables_; - vector<string> canonical_values_; + std::map<string, string> variables_; + std::vector<string> canonical_values_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); }; @@ -85,8 +85,8 @@ class AccessorEnumFieldGenerator : public FieldGenerator { private: const FieldDescriptor* descriptor_; - map<string, string> variables_; - vector<string> canonical_values_; + std::map<string, string> variables_; + std::vector<string> canonical_values_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AccessorEnumFieldGenerator); }; @@ -112,8 +112,8 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { void GenerateRepeatedDataSizeCode(io::Printer* printer) const; const FieldDescriptor* descriptor_; - map<string, string> variables_; - vector<string> canonical_values_; + std::map<string, string> variables_; + std::vector<string> canonical_values_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); }; diff --git a/src/google/protobuf/compiler/javanano/javanano_extension.cc b/src/google/protobuf/compiler/javanano/javanano_extension.cc index 0b9d1d8d..4c61f915 100644 --- a/src/google/protobuf/compiler/javanano/javanano_extension.cc +++ b/src/google/protobuf/compiler/javanano/javanano_extension.cc @@ -78,7 +78,7 @@ const char* GetTypeConstantName(const FieldDescriptor::Type type) { } // namespace void SetVariables(const FieldDescriptor* descriptor, const Params params, - map<string, string>* variables) { + std::map<string, string>* variables) { (*variables)["extends"] = ClassName(params, descriptor->containing_type()); (*variables)["name"] = RenameJavaKeywords(UnderscoresToCamelCase(descriptor)); bool repeated = descriptor->is_repeated(); diff --git a/src/google/protobuf/compiler/javanano/javanano_extension.h b/src/google/protobuf/compiler/javanano/javanano_extension.h index 4843e296..f4e9eb2d 100644 --- a/src/google/protobuf/compiler/javanano/javanano_extension.h +++ b/src/google/protobuf/compiler/javanano/javanano_extension.h @@ -61,7 +61,7 @@ class ExtensionGenerator { private: const Params& params_; const FieldDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); }; diff --git a/src/google/protobuf/compiler/javanano/javanano_field.cc b/src/google/protobuf/compiler/javanano/javanano_field.cc index 85257f3f..e31d1177 100644 --- a/src/google/protobuf/compiler/javanano/javanano_field.cc +++ b/src/google/protobuf/compiler/javanano/javanano_field.cc @@ -151,7 +151,7 @@ const FieldGenerator& FieldGeneratorMap::get( } void SetCommonOneofVariables(const FieldDescriptor* descriptor, - map<string, string>* variables) { + std::map<string, string>* variables) { (*variables)["oneof_name"] = UnderscoresToCamelCase(descriptor->containing_oneof()); (*variables)["oneof_capitalized_name"] = @@ -169,7 +169,7 @@ void SetCommonOneofVariables(const FieldDescriptor* descriptor, } void GenerateOneofFieldEquals(const FieldDescriptor* descriptor, - const map<string, string>& variables, + const std::map<string, string>& variables, io::Printer* printer) { if (GetJavaType(descriptor) == JAVATYPE_BYTES) { printer->Print(variables, @@ -190,7 +190,7 @@ void GenerateOneofFieldEquals(const FieldDescriptor* descriptor, } void GenerateOneofFieldHashCode(const FieldDescriptor* descriptor, - const map<string, string>& variables, + const std::map<string, string>& variables, io::Printer* printer) { if (GetJavaType(descriptor) == JAVATYPE_BYTES) { printer->Print(variables, diff --git a/src/google/protobuf/compiler/javanano/javanano_field.h b/src/google/protobuf/compiler/javanano/javanano_field.h index 57c221f4..347c888c 100644 --- a/src/google/protobuf/compiler/javanano/javanano_field.h +++ b/src/google/protobuf/compiler/javanano/javanano_field.h @@ -114,12 +114,12 @@ class FieldGeneratorMap { }; void SetCommonOneofVariables(const FieldDescriptor* descriptor, - map<string, string>* variables); + std::map<string, string>* variables); void GenerateOneofFieldEquals(const FieldDescriptor* descriptor, - const map<string, string>& variables, + const std::map<string, string>& variables, io::Printer* printer); void GenerateOneofFieldHashCode(const FieldDescriptor* descriptor, - const map<string, string>& variables, + const std::map<string, string>& variables, io::Printer* printer); } // namespace javanano diff --git a/src/google/protobuf/compiler/javanano/javanano_file.cc b/src/google/protobuf/compiler/javanano/javanano_file.cc index 17f7386e..7a661a42 100644 --- a/src/google/protobuf/compiler/javanano/javanano_file.cc +++ b/src/google/protobuf/compiler/javanano/javanano_file.cc @@ -59,7 +59,7 @@ bool UsesExtensions(const Message& message) { // We conservatively assume that unknown fields are extensions. if (reflection->GetUnknownFields(message).field_count() > 0) return true; - vector<const FieldDescriptor*> fields; + std::vector<const FieldDescriptor*> fields; reflection->ListFields(message, &fields); for (int i = 0; i < fields.size(); i++) { @@ -216,7 +216,7 @@ static void GenerateSibling(const string& package_dir, const string& java_package, const DescriptorClass* descriptor, GeneratorContext* output_directory, - vector<string>* file_list, + std::vector<string>* file_list, const Params& params) { string filename = package_dir + descriptor->name() + ".java"; file_list->push_back(filename); @@ -239,7 +239,7 @@ static void GenerateSibling(const string& package_dir, void FileGenerator::GenerateSiblings(const string& package_dir, GeneratorContext* output_directory, - vector<string>* file_list) { + std::vector<string>* file_list) { if (params_.java_multiple_files(file_->name())) { for (int i = 0; i < file_->message_type_count(); i++) { GenerateSibling<MessageGenerator>(package_dir, java_package_, diff --git a/src/google/protobuf/compiler/javanano/javanano_file.h b/src/google/protobuf/compiler/javanano/javanano_file.h index 217eafe2..4ad3868c 100644 --- a/src/google/protobuf/compiler/javanano/javanano_file.h +++ b/src/google/protobuf/compiler/javanano/javanano_file.h @@ -72,7 +72,7 @@ class FileGenerator { // service type). void GenerateSiblings(const string& package_dir, GeneratorContext* output_directory, - vector<string>* file_list); + std::vector<string>* file_list); const string& java_package() { return java_package_; } const string& classname() { return classname_; } diff --git a/src/google/protobuf/compiler/javanano/javanano_generator.cc b/src/google/protobuf/compiler/javanano/javanano_generator.cc index 7c3a0421..fd7151b1 100644 --- a/src/google/protobuf/compiler/javanano/javanano_generator.cc +++ b/src/google/protobuf/compiler/javanano/javanano_generator.cc @@ -94,7 +94,7 @@ bool JavaNanoGenerator::Generate(const FileDescriptor* file, const string& parameter, GeneratorContext* output_directory, string* error) const { - vector<pair<string, string> > options; + std::vector<std::pair<string, string> > options; ParseGeneratorParameter(parameter, &options); @@ -116,24 +116,24 @@ bool JavaNanoGenerator::Generate(const FileDescriptor* file, if (option_name == "output_list_file") { output_list_file = option_value; } else if (option_name == "java_package") { - vector<string> parts; - SplitStringUsing(option_value, "|", &parts); - if (parts.size() != 2) { - *error = "Bad java_package, expecting filename|PackageName found '" - + option_value + "'"; - return false; - } - params.set_java_package(parts[0], parts[1]); + std::vector<string> parts; + SplitStringUsing(option_value, "|", &parts); + if (parts.size() != 2) { + *error = "Bad java_package, expecting filename|PackageName found '" + + option_value + "'"; + return false; + } + params.set_java_package(parts[0], parts[1]); } else if (option_name == "java_outer_classname") { - vector<string> parts; - SplitStringUsing(option_value, "|", &parts); - if (parts.size() != 2) { - *error = "Bad java_outer_classname, " - "expecting filename|ClassName found '" - + option_value + "'"; - return false; - } - params.set_java_outer_classname(parts[0], parts[1]); + std::vector<string> parts; + SplitStringUsing(option_value, "|", &parts); + if (parts.size() != 2) { + *error = "Bad java_outer_classname, " + "expecting filename|ClassName found '" + + option_value + "'"; + return false; + } + params.set_java_outer_classname(parts[0], parts[1]); } else if (option_name == "store_unknown_fields") { params.set_store_unknown_fields(option_value == "true"); } else if (option_name == "java_multiple_files") { @@ -191,7 +191,7 @@ bool JavaNanoGenerator::Generate(const FileDescriptor* file, StringReplace(file_generator.java_package(), ".", "/", true); if (!package_dir.empty()) package_dir += "/"; - vector<string> all_files; + std::vector<string> all_files; if (IsOuterClassNeeded(params, file)) { string java_filename = package_dir; diff --git a/src/google/protobuf/compiler/javanano/javanano_helpers.cc b/src/google/protobuf/compiler/javanano/javanano_helpers.cc index 5018250c..1927ba12 100644 --- a/src/google/protobuf/compiler/javanano/javanano_helpers.cc +++ b/src/google/protobuf/compiler/javanano/javanano_helpers.cc @@ -567,7 +567,7 @@ string GenerateDifferentBit(int bit_index) { } void SetBitOperationVariables(const string name, - int bitIndex, map<string, string>* variables) { + int bitIndex, std::map<string, string>* variables) { (*variables)["get_" + name] = GenerateGetBit(bitIndex); (*variables)["set_" + name] = GenerateSetBit(bitIndex); (*variables)["clear_" + name] = GenerateClearBit(bitIndex); diff --git a/src/google/protobuf/compiler/javanano/javanano_helpers.h b/src/google/protobuf/compiler/javanano/javanano_helpers.h index 014c85ae..04b2d633 100644 --- a/src/google/protobuf/compiler/javanano/javanano_helpers.h +++ b/src/google/protobuf/compiler/javanano/javanano_helpers.h @@ -181,7 +181,7 @@ string GenerateDifferentBit(int bit_index); // the given name of the bit, to the appropriate Java expressions for the given // bit index. void SetBitOperationVariables(const string name, - int bitIndex, map<string, string>* variables); + int bitIndex, std::map<string, string>* variables); inline bool IsMapEntry(const Descriptor* descriptor) { // TODO(liujisi): Add an option to turn on maps for proto2 syntax as well. diff --git a/src/google/protobuf/compiler/javanano/javanano_map_field.cc b/src/google/protobuf/compiler/javanano/javanano_map_field.cc index 83b2b0ce..a4ab8858 100644 --- a/src/google/protobuf/compiler/javanano/javanano_map_field.cc +++ b/src/google/protobuf/compiler/javanano/javanano_map_field.cc @@ -84,7 +84,7 @@ const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) { } void SetMapVariables(const Params& params, - const FieldDescriptor* descriptor, map<string, string>* variables) { + const FieldDescriptor* descriptor, std::map<string, string>* variables) { const FieldDescriptor* key = KeyField(descriptor); const FieldDescriptor* value = ValueField(descriptor); (*variables)["name"] = diff --git a/src/google/protobuf/compiler/javanano/javanano_map_field.h b/src/google/protobuf/compiler/javanano/javanano_map_field.h index c01bde38..81e5915d 100644 --- a/src/google/protobuf/compiler/javanano/javanano_map_field.h +++ b/src/google/protobuf/compiler/javanano/javanano_map_field.h @@ -58,7 +58,7 @@ class MapFieldGenerator : public FieldGenerator { private: const FieldDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator); }; diff --git a/src/google/protobuf/compiler/javanano/javanano_message.cc b/src/google/protobuf/compiler/javanano/javanano_message.cc index f81f7f9a..78421887 100644 --- a/src/google/protobuf/compiler/javanano/javanano_message.cc +++ b/src/google/protobuf/compiler/javanano/javanano_message.cc @@ -182,7 +182,7 @@ void MessageGenerator::Generate(io::Printer* printer) { } // oneof - map<string, string> vars; + std::map<string, string> vars; vars["message_name"] = descriptor_->name(); for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { const OneofDescriptor* oneof_desc = descriptor_->oneof_decl(i); diff --git a/src/google/protobuf/compiler/javanano/javanano_message_field.cc b/src/google/protobuf/compiler/javanano/javanano_message_field.cc index d1d04b52..2ed8a3aa 100644 --- a/src/google/protobuf/compiler/javanano/javanano_message_field.cc +++ b/src/google/protobuf/compiler/javanano/javanano_message_field.cc @@ -54,7 +54,7 @@ namespace { // TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of // repeat code between this and the other field types. void SetMessageVariables(const Params& params, - const FieldDescriptor* descriptor, map<string, string>* variables) { + const FieldDescriptor* descriptor, std::map<string, string>* variables) { (*variables)["name"] = RenameJavaKeywords(UnderscoresToCamelCase(descriptor)); (*variables)["capitalized_name"] = diff --git a/src/google/protobuf/compiler/javanano/javanano_message_field.h b/src/google/protobuf/compiler/javanano/javanano_message_field.h index e074735c..0ae8879b 100644 --- a/src/google/protobuf/compiler/javanano/javanano_message_field.h +++ b/src/google/protobuf/compiler/javanano/javanano_message_field.h @@ -62,7 +62,7 @@ class MessageFieldGenerator : public FieldGenerator { private: const FieldDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); }; @@ -85,7 +85,7 @@ class MessageOneofFieldGenerator : public FieldGenerator { private: const FieldDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator); }; @@ -108,7 +108,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { private: const FieldDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); }; diff --git a/src/google/protobuf/compiler/javanano/javanano_params.h b/src/google/protobuf/compiler/javanano/javanano_params.h index e3b4bb93..3594767d 100644 --- a/src/google/protobuf/compiler/javanano/javanano_params.h +++ b/src/google/protobuf/compiler/javanano/javanano_params.h @@ -47,8 +47,8 @@ enum eMultipleFiles { JAVANANO_MUL_UNSET, JAVANANO_MUL_FALSE, JAVANANO_MUL_TRUE // Parameters for used by the generators class Params { public: - typedef map<string, string> NameMap; - typedef set<string> NameSet; + typedef std::map<string, string> NameMap; + typedef std::set<string> NameSet; private: string empty_; string base_name_; diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc index 978abf2c..66a0ff05 100644 --- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc +++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc @@ -166,7 +166,7 @@ bool AllAscii(const string& text) { void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params, - map<string, string>* variables) { + std::map<string, string>* variables) { (*variables)["name"] = RenameJavaKeywords(UnderscoresToCamelCase(descriptor)); (*variables)["capitalized_name"] = diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.h b/src/google/protobuf/compiler/javanano/javanano_primitive_field.h index a01981dd..d7d72d57 100644 --- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.h +++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.h @@ -65,7 +65,7 @@ class PrimitiveFieldGenerator : public FieldGenerator { void GenerateSerializationConditional(io::Printer* printer) const; const FieldDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); }; @@ -89,7 +89,7 @@ class AccessorPrimitiveFieldGenerator : public FieldGenerator { private: const FieldDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AccessorPrimitiveFieldGenerator); }; @@ -111,7 +111,7 @@ class PrimitiveOneofFieldGenerator : public FieldGenerator { private: const FieldDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator); }; @@ -137,7 +137,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { void GenerateRepeatedDataSizeCode(io::Printer* printer) const; const FieldDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); }; diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index 7c63e58f..fd2d3dfd 100755 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -143,12 +143,16 @@ bool IsReserved(const string& ident) { return false; } +bool StrEndsWith(StringPiece sp, StringPiece x) { + return sp.size() >= x.size() && sp.substr(sp.size() - x.size()) == x; +} + // Returns a copy of |filename| with any trailing ".protodevel" or ".proto // suffix stripped. // TODO(haberman): Unify with copy in compiler/cpp/internal/helpers.cc. string StripProto(const string& filename) { - const char* suffix = HasSuffixString(filename, ".protodevel") - ? ".protodevel" : ".proto"; + const char* suffix = + StrEndsWith(filename, ".protodevel") ? ".protodevel" : ".proto"; return StripSuffixString(filename, suffix); } @@ -191,8 +195,9 @@ string ModuleAlias(const string& filename) { // We'll worry about this problem if/when we actually see it. This name isn't // exposed to users so we can change it later if we need to. string basename = StripProto(filename); - StripString(&basename, "-", '$'); - StripString(&basename, "/", '_'); + ReplaceCharacters(&basename, "-", '$'); + ReplaceCharacters(&basename, "/", '_'); + ReplaceCharacters(&basename, ".", '_'); return basename + "_pb"; } @@ -239,22 +244,35 @@ string GetPrefix(const GeneratorOptions& options, return prefix; } +// Returns the fully normalized JavaScript path prefix for the given +// message descriptor. +string GetMessagePathPrefix(const GeneratorOptions& options, + const Descriptor* descriptor) { + return GetPrefix( + options, descriptor->file(), + descriptor->containing_type()); +} + // Returns the fully normalized JavaScript path for the given // message descriptor. string GetMessagePath(const GeneratorOptions& options, const Descriptor* descriptor) { - return GetPrefix( - options, descriptor->file(), - descriptor->containing_type()) + descriptor->name(); + return GetMessagePathPrefix(options, descriptor) + descriptor->name(); +} + +// Returns the fully normalized JavaScript path prefix for the given +// enumeration descriptor. +string GetEnumPathPrefix(const GeneratorOptions& options, + const EnumDescriptor* enum_descriptor) { + return GetPrefix(options, enum_descriptor->file(), + enum_descriptor->containing_type()); } // Returns the fully normalized JavaScript path for the given // enumeration descriptor. string GetEnumPath(const GeneratorOptions& options, const EnumDescriptor* enum_descriptor) { - return GetPrefix( - options, enum_descriptor->file(), - enum_descriptor->containing_type()) + enum_descriptor->name(); + return GetEnumPathPrefix(options, enum_descriptor) + enum_descriptor->name(); } string MaybeCrossFileRef(const GeneratorOptions& options, @@ -756,8 +774,22 @@ string DoubleToString(double value) { return PostProcessFloat(result); } +// Return true if this is an integral field that should be represented as string +// in JS. +bool IsIntegralFieldWithStringJSType(const FieldDescriptor* field) { + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT64: + // The default value of JSType is JS_NORMAL, which behaves the same as + // JS_NUMBER. + return field->options().jstype() == google::protobuf::FieldOptions::JS_STRING; + default: + return false; + } +} + string MaybeNumberString(const FieldDescriptor* field, const string& orig) { - return orig; + return IsIntegralFieldWithStringJSType(field) ? ("\"" + orig + "\"") : orig; } string JSFieldDefault(const FieldDescriptor* field) { @@ -856,7 +888,7 @@ string ProtoTypeName(const GeneratorOptions& options, } string JSIntegerTypeName(const FieldDescriptor* field) { - return "number"; + return IsIntegralFieldWithStringJSType(field) ? "string" : "number"; } string JSStringTypeName(const GeneratorOptions& options, @@ -996,7 +1028,7 @@ string JSFieldTypeAnnotation(const GeneratorOptions& options, if (!IsPrimitive(jstype)) { jstype = "!" + jstype; } - jstype = "Array.<" + jstype + ">"; + jstype = "Array<" + jstype + ">"; } } @@ -1033,8 +1065,7 @@ string JSBinaryReaderMethodType(const FieldDescriptor* field) { if (name[0] >= 'a' && name[0] <= 'z') { name[0] = (name[0] - 'a') + 'A'; } - - return name; + return IsIntegralFieldWithStringJSType(field) ? (name + "String") : name; } string JSBinaryReadWriteMethodName(const FieldDescriptor* field, @@ -1064,6 +1095,40 @@ string JSReturnClause(const FieldDescriptor* desc) { return ""; } +string JSTypeTag(const FieldDescriptor* desc) { + switch (desc->type()) { + case FieldDescriptor::TYPE_DOUBLE: + case FieldDescriptor::TYPE_FLOAT: + return "Float"; + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_SFIXED32: + case FieldDescriptor::TYPE_SFIXED64: + if (IsIntegralFieldWithStringJSType(desc)) { + return "StringInt"; + } else { + return "Int"; + } + case FieldDescriptor::TYPE_BOOL: + return "Boolean"; + case FieldDescriptor::TYPE_STRING: + return "String"; + case FieldDescriptor::TYPE_BYTES: + return "Bytes"; + case FieldDescriptor::TYPE_ENUM: + return "Enum"; + default: + assert(false); + } + return ""; +} + string JSReturnDoc(const GeneratorOptions& options, const FieldDescriptor* desc) { return ""; @@ -1244,13 +1309,6 @@ string FieldComments(const FieldDescriptor* field, BytesMode bytes_mode) { " * You should avoid comparisons like {@code val === true/false} in " "those cases.\n"; } - if (field->is_repeated()) { - comments += - " * If you change this array by adding, removing or replacing " - "elements, or if you\n" - " * replace the array itself, then you must call the setter to " - "update it.\n"; - } if (field->type() == FieldDescriptor::TYPE_BYTES && bytes_mode == BYTES_U8) { comments += " * Note that Uint8Array is not supported on all browsers.\n" @@ -1323,7 +1381,7 @@ bool IsExtendable(const Descriptor* desc) { // Returns the max index in the underlying data storage array beyond which the // extension object is used. string GetPivot(const Descriptor* desc) { - static const int kDefaultPivot = (1 << 29); // max field number (29 bits) + static const int kDefaultPivot = 500; // Find the max field number int max_field_number = 0; @@ -1335,7 +1393,7 @@ string GetPivot(const Descriptor* desc) { } int pivot = -1; - if (IsExtendable(desc)) { + if (IsExtendable(desc) || (max_field_number >= kDefaultPivot)) { pivot = ((max_field_number + 1) < kDefaultPivot) ? (max_field_number + 1) : kDefaultPivot; } @@ -1500,6 +1558,22 @@ bool GenerateJspbAllowedSet(const GeneratorOptions& options, return true; } +// Embeds base64 encoded GeneratedCodeInfo proto in a comment at the end of +// file. +void EmbedCodeAnnotations(const GeneratedCodeInfo& annotations, + io::Printer* printer) { + // Serialize annotations proto into base64 string. + string meta_content; + annotations.SerializeToString(&meta_content); + string meta_64; + Base64Escape(meta_content, &meta_64); + + // Print base64 encoded annotations at the end of output file in + // a comment. + printer->Print("\n// Below is base64 encoded GeneratedCodeInfo proto"); + printer->Print("\n// $encoded_proto$\n", "encoded_proto", meta_64); +} + } // anonymous namespace void Generator::GenerateHeader(const GeneratorOptions& options, @@ -1507,6 +1581,10 @@ void Generator::GenerateHeader(const GeneratorOptions& options, printer->Print("/**\n" " * @fileoverview\n" " * @enhanceable\n" + " * @suppress {messageConventions} JS Compiler reports an " + "error if a variable or\n" + " * field starts with 'MSG_' and isn't a translatable " + "message.\n" " * @public\n" " */\n" "// GENERATED CODE -- DO NOT EDIT!\n" @@ -1698,18 +1776,16 @@ void Generator::GenerateRequiresImpl(const GeneratorOptions& options, bool require_jspb, bool require_extension, bool require_map) const { if (require_jspb) { - printer->Print( - "goog.require('jspb.Message');\n" - "goog.require('jspb.BinaryReader');\n" - "goog.require('jspb.BinaryWriter');\n"); + required->insert("jspb.Message"); + required->insert("jspb.BinaryReader"); + required->insert("jspb.BinaryWriter"); } if (require_extension) { - printer->Print("goog.require('jspb.ExtensionFieldBinaryInfo');\n"); - printer->Print( - "goog.require('jspb.ExtensionFieldInfo');\n"); + required->insert("jspb.ExtensionFieldBinaryInfo"); + required->insert("jspb.ExtensionFieldInfo"); } if (require_map) { - printer->Print("goog.require('jspb.Map');\n"); + required->insert("jspb.Map"); } std::set<string>::iterator it; @@ -1883,8 +1959,10 @@ void Generator::GenerateClassConstructor(const GeneratorOptions& options, " * @extends {jspb.Message}\n" " * @constructor\n" " */\n" - "$classname$ = function(opt_data) {\n", - "classname", GetMessagePath(options, desc)); + "$classprefix$$classname$ = function(opt_data) {\n", + "classprefix", GetMessagePathPrefix(options, desc), + "classname", desc->name()); + printer->Annotate("classname", desc); string message_id = GetMessageId(desc); printer->Print( " jspb.Message.initialize(this, opt_data, $messageId$, $pivot$, " @@ -2037,6 +2115,7 @@ void Generator::GenerateClassToObject(const GeneratorOptions& options, " * http://goto/soy-param-migration\n" " * @param {!$classname$} msg The msg instance to transform.\n" " * @return {!Object}\n" + " * @suppress {unusedLocalVariables} f is only used for nested messages\n" " */\n" "$classname$.toObject = function(includeInstance, msg) {\n" " var f, obj = {", @@ -2125,7 +2204,8 @@ void Generator::GenerateFieldValueExpression(io::Printer* printer, "obj", obj_reference); } } else { - printer->Print("jspb.Message.getField($obj$, $index$)", + printer->Print("jspb.Message.get$cardinality$Field($obj$, $index$)", + "cardinality", field->is_repeated() ? "Repeated" : "", "index", JSFieldIndex(field), "obj", obj_reference); } @@ -2333,7 +2413,6 @@ void GenerateBytesWrapper(const GeneratorOptions& options, "defname", JSGetterName(options, field, BYTES_DEFAULT)); } - void Generator::GenerateClassField(const GeneratorOptions& options, io::Printer* printer, const FieldDescriptor* field) const { @@ -2365,12 +2444,13 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "keytype", key_type, "valuetype", value_type); printer->Print( - "$class$.prototype.get$name$ = function(opt_noLazyCreate) {\n" + "$class$.prototype.$gettername$ = function(opt_noLazyCreate) {\n" " return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n", "class", GetMessagePath(options, field->containing_type()), - "name", JSGetterName(options, field), + "gettername", "get" + JSGetterName(options, field), "keytype", key_type, "valuetype", value_type); + printer->Annotate("gettername", field); printer->Print( " jspb.Message.getMapField(this, $index$, opt_noLazyCreate", "index", JSFieldIndex(field)); @@ -2409,7 +2489,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, /* force_present = */ false, /* singular_if_not_packed = */ false)); printer->Print( - "$class$.prototype.get$name$ = function() {\n" + "$class$.prototype.$gettername$ = function() {\n" " return /** @type{$type$} */ (\n" " jspb.Message.get$rpt$WrapperField(this, $wrapperclass$, " "$index$$required$));\n" @@ -2417,7 +2497,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "\n" "\n", "class", GetMessagePath(options, field->containing_type()), - "name", JSGetterName(options, field), + "gettername", "get" + JSGetterName(options, field), "type", JSFieldTypeAnnotation(options, field, /* is_setter_argument = */ false, /* force_present = */ false, @@ -2427,9 +2507,10 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "wrapperclass", SubmessageTypeRef(options, field), "required", (field->label() == FieldDescriptor::LABEL_REQUIRED ? ", 1" : "")); + printer->Annotate("gettername", field); printer->Print( "/** @param {$optionaltype$} value$returndoc$ */\n" - "$class$.prototype.set$name$ = function(value) {\n" + "$class$.prototype.$settername$ = function(value) {\n" " jspb.Message.set$oneoftag$$repeatedtag$WrapperField(", "optionaltype", JSFieldTypeAnnotation(options, field, @@ -2438,9 +2519,10 @@ void Generator::GenerateClassField(const GeneratorOptions& options, /* singular_if_not_packed = */ false), "returndoc", JSReturnDoc(options, field), "class", GetMessagePath(options, field->containing_type()), - "name", JSGetterName(options, field), + "settername", "set" + JSGetterName(options, field), "oneoftag", (field->containing_oneof() ? "Oneof" : ""), "repeatedtag", (field->is_repeated() ? "Repeated" : "")); + printer->Annotate("settername", field); printer->Print( "this, $index$$oneofgroup$, value);$returnvalue$\n" @@ -2463,7 +2545,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, // Simple (primitive) field, either singular or repeated. // TODO(b/26173701): Always use BYTES_DEFAULT for the getter return type; - // at this point we "lie" to non-binary users and tell the the return + // at this point we "lie" to non-binary users and tell the return // type is always base64 string, pending a LSC to migrate to typed getters. BytesMode bytes_mode = field->type() == FieldDescriptor::TYPE_BYTES && !options.binary ? @@ -2492,9 +2574,10 @@ void Generator::GenerateClassField(const GeneratorOptions& options, } printer->Print( - "$class$.prototype.get$name$ = function() {\n", + "$class$.prototype.$gettername$ = function() {\n", "class", GetMessagePath(options, field->containing_type()), - "name", JSGetterName(options, field)); + "gettername", "get" + JSGetterName(options, field)); + printer->Annotate("gettername", field); if (untyped) { printer->Print( @@ -2555,26 +2638,47 @@ void Generator::GenerateClassField(const GeneratorOptions& options, /* singular_if_not_packed = */ false), "returndoc", JSReturnDoc(options, field)); } - printer->Print( - "$class$.prototype.set$name$ = function(value) {\n" - " jspb.Message.set$oneoftag$Field(this, $index$", - "class", GetMessagePath(options, field->containing_type()), - "name", JSGetterName(options, field), - "oneoftag", (field->containing_oneof() ? "Oneof" : ""), - "index", JSFieldIndex(field)); - printer->Print( - "$oneofgroup$, $type$value$rptvalueinit$$typeclose$);$returnvalue$\n" - "};\n" - "\n" - "\n", - "type", - untyped ? "/** @type{string|number|boolean|Array|undefined} */(" : "", - "typeclose", untyped ? ")" : "", - "oneofgroup", - (field->containing_oneof() ? (", " + JSOneofArray(options, field)) - : ""), - "returnvalue", JSReturnClause(field), "rptvalueinit", - (field->is_repeated() ? " || []" : "")); + + if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 && + !field->is_repeated() && !field->is_map() && + !HasFieldPresence(options, field)) { + // Proto3 non-repeated and non-map fields without presence use the + // setProto3*Field function. + printer->Print( + "$class$.prototype.$settername$ = function(value) {\n" + " jspb.Message.setProto3$typetag$Field(this, $index$, " + "value);$returnvalue$\n" + "};\n" + "\n" + "\n", + "class", GetMessagePath(options, field->containing_type()), + "settername", "set" + JSGetterName(options, field), "typetag", + JSTypeTag(field), "index", JSFieldIndex(field), "returnvalue", + JSReturnClause(field)); + printer->Annotate("settername", field); + } else { + // Otherwise, use the regular setField function. + printer->Print( + "$class$.prototype.$settername$ = function(value) {\n" + " jspb.Message.set$oneoftag$Field(this, $index$", + "class", GetMessagePath(options, field->containing_type()), + "settername", "set" + JSGetterName(options, field), "oneoftag", + (field->containing_oneof() ? "Oneof" : ""), "index", + JSFieldIndex(field)); + printer->Annotate("settername", field); + printer->Print( + "$oneofgroup$, $type$value$rptvalueinit$$typeclose$);$returnvalue$\n" + "};\n" + "\n" + "\n", + "type", + untyped ? "/** @type{string|number|boolean|Array|undefined} */(" : "", + "typeclose", untyped ? ")" : "", "oneofgroup", + (field->containing_oneof() ? (", " + JSOneofArray(options, field)) + : ""), + "returnvalue", JSReturnClause(field), "rptvalueinit", + (field->is_repeated() ? " || []" : "")); + } if (untyped) { printer->Print( @@ -2594,41 +2698,46 @@ void Generator::GenerateClassField(const GeneratorOptions& options, // fields with presence. if (IsMap(options, field)) { printer->Print( - "$class$.prototype.clear$name$ = function() {\n" - " this.get$name$().clear();$returnvalue$\n" + "$class$.prototype.$clearername$ = function() {\n" + " this.$gettername$().clear();$returnvalue$\n" "};\n" "\n" "\n", "class", GetMessagePath(options, field->containing_type()), - "name", JSGetterName(options, field), + "clearername", "clear" + JSGetterName(options, field), + "gettername", "get" + JSGetterName(options, field), "returnvalue", JSReturnClause(field)); + printer->Annotate("clearername", field); } else if (field->is_repeated() || (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !field->is_required())) { // Fields where we can delegate to the regular setter. printer->Print( - "$class$.prototype.clear$name$ = function() {\n" - " this.set$name$($clearedvalue$);$returnvalue$\n" + "$class$.prototype.$clearername$ = function() {\n" + " this.$settername$($clearedvalue$);$returnvalue$\n" "};\n" "\n" "\n", "class", GetMessagePath(options, field->containing_type()), - "name", JSGetterName(options, field), + "clearername", "clear" + JSGetterName(options, field), + "settername", "set" + JSGetterName(options, field), "clearedvalue", (field->is_repeated() ? "[]" : "undefined"), "returnvalue", JSReturnClause(field)); + printer->Annotate("clearername", field); } else if (HasFieldPresence(options, field)) { // Fields where we can't delegate to the regular setter because it doesn't // accept "undefined" as an argument. printer->Print( - "$class$.prototype.clear$name$ = function() {\n" + "$class$.prototype.$clearername$ = function() {\n" " jspb.Message.set$maybeoneof$Field(this, " "$index$$maybeoneofgroup$, ", "class", GetMessagePath(options, field->containing_type()), - "name", JSGetterName(options, field), + "clearername", "clear" + JSGetterName(options, field), "maybeoneof", (field->containing_oneof() ? "Oneof" : ""), "maybeoneofgroup", (field->containing_oneof() ? (", " + JSOneofArray(options, field)) : ""), "index", JSFieldIndex(field)); + printer->Annotate("clearername", field); printer->Print( "$clearedvalue$);$returnvalue$\n" "};\n" @@ -2644,14 +2753,15 @@ void Generator::GenerateClassField(const GeneratorOptions& options, " * Returns whether this field is set.\n" " * @return {!boolean}\n" " */\n" - "$class$.prototype.has$name$ = function() {\n" + "$class$.prototype.$hasername$ = function() {\n" " return jspb.Message.getField(this, $index$) != null;\n" "};\n" "\n" "\n", "class", GetMessagePath(options, field->containing_type()), - "name", JSGetterName(options, field), + "hasername", "has" + JSGetterName(options, field), "index", JSFieldIndex(field)); + printer->Annotate("hasername", field); } } @@ -2663,13 +2773,14 @@ void Generator::GenerateRepeatedPrimitiveHelperMethods( " * @param {!$optionaltype$} value\n" " * @param {number=} opt_index\n" " */\n" - "$class$.prototype.add$name$ = function(value, opt_index) {\n" + "$class$.prototype.$addername$ = function(value, opt_index) {\n" " jspb.Message.addToRepeatedField(this, $index$", - "class", GetMessagePath(options, field->containing_type()), - "name", JSGetterName(options, field, BYTES_DEFAULT, - /* drop_list = */ true), + "class", GetMessagePath(options, field->containing_type()), "addername", + "add" + JSGetterName(options, field, BYTES_DEFAULT, + /* drop_list = */ true), "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "index", JSFieldIndex(field)); + printer->Annotate("addername", field); printer->Print( "$oneofgroup$, $type$value$rptvalueinit$$typeclose$, opt_index);\n" "};\n" @@ -2727,7 +2838,7 @@ void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options, "so that it\n" " * works in OPTIMIZED mode.\n" " *\n" - " * @type {!Object.<number, jspb.ExtensionFieldInfo>}\n" + " * @type {!Object<number, jspb.ExtensionFieldInfo>}\n" " */\n" "$class$.extensions = {};\n" "\n", @@ -2748,7 +2859,7 @@ void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options, "so that it\n" " * works in OPTIMIZED mode.\n" " *\n" - " * @type {!Object.<number, jspb.ExtensionFieldBinaryInfo>}\n" + " * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}\n" " */\n" "$class$.extensionsBinary = {};\n" "\n", @@ -2910,6 +3021,7 @@ void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options, " * format), writing to the given BinaryWriter.\n" " * @param {!$class$} message\n" " * @param {!jspb.BinaryWriter} writer\n" + " * @suppress {unusedLocalVariables} f is only used for nested messages\n" " */\n" "$class$.serializeBinaryToWriter = function(message, " "writer) {\n" @@ -2982,7 +3094,13 @@ void Generator::GenerateClassSerializeBinaryField( case FieldDescriptor::CPPTYPE_INT64: case FieldDescriptor::CPPTYPE_UINT32: case FieldDescriptor::CPPTYPE_UINT64: { - { + if (IsIntegralFieldWithStringJSType(field)) { + // We can use `parseInt` here even though it will not be precise for + // 64-bit quantities because we are only testing for zero/nonzero, + // and JS numbers (64-bit floating point values, i.e., doubles) are + // integer-precise in the range that includes zero. + printer->Print(" if (parseInt(f, 10) !== 0) {\n"); + } else { printer->Print(" if (f !== 0) {\n"); } break; @@ -3060,8 +3178,10 @@ void Generator::GenerateEnum(const GeneratorOptions& options, "/**\n" " * @enum {number}\n" " */\n" - "$name$ = {\n", - "name", GetEnumPath(options, enumdesc)); + "$enumprefix$$name$ = {\n", + "enumprefix", GetEnumPathPrefix(options, enumdesc), + "name", enumdesc->name()); + printer->Annotate("name", enumdesc); for (int i = 0; i < enumdesc->value_count(); i++) { const EnumValueDescriptor* value = enumdesc->value(i); @@ -3070,6 +3190,7 @@ void Generator::GenerateEnum(const GeneratorOptions& options, "name", ToEnumCase(value->name()), "value", SimpleItoa(value->number()), "comma", (i == enumdesc->value_count() - 1) ? "" : ","); + printer->Annotate("name", value); } printer->Print( @@ -3090,7 +3211,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options, "/**\n" " * A tuple of {field number, class constructor} for the extension\n" " * field named `$name$`.\n" - " * @type {!jspb.ExtensionFieldInfo.<$extensionType$>}\n" + " * @type {!jspb.ExtensionFieldInfo<$extensionType$>}\n" " */\n" "$class$.$name$ = new jspb.ExtensionFieldInfo(\n", "name", JSObjectFieldName(options, field), @@ -3209,6 +3330,12 @@ bool GeneratorOptions::ParseFromOptions( return false; } one_output_file_per_input_file = true; + } else if (options[i].first == "annotate_code") { + if (!options[i].second.empty()) { + *error = "Unexpected option value for annotate_code"; + return false; + } + annotate_code = true; } else { // Assume any other option is an output directory, as long as it is a bare // `key` rather than a `key=value` option. @@ -3306,7 +3433,8 @@ void Generator::GenerateFile(const GeneratorOptions& options, printer->Print( "var $alias$ = require('$file$');\n", "alias", ModuleAlias(name), - "file", GetRootPath(file->name(), name) + GetJSFilename(options, name)); + "file", + GetRootPath(file->name(), name) + GetJSFilename(options, name)); } } @@ -3508,16 +3636,24 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files, options.output_dir + "/" + GetJSFilename(options, file->name()); google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); GOOGLE_CHECK(output.get()); - io::Printer printer(output.get(), '$'); + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( + &annotations); + io::Printer printer(output.get(), '$', + options.annotate_code ? &annotation_collector : NULL); + GenerateFile(options, &printer, file); if (printer.failed()) { return false; } + + if (options.annotate_code) { + EmbedCodeAnnotations(annotations, &printer); + } } } - return true; } diff --git a/src/google/protobuf/compiler/js/js_generator.h b/src/google/protobuf/compiler/js/js_generator.h index 6e932d7f..3cc60e22 100755 --- a/src/google/protobuf/compiler/js/js_generator.h +++ b/src/google/protobuf/compiler/js/js_generator.h @@ -79,7 +79,8 @@ struct GeneratorOptions { library(""), error_on_name_conflict(false), extension(".js"), - one_output_file_per_input_file(false) {} + one_output_file_per_input_file(false), + annotate_code(false) {} bool ParseFromOptions( const std::vector< std::pair< string, string > >& options, @@ -118,6 +119,9 @@ struct GeneratorOptions { string extension; // Create a separate output file for each input file? bool one_output_file_per_input_file; + // If true, we should build .meta files that contain annotations for + // generated code. See GeneratedCodeInfo in descriptor.proto. + bool annotate_code; }; // CodeGenerator implementation which generates a JavaScript source file and diff --git a/src/google/protobuf/compiler/js/well_known_types/any.js b/src/google/protobuf/compiler/js/well_known_types/any.js index 22f18919..d7ca6e3a 100644 --- a/src/google/protobuf/compiler/js/well_known_types/any.js +++ b/src/google/protobuf/compiler/js/well_known_types/any.js @@ -69,7 +69,7 @@ proto.google.protobuf.Any.prototype.pack = function(serialized, name, * the binary data properly. * @param {string} name The expected type name of this message object. * @return {?T} If the name matched the expected name, returns the deserialized - * object, otherwise returns undefined. + * object, otherwise returns null. */ proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) { if (this.getTypeName() == name) { diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index 0ddb99e5..7719ec3d 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -40,6 +40,7 @@ #endif #include <vector> + #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/logging.h> @@ -52,16 +53,24 @@ #include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/descriptor.h> +#include <google/protobuf/text_format.h> #include <google/protobuf/stubs/substitute.h> #include <gtest/gtest.h> +#ifdef major +#undef major +#endif +#ifdef minor +#undef minor +#endif + namespace google { namespace protobuf { namespace compiler { // Returns the list of the names of files in all_files in the form of a // comma-separated string. -string CommaSeparatedList(const std::vector<const FileDescriptor*> all_files) { +string CommaSeparatedList(const std::vector<const FileDescriptor*>& all_files) { std::vector<string> names; for (size_t i = 0; i < all_files.size(); i++) { names.push_back(all_files[i]->name()); @@ -129,11 +138,48 @@ void MockCodeGenerator::ExpectGenerated( } } +namespace { +void CheckSingleAnnotation(const string& expected_file, + const string& expected_text, + const string& file_content, + const GeneratedCodeInfo::Annotation& annotation) { + EXPECT_EQ(expected_file, annotation.source_file()); + ASSERT_GE(file_content.size(), annotation.begin()); + ASSERT_GE(file_content.size(), annotation.end()); + ASSERT_LE(annotation.begin(), annotation.end()); + EXPECT_EQ(expected_text.size(), annotation.end() - annotation.begin()); + EXPECT_EQ(expected_text, + file_content.substr(annotation.begin(), expected_text.size())); +} +} // anonymous namespace + +void MockCodeGenerator::CheckGeneratedAnnotations( + const string& name, const string& file, const string& output_directory) { + string file_content; + GOOGLE_CHECK_OK( + File::GetContents(output_directory + "/" + GetOutputFileName(name, file), + &file_content, true)); + string meta_content; + GOOGLE_CHECK_OK(File::GetContents( + output_directory + "/" + GetOutputFileName(name, file) + ".meta", + &meta_content, true)); + GeneratedCodeInfo annotations; + GOOGLE_CHECK(TextFormat::ParseFromString(meta_content, &annotations)); + ASSERT_EQ(3, annotations.annotation_size()); + CheckSingleAnnotation("first_annotation", "first", file_content, + annotations.annotation(0)); + CheckSingleAnnotation("second_annotation", "second", file_content, + annotations.annotation(1)); + CheckSingleAnnotation("third_annotation", "third", file_content, + annotations.annotation(2)); +} + bool MockCodeGenerator::Generate( const FileDescriptor* file, const string& parameter, GeneratorContext* context, string* error) const { + bool annotate = false; for (int i = 0; i < file->message_type_count(); i++) { if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) { string command = StripPrefixString(file->message_type(i)->name(), @@ -162,6 +208,8 @@ bool MockCodeGenerator::Generate( std::cerr << "Saw json_name: " << field_descriptor_proto.has_json_name() << std::endl; abort(); + } else if (command == "Annotate") { + annotate = true; } else if (command == "ShowVersionNumber") { Version compiler_version; context->GetCompilerVersion(&compiler_version); @@ -212,16 +260,40 @@ bool MockCodeGenerator::Generate( google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output( context->Open(GetOutputFileName(name_, file))); - io::Printer printer(output.get(), '$'); - printer.PrintRaw(GetOutputFileContent(name_, parameter, - file, context)); + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( + &annotations); + io::Printer printer(output.get(), '$', + annotate ? &annotation_collector : NULL); + printer.PrintRaw(GetOutputFileContent(name_, parameter, file, context)); + string annotate_suffix = "_annotation"; + if (annotate) { + printer.Print("$p$", "p", "first"); + printer.Annotate("p", "first" + annotate_suffix); + } printer.PrintRaw(kFirstInsertionPoint); + if (annotate) { + printer.Print("$p$", "p", "second"); + printer.Annotate("p", "second" + annotate_suffix); + } printer.PrintRaw(kSecondInsertionPoint); + if (annotate) { + printer.Print("$p$", "p", "third"); + printer.Annotate("p", "third" + annotate_suffix); + } if (printer.failed()) { *error = "MockCodeGenerator detected write error."; return false; } + if (annotate) { + google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> meta_output( + context->Open(GetOutputFileName(name_, file) + ".meta")); + if (!TextFormat::Print(annotations, meta_output.get())) { + *error = "MockCodeGenerator couldn't write .meta"; + return false; + } + } } return true; diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h index e1665f88..cdd9138c 100644 --- a/src/google/protobuf/compiler/mock_code_generator.h +++ b/src/google/protobuf/compiler/mock_code_generator.h @@ -68,6 +68,8 @@ namespace compiler { // printing "Saw message type MockCodeGenerator_HasSourceCodeInfo: FOO." to // stderr, where FOO is "1" if the supplied FileDescriptorProto has source // code info, and "0" otherwise. +// MockCodeGenerator_Annotate: Generate() will add annotations to its output +// that can later be verified with CheckGeneratedAnnotations. class MockCodeGenerator : public CodeGenerator { public: MockCodeGenerator(const string& name); @@ -88,6 +90,12 @@ class MockCodeGenerator : public CodeGenerator { const string& parsed_file_list, const string& output_directory); + // Checks that the correct text ranges were annotated by the + // MockCodeGenerator_Annotate directive. + static void CheckGeneratedAnnotations(const string& name, + const string& file, + const string& output_directory); + // Get the name of the file which would be written by the given generator. static string GetOutputFileName(const string& generator_name, const FileDescriptor* file); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc index 02d60b3e..978e985c 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc @@ -149,7 +149,7 @@ void EnumGenerator::GenerateSource(io::Printer* printer) { printer->Print( "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n" - " static GPBEnumDescriptor *descriptor = NULL;\n" + " static _Atomic(GPBEnumDescriptor*) descriptor = nil;\n" " if (!descriptor) {\n", "name", name_); @@ -192,7 +192,8 @@ void EnumGenerator::GenerateSource(io::Printer* printer) { "extraTextFormatInfo", CEscape(text_format_decode_data.Data())); } printer->Print( - " if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {\n" + " GPBEnumDescriptor *expected = nil;\n" + " if (!atomic_compare_exchange_strong(&descriptor, &expected, worker)) {\n" " [worker release];\n" " }\n" " }\n" diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.h b/src/google/protobuf/compiler/objectivec/objectivec_enum.h index 0b41cf73..f52e9e68 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.h @@ -59,8 +59,8 @@ class EnumGenerator { private: const EnumDescriptor* descriptor_; - vector<const EnumValueDescriptor*> base_values_; - vector<const EnumValueDescriptor*> all_values_; + std::vector<const EnumValueDescriptor*> base_values_; + std::vector<const EnumValueDescriptor*> all_values_; const string name_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc index 7a774a09..8899a13a 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc @@ -46,7 +46,7 @@ namespace objectivec { namespace { void SetEnumVariables(const FieldDescriptor* descriptor, - map<string, string>* variables) { + std::map<string, string>* variables) { string type = EnumName(descriptor->enum_type()); (*variables)["storage_type"] = type; // For non repeated fields, if it was defined in a different file, the @@ -118,7 +118,7 @@ void EnumFieldGenerator::GenerateCFunctionImplementations( } void EnumFieldGenerator::DetermineForwardDeclarations( - set<string>* fwd_decls) const { + std::set<string>* fwd_decls) const { SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls); // If it is an enum defined in a different file, then we'll need a forward // declaration for it. When it is in our file, all the enums are output diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h index 946faa81..ae56c069 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h @@ -47,7 +47,7 @@ class EnumFieldGenerator : public SingleFieldGenerator { public: virtual void GenerateCFunctionDeclarations(io::Printer* printer) const; virtual void GenerateCFunctionImplementations(io::Printer* printer) const; - virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const; + virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const; protected: EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc index 73e4b86e..b788d0a3 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc @@ -59,7 +59,7 @@ ExtensionGenerator::ExtensionGenerator(const string& root_class_name, ExtensionGenerator::~ExtensionGenerator() {} void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { - map<string, string> vars; + std::map<string, string> vars; vars["method_name"] = method_name_; SourceLocation location; if (descriptor_->GetSourceLocation(&location)) { @@ -77,7 +77,7 @@ void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { void ExtensionGenerator::GenerateStaticVariablesInitialization( io::Printer* printer) { - map<string, string> vars; + std::map<string, string> vars; vars["root_class_and_method_name"] = root_class_and_method_name_; vars["extended_type"] = ClassName(descriptor_->containing_type()); vars["number"] = SimpleItoa(descriptor_->number()); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc index 9f7e84f2..b6123fad 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc @@ -49,7 +49,7 @@ namespace objectivec { namespace { void SetCommonFieldVariables(const FieldDescriptor* descriptor, - map<string, string>* variables) { + std::map<string, string>* variables) { string camel_case_name = FieldName(descriptor); string raw_field_name; if (descriptor->type() == FieldDescriptor::TYPE_GROUP) { @@ -178,7 +178,7 @@ void FieldGenerator::GenerateCFunctionImplementations( } void FieldGenerator::DetermineForwardDeclarations( - set<string>* fwd_decls) const { + std::set<string>* fwd_decls) const { // Nothing } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.h b/src/google/protobuf/compiler/objectivec/objectivec_field.h index a3a4b1b6..6bd5db2e 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.h @@ -67,7 +67,7 @@ class FieldGenerator { virtual void GenerateCFunctionImplementations(io::Printer* printer) const; // Exposed for subclasses, should always call it on the parent class also. - virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const; + virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const; // Used during generation, not intended to be extended by subclasses. void GenerateFieldDescription( @@ -100,7 +100,7 @@ class FieldGenerator { virtual bool WantsHasProperty(void) const = 0; const FieldDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index 7ad127bb..6f80a0de 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -56,6 +56,20 @@ const int32 GOOGLE_PROTOBUF_OBJC_VERSION = 30002; const char* kHeaderExtension = ".pbobjc.h"; +// Checks if a message contains any enums definitions (on the message or +// a nested message under it). +bool MessageContainsEnums(const Descriptor* message) { + if (message->enum_type_count() > 0) { + return true; + } + for (int i = 0; i < message->nested_type_count(); i++) { + if (MessageContainsEnums(message->nested_type(i))) { + return true; + } + } + return false; +} + // Checks if a message contains any extension definitions (on the message or // a nested message under it). bool MessageContainsExtensions(const Descriptor* message) { @@ -70,6 +84,20 @@ bool MessageContainsExtensions(const Descriptor* message) { return false; } +// Checks if the file contains any enum definitions (at the root or +// nested under a message). +bool FileContainsEnums(const FileDescriptor* file) { + if (file->enum_type_count() > 0) { + return true; + } + for (int i = 0; i < file->message_type_count(); i++) { + if (MessageContainsEnums(file->message_type(i))) { + return true; + } + } + return false; +} + // Checks if the file contains any extensions definitions (at the root or // nested under a message). bool FileContainsExtensions(const FileDescriptor* file) { @@ -88,9 +116,9 @@ bool FileContainsExtensions(const FileDescriptor* file) { // deps as visited and prunes them from the needed files list. void PruneFileAndDepsMarkingAsVisited( const FileDescriptor* file, - vector<const FileDescriptor*>* files, - set<const FileDescriptor*>* files_visited) { - vector<const FileDescriptor*>::iterator iter = + std::vector<const FileDescriptor*>* files, + std::set<const FileDescriptor*>* files_visited) { + std::vector<const FileDescriptor*>::iterator iter = std::find(files->begin(), files->end(), file); if (iter != files->end()) { files->erase(iter); @@ -104,8 +132,8 @@ void PruneFileAndDepsMarkingAsVisited( // Helper for CollectMinimalFileDepsContainingExtensions. void CollectMinimalFileDepsContainingExtensionsWorker( const FileDescriptor* file, - vector<const FileDescriptor*>* files, - set<const FileDescriptor*>* files_visited) { + std::vector<const FileDescriptor*>* files, + std::set<const FileDescriptor*>* files_visited) { if (files_visited->find(file) != files_visited->end()) { return; } @@ -137,8 +165,8 @@ void CollectMinimalFileDepsContainingExtensionsWorker( // specifically). void CollectMinimalFileDepsContainingExtensions( const FileDescriptor* file, - vector<const FileDescriptor*>* files) { - set<const FileDescriptor*> files_visited; + std::vector<const FileDescriptor*>* files) { + std::set<const FileDescriptor*> files_visited; for (int i = 0; i < file->dependency_count(); i++) { const FileDescriptor* dep = file->dependency(i); CollectMinimalFileDepsContainingExtensionsWorker(dep, files, @@ -229,12 +257,12 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { "CF_EXTERN_C_BEGIN\n" "\n"); - set<string> fwd_decls; - for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); + std::set<string> fwd_decls; + for (std::vector<MessageGenerator *>::iterator iter = message_generators_.begin(); iter != message_generators_.end(); ++iter) { (*iter)->DetermineForwardDeclarations(&fwd_decls); } - for (set<string>::const_iterator i(fwd_decls.begin()); + for (std::set<string>::const_iterator i(fwd_decls.begin()); i != fwd_decls.end(); ++i) { printer->Print("$value$;\n", "value", *i); } @@ -247,12 +275,12 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { "\n"); // need to write out all enums first - for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin(); + for (std::vector<EnumGenerator *>::iterator iter = enum_generators_.begin(); iter != enum_generators_.end(); ++iter) { (*iter)->GenerateHeader(printer); } - for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); + for (std::vector<MessageGenerator *>::iterator iter = message_generators_.begin(); iter != message_generators_.end(); ++iter) { (*iter)->GenerateEnumHeader(printer); } @@ -283,7 +311,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { "@interface $root_class_name$ (DynamicMethods)\n", "root_class_name", root_class_name_); - for (vector<ExtensionGenerator *>::iterator iter = + for (std::vector<ExtensionGenerator *>::iterator iter = extension_generators_.begin(); iter != extension_generators_.end(); ++iter) { (*iter)->GenerateMembersHeader(printer); @@ -292,7 +320,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { printer->Print("@end\n\n"); } // extension_generators_.size() > 0 - for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); + for (std::vector<MessageGenerator *>::iterator iter = message_generators_.begin(); iter != message_generators_.end(); ++iter) { (*iter)->GenerateMessageHeader(printer); } @@ -311,7 +339,14 @@ void FileGenerator::GenerateSource(io::Printer *printer) { // #import the runtime support. PrintFileRuntimePreamble(printer, "GPBProtocolBuffers_RuntimeSupport.h"); - vector<const FileDescriptor*> deps_with_extensions; + // Enums use atomic in the generated code, so add the system import as needed. + if (FileContainsEnums(file_)) { + printer->Print( + "#import <stdatomic.h>\n" + "\n"); + } + + std::vector<const FileDescriptor*> deps_with_extensions; CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions); { @@ -325,7 +360,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { // #import the headers for anything that a plain dependency of this proto // file (that means they were just an include, not a "public" include). - set<string> public_import_names; + std::set<string> public_import_names; for (int i = 0; i < file_->public_dependency_count(); i++) { public_import_names.insert(file_->public_dependency(i)->name()); } @@ -341,7 +376,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { // imported so it can get merged into the root's extensions registry. // See the Note by CollectMinimalFileDepsContainingExtensions before // changing this. - for (vector<const FileDescriptor *>::iterator iter = + for (std::vector<const FileDescriptor *>::iterator iter = deps_with_extensions.begin(); iter != deps_with_extensions.end(); ++iter) { if (!IsDirectDependency(*iter, file_)) { @@ -353,7 +388,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { } bool includes_oneof = false; - for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); + for (std::vector<MessageGenerator *>::iterator iter = message_generators_.begin(); iter != message_generators_.end(); ++iter) { if ((*iter)->IncludesOneOfDefinition()) { includes_oneof = true; @@ -406,12 +441,12 @@ void FileGenerator::GenerateSource(io::Printer *printer) { printer->Print( "static GPBExtensionDescription descriptions[] = {\n"); printer->Indent(); - for (vector<ExtensionGenerator *>::iterator iter = + for (std::vector<ExtensionGenerator *>::iterator iter = extension_generators_.begin(); iter != extension_generators_.end(); ++iter) { (*iter)->GenerateStaticVariablesInitialization(printer); } - for (vector<MessageGenerator *>::iterator iter = + for (std::vector<MessageGenerator *>::iterator iter = message_generators_.begin(); iter != message_generators_.end(); ++iter) { (*iter)->GenerateStaticVariablesInitialization(printer); @@ -435,7 +470,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { } else { printer->Print( "// Merge in the imports (direct or indirect) that defined extensions.\n"); - for (vector<const FileDescriptor *>::iterator iter = + for (std::vector<const FileDescriptor *>::iterator iter = deps_with_extensions.begin(); iter != deps_with_extensions.end(); ++iter) { const string root_class_name(FileClassName((*iter))); @@ -468,7 +503,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { // File descriptor only needed if there are messages to use it. if (message_generators_.size() > 0) { - map<string, string> vars; + std::map<string, string> vars; vars["root_class_name"] = root_class_name_; vars["package"] = file_->package(); vars["objc_prefix"] = FileClassPrefix(file_); @@ -511,11 +546,11 @@ void FileGenerator::GenerateSource(io::Printer *printer) { "\n"); } - for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin(); + for (std::vector<EnumGenerator *>::iterator iter = enum_generators_.begin(); iter != enum_generators_.end(); ++iter) { (*iter)->GenerateSource(printer); } - for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); + for (std::vector<MessageGenerator *>::iterator iter = message_generators_.begin(); iter != message_generators_.end(); ++iter) { (*iter)->GenerateSource(printer); } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.h b/src/google/protobuf/compiler/objectivec/objectivec_file.h index a60a6885..9c3f0071 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.h @@ -67,9 +67,9 @@ class FileGenerator { const FileDescriptor* file_; string root_class_name_; - vector<EnumGenerator*> enum_generators_; - vector<MessageGenerator*> message_generators_; - vector<ExtensionGenerator*> extension_generators_; + std::vector<EnumGenerator*> enum_generators_; + std::vector<MessageGenerator*> message_generators_; + std::vector<ExtensionGenerator*> extension_generators_; const Options options_; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index 36407467..760ff481 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -57,7 +57,7 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file, return false; } -bool ObjectiveCGenerator::GenerateAll(const vector<const FileDescriptor*>& files, +bool ObjectiveCGenerator::GenerateAll(const std::vector<const FileDescriptor*>& files, const string& parameter, GeneratorContext* context, string* error) const { @@ -71,7 +71,7 @@ bool ObjectiveCGenerator::GenerateAll(const vector<const FileDescriptor*>& files Options generation_options; - vector<pair<string, string> > options; + std::vector<std::pair<string, string> > options; ParseGeneratorParameter(parameter, &options); for (int i = 0; i < options.size(); i++) { if (options[i].first == "expected_prefixes_path") { diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.h b/src/google/protobuf/compiler/objectivec/objectivec_generator.h index b1723318..3e43f732 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.h @@ -56,7 +56,7 @@ class LIBPROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator { const string& parameter, GeneratorContext* context, string* error) const; - bool GenerateAll(const vector<const FileDescriptor*>& files, + bool GenerateAll(const std::vector<const FileDescriptor*>& files, const string& parameter, GeneratorContext* context, string* error) const; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 1ea2676a..5727dd56 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -28,9 +28,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifdef _MSC_VER -#include <io.h> -#else +#ifndef _MSC_VER #include <unistd.h> #endif #include <climits> @@ -49,8 +47,10 @@ #include <google/protobuf/io/printer.h> #include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/io_win32.h> #include <google/protobuf/stubs/strutil.h> + // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // error cases, so it seems to be ok to use as a back door for errors. @@ -59,6 +59,16 @@ namespace protobuf { namespace compiler { namespace objectivec { +// <io.h> is transitively included in this file. Import the functions explicitly +// in this port namespace to avoid ambiguous definition. +namespace posix { +#ifdef _WIN32 +using ::google::protobuf::internal::win32::open; +#else +using ::open; +#endif +} // namespace port + Options::Options() { // Default is the value of the env for the package prefixes. const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES"); @@ -90,7 +100,7 @@ bool ascii_isnewline(char c) { // Do not expose this outside of helpers, stick to having functions for specific // cases (ClassName(), FieldName()), so there is always consistent suffix rules. string UnderscoresToCamelCase(const string& input, bool first_capitalized) { - vector<string> values; + std::vector<string> values; string current; bool last_char_was_number = false; @@ -131,7 +141,7 @@ string UnderscoresToCamelCase(const string& input, bool first_capitalized) { string result; bool first_segment_forces_upper = false; - for (vector<string>::iterator i = values.begin(); i != values.end(); ++i) { + for (std::vector<string>::iterator i = values.begin(); i != values.end(); ++i) { string value = *i; bool all_upper = (kUpperSegments.count(value) > 0); if (all_upper && (result.length() == 0)) { @@ -196,7 +206,7 @@ const char* const kReservedWordList[] = { // method declared in protos. The main cases are methods // that take no arguments, or setFoo:/hasFoo: type methods. "clear", "data", "delimitedData", "descriptor", "extensionRegistry", - "extensionsCurrentlySet", "isInitialized", "serializedSize", + "extensionsCurrentlySet", "initialized", "isInitialized", "serializedSize", "sortedExtensionsInUse", "unknownFields", // MacTypes.h names @@ -854,7 +864,7 @@ bool HasNonZeroDefaultValue(const FieldDescriptor* field) { } string BuildFlagsString(const FlagType flag_type, - const vector<string>& strings) { + const std::vector<string>& strings) { if (strings.size() == 0) { return GetZeroEnumNameForFlagType(flag_type); } else if (strings.size() == 1) { @@ -876,7 +886,7 @@ string BuildCommentsString(const SourceLocation& location, const string& comments = location.leading_comments.empty() ? location.trailing_comments : location.leading_comments; - vector<string> lines; + std::vector<string> lines; SplitStringAllowEmpty(comments, "\n", &lines); while (!lines.empty() && lines.back().empty()) { lines.pop_back(); @@ -980,13 +990,13 @@ namespace { class ExpectedPrefixesCollector : public LineConsumer { public: - ExpectedPrefixesCollector(map<string, string>* inout_package_to_prefix_map) + ExpectedPrefixesCollector(std::map<string, string>* inout_package_to_prefix_map) : prefix_map_(inout_package_to_prefix_map) {} virtual bool ConsumeLine(const StringPiece& line, string* out_error); private: - map<string, string>* prefix_map_; + std::map<string, string>* prefix_map_; }; bool ExpectedPrefixesCollector::ConsumeLine( @@ -1009,7 +1019,7 @@ bool ExpectedPrefixesCollector::ConsumeLine( } bool LoadExpectedPackagePrefixes(const Options &generation_options, - map<string, string>* prefix_map, + std::map<string, string>* prefix_map, string* out_error) { if (generation_options.expected_prefixes_path.empty()) { return true; @@ -1023,7 +1033,7 @@ bool LoadExpectedPackagePrefixes(const Options &generation_options, bool ValidateObjCClassPrefix( const FileDescriptor* file, const string& expected_prefixes_path, - const map<string, string>& expected_package_prefixes, + const std::map<string, string>& expected_package_prefixes, string* out_error) { const string prefix = file->options().objc_class_prefix(); const string package = file->package(); @@ -1033,7 +1043,7 @@ bool ValidateObjCClassPrefix( // Check: Error - See if there was an expected prefix for the package and // report if it doesn't match (wrong or missing). - map<string, string>::const_iterator package_match = + std::map<string, string>::const_iterator package_match = expected_package_prefixes.find(package); if (package_match != expected_package_prefixes.end()) { // There was an entry, and... @@ -1082,7 +1092,7 @@ bool ValidateObjCClassPrefix( // Look for any other package that uses the same prefix. string other_package_for_prefix; - for (map<string, string>::const_iterator i = expected_package_prefixes.begin(); + for (std::map<string, string>::const_iterator i = expected_package_prefixes.begin(); i != expected_package_prefixes.end(); ++i) { if (i->second == prefix) { other_package_for_prefix = i->first; @@ -1146,11 +1156,11 @@ bool ValidateObjCClassPrefix( } // namespace -bool ValidateObjCClassPrefixes(const vector<const FileDescriptor*>& files, +bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, const Options& generation_options, string* out_error) { // Load the expected package prefixes, if available, to validate against. - map<string, string> expected_package_prefixes; + std::map<string, string> expected_package_prefixes; if (!LoadExpectedPackagePrefixes(generation_options, &expected_package_prefixes, out_error)) { @@ -1177,7 +1187,7 @@ TextFormatDecodeData::~TextFormatDecodeData() { } void TextFormatDecodeData::AddString(int32 key, const string& input_for_decode, const string& desired_output) { - for (vector<DataEntry>::const_iterator i = entries_.begin(); + for (std::vector<DataEntry>::const_iterator i = entries_.begin(); i != entries_.end(); ++i) { if (i->first == key) { std::cerr << "error: duplicate key (" << key @@ -1201,7 +1211,7 @@ string TextFormatDecodeData::Data() const { io::CodedOutputStream output_stream(&data_outputstream); output_stream.WriteVarint32(num_entries()); - for (vector<DataEntry>::const_iterator i = entries_.begin(); + for (std::vector<DataEntry>::const_iterator i = entries_.begin(); i != entries_.end(); ++i) { output_stream.WriteVarint32(i->first); output_stream.WriteString(i->second); @@ -1464,7 +1474,7 @@ bool ParseSimpleFile( const string& path, LineConsumer* line_consumer, string* out_error) { int fd; do { - fd = open(path.c_str(), O_RDONLY); + fd = posix::open(path.c_str(), O_RDONLY); } while (fd < 0 && errno == EINTR); if (fd < 0) { *out_error = @@ -1519,7 +1529,7 @@ void ImportWriter::AddFile(const FileDescriptor* file, ParseFrameworkMappings(); } - map<string, string>::iterator proto_lookup = + std::map<string, string>::iterator proto_lookup = proto_file_to_framework_name_.find(file->name()); if (proto_lookup != proto_file_to_framework_name_.end()) { other_framework_imports_.push_back( @@ -1551,7 +1561,7 @@ void ImportWriter::Print(io::Printer* printer) const { printer->Print( "#if $cpp_symbol$\n", "cpp_symbol", cpp_symbol); - for (vector<string>::const_iterator iter = protobuf_framework_imports_.begin(); + for (std::vector<string>::const_iterator iter = protobuf_framework_imports_.begin(); iter != protobuf_framework_imports_.end(); ++iter) { printer->Print( " #import <$framework_name$/$header$>\n", @@ -1560,7 +1570,7 @@ void ImportWriter::Print(io::Printer* printer) const { } printer->Print( "#else\n"); - for (vector<string>::const_iterator iter = protobuf_non_framework_imports_.begin(); + for (std::vector<string>::const_iterator iter = protobuf_non_framework_imports_.begin(); iter != protobuf_non_framework_imports_.end(); ++iter) { printer->Print( " #import \"$header$\"\n", @@ -1577,10 +1587,10 @@ void ImportWriter::Print(io::Printer* printer) const { printer->Print("\n"); } - for (vector<string>::const_iterator iter = other_framework_imports_.begin(); + for (std::vector<string>::const_iterator iter = other_framework_imports_.begin(); iter != other_framework_imports_.end(); ++iter) { printer->Print( - " #import <$header$>\n", + "#import <$header$>\n", "header", *iter); } @@ -1592,10 +1602,10 @@ void ImportWriter::Print(io::Printer* printer) const { printer->Print("\n"); } - for (vector<string>::const_iterator iter = other_imports_.begin(); + for (std::vector<string>::const_iterator iter = other_imports_.begin(); iter != other_imports_.end(); ++iter) { printer->Print( - " #import \"$header$\"\n", + "#import \"$header$\"\n", "header", *iter); } } @@ -1640,7 +1650,7 @@ bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( StringPiece proto_file(proto_file_list, start, offset - start); StringPieceTrimWhitespace(&proto_file); if (proto_file.size() != 0) { - map<string, string>::iterator existing_entry = + std::map<string, string>::iterator existing_entry = map_->find(proto_file.ToString()); if (existing_entry != map_->end()) { std::cerr << "warning: duplicate proto file reference, replacing framework entry for '" diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index c99262a1..f74607c8 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -190,7 +190,7 @@ string LIBPROTOC_EXPORT GPBGenericValueFieldName(const FieldDescriptor* field); string LIBPROTOC_EXPORT DefaultValue(const FieldDescriptor* field); bool LIBPROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field); -string LIBPROTOC_EXPORT BuildFlagsString(const FlagType type, const vector<string>& strings); +string LIBPROTOC_EXPORT BuildFlagsString(const FlagType type, const std::vector<string>& strings); // Builds HeaderDoc/appledoc style comments out of the comments in the .proto // file. @@ -210,7 +210,7 @@ bool LIBPROTOC_EXPORT IsProtobufLibraryBundledProtoFile(const FileDescriptor* fi // Checks the prefix for the given files and outputs any warnings as needed. If // there are flat out errors, then out_error is filled in with the first error // and the result is false. -bool LIBPROTOC_EXPORT ValidateObjCClassPrefixes(const vector<const FileDescriptor*>& files, +bool LIBPROTOC_EXPORT ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, const Options& generation_options, string* out_error); @@ -233,7 +233,7 @@ class LIBPROTOC_EXPORT TextFormatDecodeData { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormatDecodeData); typedef std::pair<int32, string> DataEntry; - vector<DataEntry> entries_; + std::vector<DataEntry> entries_; }; // Helper for parsing simple files. @@ -262,26 +262,26 @@ class LIBPROTOC_EXPORT ImportWriter { private: class ProtoFrameworkCollector : public LineConsumer { public: - ProtoFrameworkCollector(map<string, string>* inout_proto_file_to_framework_name) + ProtoFrameworkCollector(std::map<string, string>* inout_proto_file_to_framework_name) : map_(inout_proto_file_to_framework_name) {} virtual bool ConsumeLine(const StringPiece& line, string* out_error); private: - map<string, string>* map_; + std::map<string, string>* map_; }; void ParseFrameworkMappings(); const string generate_for_named_framework_; const string named_framework_to_proto_path_mappings_path_; - map<string, string> proto_file_to_framework_name_; + std::map<string, string> proto_file_to_framework_name_; bool need_to_parse_mapping_file_; - vector<string> protobuf_framework_imports_; - vector<string> protobuf_non_framework_imports_; - vector<string> other_framework_imports_; - vector<string> other_imports_; + std::vector<string> protobuf_framework_imports_; + std::vector<string> protobuf_non_framework_imports_; + std::vector<string> other_framework_imports_; + std::vector<string> other_imports_; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc index 0bc9dc10..bcaf5709 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -162,7 +162,7 @@ void MapFieldGenerator::FinishInitialization(void) { } void MapFieldGenerator::DetermineForwardDeclarations( - set<string>* fwd_decls) const { + std::set<string>* fwd_decls) const { RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); const FieldDescriptor* value_descriptor = descriptor_->message_type()->FindFieldByName("value"); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h index bc68a682..6664d849 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h @@ -51,7 +51,7 @@ class MapFieldGenerator : public RepeatedFieldGenerator { MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); virtual ~MapFieldGenerator(); - virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const; + virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const; private: scoped_ptr<FieldGenerator> value_field_generator_; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc index 0a554a83..f1465c3e 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -220,20 +220,20 @@ MessageGenerator::~MessageGenerator() { void MessageGenerator::GenerateStaticVariablesInitialization( io::Printer* printer) { - for (vector<ExtensionGenerator*>::iterator iter = + for (std::vector<ExtensionGenerator*>::iterator iter = extension_generators_.begin(); iter != extension_generators_.end(); ++iter) { (*iter)->GenerateStaticVariablesInitialization(printer); } - for (vector<MessageGenerator*>::iterator iter = + for (std::vector<MessageGenerator*>::iterator iter = nested_message_generators_.begin(); iter != nested_message_generators_.end(); ++iter) { (*iter)->GenerateStaticVariablesInitialization(printer); } } -void MessageGenerator::DetermineForwardDeclarations(set<string>* fwd_decls) { +void MessageGenerator::DetermineForwardDeclarations(std::set<string>* fwd_decls) { if (!IsMapEntryMessage(descriptor_)) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* fieldDescriptor = descriptor_->field(i); @@ -242,7 +242,7 @@ void MessageGenerator::DetermineForwardDeclarations(set<string>* fwd_decls) { } } - for (vector<MessageGenerator*>::iterator iter = + for (std::vector<MessageGenerator*>::iterator iter = nested_message_generators_.begin(); iter != nested_message_generators_.end(); ++iter) { (*iter)->DetermineForwardDeclarations(fwd_decls); @@ -254,7 +254,7 @@ bool MessageGenerator::IncludesOneOfDefinition() const { return true; } - for (vector<MessageGenerator*>::const_iterator iter = + for (std::vector<MessageGenerator*>::const_iterator iter = nested_message_generators_.begin(); iter != nested_message_generators_.end(); ++iter) { if ((*iter)->IncludesOneOfDefinition()) { @@ -266,12 +266,12 @@ bool MessageGenerator::IncludesOneOfDefinition() const { } void MessageGenerator::GenerateEnumHeader(io::Printer* printer) { - for (vector<EnumGenerator*>::iterator iter = enum_generators_.begin(); + for (std::vector<EnumGenerator*>::iterator iter = enum_generators_.begin(); iter != enum_generators_.end(); ++iter) { (*iter)->GenerateHeader(printer); } - for (vector<MessageGenerator*>::iterator iter = + for (std::vector<MessageGenerator*>::iterator iter = nested_message_generators_.begin(); iter != nested_message_generators_.end(); ++iter) { (*iter)->GenerateEnumHeader(printer); @@ -280,13 +280,13 @@ void MessageGenerator::GenerateEnumHeader(io::Printer* printer) { void MessageGenerator::GenerateExtensionRegistrationSource( io::Printer* printer) { - for (vector<ExtensionGenerator*>::iterator iter = + for (std::vector<ExtensionGenerator*>::iterator iter = extension_generators_.begin(); iter != extension_generators_.end(); ++iter) { (*iter)->GenerateRegistrationSource(printer); } - for (vector<MessageGenerator*>::iterator iter = + for (std::vector<MessageGenerator*>::iterator iter = nested_message_generators_.begin(); iter != nested_message_generators_.end(); ++iter) { (*iter)->GenerateExtensionRegistrationSource(printer); @@ -296,7 +296,7 @@ void MessageGenerator::GenerateExtensionRegistrationSource( void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { // This a a map entry message, just recurse and do nothing directly. if (IsMapEntryMessage(descriptor_)) { - for (vector<MessageGenerator*>::iterator iter = + for (std::vector<MessageGenerator*>::iterator iter = nested_message_generators_.begin(); iter != nested_message_generators_.end(); ++iter) { (*iter)->GenerateMessageHeader(printer); @@ -326,7 +326,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { printer->Print("};\n\n"); } - for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + for (std::vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); iter != oneof_generators_.end(); ++iter) { (*iter)->GenerateCaseEnum(printer); } @@ -345,7 +345,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { "deprecated_attribute", deprecated_attribute_, "comments", message_comments); - vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0); + std::vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0); for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); if (field->containing_oneof() != NULL) { @@ -367,7 +367,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { } if (!oneof_generators_.empty()) { - for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + for (std::vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); iter != oneof_generators_.end(); ++iter) { (*iter)->GenerateClearFunctionDeclaration(printer); } @@ -377,7 +377,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { if (descriptor_->extension_count() > 0) { printer->Print("@interface $classname$ (DynamicMethods)\n\n", "classname", class_name_); - for (vector<ExtensionGenerator*>::iterator iter = + for (std::vector<ExtensionGenerator*>::iterator iter = extension_generators_.begin(); iter != extension_generators_.end(); ++iter) { (*iter)->GenerateMembersHeader(printer); @@ -385,7 +385,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { printer->Print("@end\n\n"); } - for (vector<MessageGenerator*>::iterator iter = + for (std::vector<MessageGenerator*>::iterator iter = nested_message_generators_.begin(); iter != nested_message_generators_.end(); ++iter) { (*iter)->GenerateMessageHeader(printer); @@ -410,7 +410,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { printer->Print("@implementation $classname$\n\n", "classname", class_name_); - for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + for (std::vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); iter != oneof_generators_.end(); ++iter) { (*iter)->GeneratePropertyImplementation(printer); } @@ -425,7 +425,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { scoped_array<const FieldDescriptor*> size_order_fields( SortFieldsByStorageSize(descriptor_)); - vector<const Descriptor::ExtensionRange*> sorted_extensions; + std::vector<const Descriptor::ExtensionRange*> sorted_extensions; for (int i = 0; i < descriptor_->extension_range_count(); ++i) { sorted_extensions.push_back(descriptor_->extension_range(i)); } @@ -448,7 +448,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { sizeof_has_storage = 1; } // Tell all the fields the oneof base. - for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + for (std::vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); iter != oneof_generators_.end(); ++iter) { (*iter)->SetOneofIndexBase(sizeof_has_storage); } @@ -514,7 +514,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { " };\n"); } - map<string, string> vars; + std::map<string, string> vars; vars["classname"] = class_name_; vars["rootclassname"] = root_classname_; vars["fields"] = has_fields ? "fields" : "NULL"; @@ -548,7 +548,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { if (oneof_generators_.size() != 0) { printer->Print( " static const char *oneofs[] = {\n"); - for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + for (std::vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); iter != oneof_generators_.end(); ++iter) { printer->Print( " \"$name$\",\n", @@ -623,18 +623,18 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { .GenerateCFunctionImplementations(printer); } - for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + for (std::vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); iter != oneof_generators_.end(); ++iter) { (*iter)->GenerateClearFunctionImplementation(printer); } } - for (vector<EnumGenerator*>::iterator iter = enum_generators_.begin(); + for (std::vector<EnumGenerator*>::iterator iter = enum_generators_.begin(); iter != enum_generators_.end(); ++iter) { (*iter)->GenerateSource(printer); } - for (vector<MessageGenerator*>::iterator iter = + for (std::vector<MessageGenerator*>::iterator iter = nested_message_generators_.begin(); iter != nested_message_generators_.end(); ++iter) { (*iter)->GenerateSource(printer); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.h b/src/google/protobuf/compiler/objectivec/objectivec_message.h index 0fb78bc0..2de03f12 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.h @@ -64,7 +64,7 @@ class MessageGenerator { void GenerateMessageHeader(io::Printer* printer); void GenerateSource(io::Printer* printer); void GenerateExtensionRegistrationSource(io::Printer* printer); - void DetermineForwardDeclarations(set<string>* fwd_decls); + void DetermineForwardDeclarations(std::set<string>* fwd_decls); // Checks if the message or a nested message includes a oneof definition. bool IncludesOneOfDefinition() const; @@ -86,10 +86,10 @@ class MessageGenerator { FieldGeneratorMap field_generators_; const string class_name_; const string deprecated_attribute_; - vector<ExtensionGenerator*> extension_generators_; - vector<EnumGenerator*> enum_generators_; - vector<MessageGenerator*> nested_message_generators_; - vector<OneofGenerator*> oneof_generators_; + std::vector<ExtensionGenerator*> extension_generators_; + std::vector<EnumGenerator*> enum_generators_; + std::vector<MessageGenerator*> nested_message_generators_; + std::vector<OneofGenerator*> oneof_generators_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); }; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc index d6ccd6d1..699d25b3 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc @@ -45,7 +45,7 @@ namespace objectivec { namespace { void SetMessageVariables(const FieldDescriptor* descriptor, - map<string, string>* variables) { + std::map<string, string>* variables) { const string& message_type = ClassName(descriptor->message_type()); (*variables)["type"] = message_type; (*variables)["containing_class"] = ClassName(descriptor->containing_type()); @@ -67,7 +67,7 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, MessageFieldGenerator::~MessageFieldGenerator() {} void MessageFieldGenerator::DetermineForwardDeclarations( - set<string>* fwd_decls) const { + std::set<string>* fwd_decls) const { ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls); // Class name is already in "storage_type". fwd_decls->insert("@class " + variable("storage_type")); @@ -95,7 +95,7 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} void RepeatedMessageFieldGenerator::DetermineForwardDeclarations( - set<string>* fwd_decls) const { + std::set<string>* fwd_decls) const { RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); // Class name is already in "storage_type". fwd_decls->insert("@class " + variable("storage_type")); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h index d2dba153..50f4b6d4 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h @@ -51,7 +51,7 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator { virtual bool WantsHasProperty(void) const; public: - virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const; + virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); @@ -67,7 +67,7 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { virtual ~RepeatedMessageFieldGenerator(); public: - virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const; + virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h index 3d9df4db..ff353a6c 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h @@ -67,7 +67,7 @@ class OneofGenerator { private: const OneofDescriptor* descriptor_; - map<string, string> variables_; + std::map<string, string> variables_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OneofGenerator); }; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc index d49350f4..aa8ac324 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc @@ -118,7 +118,7 @@ const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) { } void SetPrimitiveVariables(const FieldDescriptor* descriptor, - map<string, string>* variables) { + std::map<string, string>* variables) { std::string primitive_name = PrimitiveTypeName(descriptor); (*variables)["type"] = primitive_name; (*variables)["storage_type"] = primitive_name; diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 1a409566..03d05ad4 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -664,7 +664,7 @@ bool Parser::ParseMessageDefinition( namespace { -const int kMaxExtensionRangeSentinel = -1; +const int kMaxRangeSentinel = -1; bool IsMessageSetWireFormatMessage(const DescriptorProto& message) { const MessageOptions& options = message.options(); @@ -688,12 +688,27 @@ void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) { kint32max : FieldDescriptor::kMaxNumber + 1; for (int i = 0; i < message->extension_range_size(); ++i) { - if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) { + if (message->extension_range(i).end() == kMaxRangeSentinel) { message->mutable_extension_range(i)->set_end(max_extension_number); } } } +// Modifies any reserved ranges that specified 'max' as the end of the +// reserved range, and sets them to the type-specific maximum. The actual max +// tag number can only be determined after all options have been parsed. +void AdjustReservedRangesWithMaxEndNumber(DescriptorProto* message) { + const bool is_message_set = IsMessageSetWireFormatMessage(*message); + const int max_field_number = is_message_set ? + kint32max : + FieldDescriptor::kMaxNumber + 1; + for (int i = 0; i < message->reserved_range_size(); ++i) { + if (message->reserved_range(i).end() == kMaxRangeSentinel) { + message->mutable_reserved_range(i)->set_end(max_field_number); + } + } +} + } // namespace bool Parser::ParseMessageBlock(DescriptorProto* message, @@ -717,6 +732,9 @@ bool Parser::ParseMessageBlock(DescriptorProto* message, if (message->extension_range_size() > 0) { AdjustExtensionRangesWithMaxEndNumber(message); } + if (message->reserved_range_size() > 0) { + AdjustReservedRangesWithMaxEndNumber(message); + } return true; } @@ -1429,6 +1447,8 @@ bool Parser::ParseExtensions(DescriptorProto* message, // Parse the declaration. DO(Consume("extensions")); + int old_range_size = message->extension_range_size(); + do { // Note that kExtensionRangeFieldNumber was already pushed by the parent. LocationRecorder location(extensions_location, @@ -1455,7 +1475,7 @@ bool Parser::ParseExtensions(DescriptorProto* message, // Set to the sentinel value - 1 since we increment the value below. // The actual value of the end of the range should be set with // AdjustExtensionRangesWithMaxEndNumber. - end = kMaxExtensionRangeSentinel - 1; + end = kMaxRangeSentinel - 1; } else { DO(ConsumeInteger(&end, "Expected integer.")); } @@ -1475,12 +1495,36 @@ bool Parser::ParseExtensions(DescriptorProto* message, range->set_end(end); } while (TryConsume(",")); + if (LookingAt("[")) { + LocationRecorder location( + extensions_location, + DescriptorProto::ExtensionRange::kOptionsFieldNumber); + + DO(Consume("[")); + + // Parse extension range options in the first range. + ExtensionRangeOptions* options = + message->mutable_extension_range(old_range_size)->mutable_options(); + do { + DO(ParseOption(options, location, containing_file, OPTION_ASSIGNMENT)); + } while (TryConsume(",")); + + DO(Consume("]")); + + // Then copy the extension range options to all of the other ranges we've + // parsed. + for (int i = old_range_size + 1; i < message->extension_range_size(); i++) { + message->mutable_extension_range(i)->mutable_options() + ->CopyFrom(*options); + } + } + DO(ConsumeEndOfDeclaration(";", &extensions_location)); return true; } -// This is similar to extension range parsing, except that "max" is not -// supported, and accepts field name literals. +// This is similar to extension range parsing, except that it accepts field +// name literals. bool Parser::ParseReserved(DescriptorProto* message, const LocationRecorder& message_location) { // Parse the declaration. @@ -1496,7 +1540,6 @@ bool Parser::ParseReserved(DescriptorProto* message, } } - bool Parser::ParseReservedNames(DescriptorProto* message, const LocationRecorder& parent_location) { do { @@ -1528,7 +1571,14 @@ bool Parser::ParseReservedNumbers(DescriptorProto* message, if (TryConsume("to")) { LocationRecorder end_location( location, DescriptorProto::ReservedRange::kEndFieldNumber); - DO(ConsumeInteger(&end, "Expected integer.")); + if (TryConsume("max")) { + // Set to the sentinel value - 1 since we increment the value below. + // The actual value of the end of the range should be set with + // AdjustExtensionRangesWithMaxEndNumber. + end = kMaxRangeSentinel - 1; + } else { + DO(ConsumeInteger(&end, "Expected integer.")); + } } else { LocationRecorder end_location( location, DescriptorProto::ReservedRange::kEndFieldNumber); @@ -1550,6 +1600,81 @@ bool Parser::ParseReservedNumbers(DescriptorProto* message, return true; } +bool Parser::ParseReserved(EnumDescriptorProto* message, + const LocationRecorder& message_location) { + // Parse the declaration. + DO(Consume("reserved")); + if (LookingAtType(io::Tokenizer::TYPE_STRING)) { + LocationRecorder location(message_location, + DescriptorProto::kReservedNameFieldNumber); + return ParseReservedNames(message, location); + } else { + LocationRecorder location(message_location, + DescriptorProto::kReservedRangeFieldNumber); + return ParseReservedNumbers(message, location); + } +} + +bool Parser::ParseReservedNames(EnumDescriptorProto* message, + const LocationRecorder& parent_location) { + do { + LocationRecorder location(parent_location, message->reserved_name_size()); + DO(ConsumeString(message->add_reserved_name(), "Expected enum value.")); + } while (TryConsume(",")); + DO(ConsumeEndOfDeclaration(";", &parent_location)); + return true; +} + +bool Parser::ParseReservedNumbers(EnumDescriptorProto* message, + const LocationRecorder& parent_location) { + bool first = true; + do { + LocationRecorder location(parent_location, message->reserved_range_size()); + + EnumDescriptorProto::EnumReservedRange* range = + message->add_reserved_range(); + int start, end; + io::Tokenizer::Token start_token; + { + LocationRecorder start_location( + location, EnumDescriptorProto::EnumReservedRange::kStartFieldNumber); + start_token = input_->current(); + DO(ConsumeSignedInteger(&start, (first ? + "Expected enum value or number range." : + "Expected enum number range."))); + } + + if (TryConsume("to")) { + LocationRecorder end_location( + location, EnumDescriptorProto::EnumReservedRange::kEndFieldNumber); + if (TryConsume("max")) { + // This is in the enum descriptor path, which doesn't have the message + // set duality to fix up, so it doesn't integrate with the sentinel. + + // Evaluate 'max' to INT_MAX - 1 so that incrementing to create the + // exclusive range end doesn't cause an overflow. + // Note, this prevents reserving the actual INT_MAX enum value. + end = INT_MAX; + } else { + DO(ConsumeSignedInteger(&end, "Expected integer.")); + } + } else { + LocationRecorder end_location( + location, EnumDescriptorProto::EnumReservedRange::kEndFieldNumber); + end_location.StartAt(start_token); + end_location.EndAt(start_token); + end = start; + } + + range->set_start(start); + range->set_end(end); + first = false; + } while (TryConsume(",")); + + DO(ConsumeEndOfDeclaration(";", &parent_location)); + return true; +} + bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, RepeatedPtrField<DescriptorProto>* messages, const LocationRecorder& parent_location, @@ -1730,6 +1855,8 @@ bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type, EnumDescriptorProto::kOptionsFieldNumber); return ParseOption(enum_type->mutable_options(), location, containing_file, OPTION_STATEMENT); + } else if (LookingAt("reserved")) { + return ParseReserved(enum_type, enum_location); } else { LocationRecorder location(enum_location, EnumDescriptorProto::kValueFieldNumber, enum_type->value_size()); @@ -2116,4 +2243,5 @@ void SourceLocationTable::Clear() { } // namespace compiler } // namespace protobuf + } // namespace google diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h index dd8b6586..33b4c700 100644 --- a/src/google/protobuf/compiler/parser.h +++ b/src/google/protobuf/compiler/parser.h @@ -371,6 +371,12 @@ class LIBPROTOBUF_EXPORT Parser { const LocationRecorder& parent_location); bool ParseReservedNumbers(DescriptorProto* message, const LocationRecorder& parent_location); + bool ParseReserved(EnumDescriptorProto* message, + const LocationRecorder& message_location); + bool ParseReservedNames(EnumDescriptorProto* message, + const LocationRecorder& parent_location); + bool ParseReservedNumbers(EnumDescriptorProto* message, + const LocationRecorder& parent_location); // Parse an "extend" declaration. (See also comments for // ParseMessageField().) diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index d5e31325..9b59842e 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -663,7 +663,7 @@ TEST_F(ParseMessageTest, ReservedRange) { ExpectParsesTo( "message TestMessage {\n" " required int32 foo = 1;\n" - " reserved 2, 15, 9 to 11, 3;\n" + " reserved 2, 15, 9 to 11, 3, 20 to max;\n" "}\n", "message_type {" @@ -673,6 +673,29 @@ TEST_F(ParseMessageTest, ReservedRange) { " reserved_range { start:15 end:16 }" " reserved_range { start:9 end:12 }" " reserved_range { start:3 end:4 }" + " reserved_range { start:20 end:536870912 }" + "}"); +} + +TEST_F(ParseMessageTest, ReservedRangeOnMessageSet) { + ExpectParsesTo( + "message TestMessage {\n" + " option message_set_wire_format = true;\n" + " reserved 20 to max;\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"message_set_wire_format\"" + " is_extension: false" + " }" + " identifier_value: \"true\"" + " }" + " }" + " reserved_range { start:20 end:2147483647 }" "}"); } @@ -703,6 +726,30 @@ TEST_F(ParseMessageTest, ExtensionRange) { "}"); } +TEST_F(ParseMessageTest, ExtensionRangeWithOptions) { + ExpectParsesTo( + "message TestMessage {\n" + " extensions 10 to 19 [(i) = 5];\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " extension_range {" + " start:10" + " end:20" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + "}"); +} + TEST_F(ParseMessageTest, CompoundExtensionRange) { ExpectParsesTo( "message TestMessage {\n" @@ -719,6 +766,82 @@ TEST_F(ParseMessageTest, CompoundExtensionRange) { "}"); } +TEST_F(ParseMessageTest, CompoundExtensionRangeWithOptions) { + ExpectParsesTo( + "message TestMessage {\n" + " extensions 2, 15, 9 to 11, 100 to max, 3 [(i) = 5];\n" + "}\n", + + "message_type {" + " name: \"TestMessage\"" + " extension_range {" + " start:2" + " end:3" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + " extension_range {" + " start:15" + " end:16" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + " extension_range {" + " start:9" + " end:12" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + " extension_range {" + " start:100" + " end:536870912" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + " extension_range {" + " start:3" + " end:4" + " options {" + " uninterpreted_option {" + " name {" + " name_part: \"i\"" + " is_extension: true" + " }" + " positive_int_value: 5" + " }" + " }" + " }" + "}"); +} + TEST_F(ParseMessageTest, LargerMaxForMessageSetWireFormatMessages) { // Messages using the message_set_wire_format option can accept larger // extension numbers, as the numbers are not encoded as int32 field values @@ -871,6 +994,42 @@ TEST_F(ParseEnumTest, ValueOptions) { "}"); } +TEST_F(ParseEnumTest, ReservedRange) { + ExpectParsesTo( + "enum TestEnum {\n" + " FOO = 0;\n" + " reserved -2147483648, -6 to -4, -1 to 1, 2, 15, 9 to 11, 3, 20 to max;\n" + "}\n", + + "enum_type {" + " name: \"TestEnum\"" + " value { name:\"FOO\" number:0 }" + " reserved_range { start:-2147483648 end:-2147483648 }" + " reserved_range { start:-6 end:-4 }" + " reserved_range { start:-1 end:1 }" + " reserved_range { start:2 end:2 }" + " reserved_range { start:15 end:15 }" + " reserved_range { start:9 end:11 }" + " reserved_range { start:3 end:3 }" + " reserved_range { start:20 end:2147483647 }" + "}"); +} + +TEST_F(ParseEnumTest, ReservedNames) { + ExpectParsesTo( + "enum TestEnum {\n" + " FOO = 0;\n" + " reserved \"foo\", \"bar\";\n" + "}\n", + + "enum_type {" + " name: \"TestEnum\"" + " value { name:\"FOO\" number:0 }" + " reserved_name: \"foo\"" + " reserved_name: \"bar\"" + "}"); +} + // =================================================================== typedef ParserTest ParseServiceTest; @@ -1365,15 +1524,60 @@ TEST_F(ParseErrorTest, EnumValueMissingNumber) { "1:5: Missing numeric value for enum constant.\n"); } +TEST_F(ParseErrorTest, EnumReservedStandaloneMaxNotAllowed) { + ExpectHasErrors( + "enum TestEnum {\n" + " FOO = 1;\n" + " reserved max;\n" + "}\n", + "2:11: Expected enum value or number range.\n"); +} + +TEST_F(ParseErrorTest, EnumReservedMixNameAndNumber) { + ExpectHasErrors( + "enum TestEnum {\n" + " FOO = 1;\n" + " reserved 10, \"foo\";\n" + "}\n", + "2:15: Expected enum number range.\n"); +} + +TEST_F(ParseErrorTest, EnumReservedPositiveNumberOutOfRange) { + ExpectHasErrors( + "enum TestEnum {\n" + "FOO = 1;\n" + " reserved 2147483648;\n" + "}\n", + "2:11: Integer out of range.\n"); +} + +TEST_F(ParseErrorTest, EnumReservedNegativeNumberOutOfRange) { + ExpectHasErrors( + "enum TestEnum {\n" + "FOO = 1;\n" + " reserved -2147483649;\n" + "}\n", + "2:12: Integer out of range.\n"); +} + +TEST_F(ParseErrorTest, EnumReservedMissingQuotes) { + ExpectHasErrors( + "enum TestEnum {\n" + " FOO = 1;\n" + " reserved foo;\n" + "}\n", + "2:11: Expected enum value or number range.\n"); +} + // ------------------------------------------------------------------- // Reserved field number errors -TEST_F(ParseErrorTest, ReservedMaxNotAllowed) { +TEST_F(ParseErrorTest, ReservedStandaloneMaxNotAllowed) { ExpectHasErrors( "message Foo {\n" - " reserved 10 to max;\n" + " reserved max;\n" "}\n", - "1:17: Expected integer.\n"); + "1:11: Expected field name or number range.\n"); } TEST_F(ParseErrorTest, ReservedMixNameAndNumber) { @@ -1392,6 +1596,23 @@ TEST_F(ParseErrorTest, ReservedMissingQuotes) { "1:11: Expected field name or number range.\n"); } +TEST_F(ParseErrorTest, ReservedNegativeNumber) { + ExpectHasErrors( + "message Foo {\n" + " reserved -10;\n" + "}\n", + "1:11: Expected field name or number range.\n"); +} + +TEST_F(ParseErrorTest, ReservedNumberOutOfRange) { + ExpectHasErrors( + "message Foo {\n" + " reserved 2147483648;\n" + "}\n", + "1:11: Integer out of range.\n"); +} + + // ------------------------------------------------------------------- // Service errors diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 78252817..eefdb196 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -49,8 +49,31 @@ const std::string kDescriptorMetadataFile = "GPBMetadata/Google/Protobuf/Internal/Descriptor.php"; const std::string kDescriptorDirName = "Google/Protobuf/Internal"; const std::string kDescriptorPackageName = "Google\\Protobuf\\Internal"; -const char* const kReservedNames[] = {"ARRAY", "Empty", "ECHO"}; -const int kReservedNamesSize = 3; +const char* const kReservedNames[] = { + "abstract", "and", "array", "as", "break", + "callable", "case", "catch", "class", "clone", + "const", "continue", "declare", "default", "die", + "do", "echo", "else", "elseif", "empty", + "enddeclare", "endfor", "endforeach", "endif", "endswitch", + "endwhile", "eval", "exit", "extends", "final", + "for", "foreach", "function", "global", "goto", + "if", "implements", "include", "include_once", "instanceof", + "insteadof", "interface", "isset", "list", "namespace", + "new", "or", "print", "private", "protected", + "public", "require", "require_once", "return", "static", + "switch", "throw", "trait", "try", "unset", + "use", "var", "while", "xor", "int", + "float", "bool", "string", "true", "false", + "null", "void", "iterable"}; +const char* const kValidConstantNames[] = { + "int", "float", "bool", "string", "true", + "false", "null", "void", "iterable", +}; +const int kReservedNamesSize = 73; +const int kValidConstantNamesSize = 9; +const int kFieldSetter = 1; +const int kFieldGetter = 2; +const int kFieldProperty = 3; namespace google { namespace protobuf { @@ -71,12 +94,18 @@ std::string EscapeDollor(const string& to_escape); std::string BinaryToHex(const string& binary); void Indent(io::Printer* printer); void Outdent(io::Printer* printer); -void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message); -void GenerateFieldDocComment(io::Printer* printer, - const FieldDescriptor* field); -void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_); +void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message, + int is_descriptor); +void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, + int is_descriptor, int function_type); +void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_, + int is_descriptor); void GenerateEnumValueDocComment(io::Printer* printer, const EnumValueDescriptor* value); +void GenerateServiceDocComment(io::Printer* printer, + const ServiceDescriptor* service); +void GenerateServiceMethodDocComment(io::Printer* printer, + const MethodDescriptor* method); std::string RenameEmpty(const std::string& name) { if (name == "Empty") { @@ -116,8 +145,11 @@ std::string ClassNamePrefix(const string& classname, bool is_reserved = false; + string lower = classname; + transform(lower.begin(), lower.end(), lower.begin(), ::tolower); + for (int i = 0; i < kReservedNamesSize; i++) { - if (classname == kReservedNames[i]) { + if (lower == kReservedNames[i]) { is_reserved = true; break; } @@ -134,17 +166,36 @@ std::string ClassNamePrefix(const string& classname, return ""; } +std::string ConstantNamePrefix(const string& classname) { + bool is_reserved = false; -template <typename DescriptorType> -std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { - string classname = desc->name(); - const Descriptor* containing = desc->containing_type(); - while (containing != NULL) { - classname = containing->name() + '_' + classname; - containing = containing->containing_type(); + string lower = classname; + transform(lower.begin(), lower.end(), lower.begin(), ::tolower); + + for (int i = 0; i < kReservedNamesSize; i++) { + if (lower == kReservedNames[i]) { + is_reserved = true; + break; + } + } + + for (int i = 0; i < kValidConstantNamesSize; i++) { + if (lower == kValidConstantNames[i]) { + is_reserved = false; + break; + } } - classname = ClassNamePrefix(classname, desc) + classname; + if (is_reserved) { + return "PB"; + } + + return ""; +} + +template <typename DescriptorType> +std::string NamespacedName(const string& classname, + const DescriptorType* desc, bool is_descriptor) { if (desc->file()->options().has_php_namespace()) { const string& php_namespace = desc->file()->options().php_namespace(); if (php_namespace != "") { @@ -162,6 +213,17 @@ std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { } } +template <typename DescriptorType> +std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { + string classname = GeneratedClassName(desc); + return NamespacedName(classname, desc, is_descriptor); +} + +std::string FullClassName(const ServiceDescriptor* desc, bool is_descriptor) { + string classname = GeneratedClassName(desc); + return NamespacedName(classname, desc, is_descriptor); +} + std::string PhpName(const std::string& full_name, bool is_descriptor) { if (is_descriptor) { return kDescriptorPackageName; @@ -267,6 +329,17 @@ std::string GeneratedEnumFileName(const EnumDescriptor* en, return result + ".php"; } +std::string GeneratedServiceFileName(const ServiceDescriptor* service, + bool is_descriptor) { + std::string result = FullClassName(service, is_descriptor) + "Interface"; + for (int i = 0; i < result.size(); i++) { + if (result[i] == '\\') { + result[i] = '/'; + } + } + return result + ".php"; +} + std::string IntToString(int32 value) { std::ostringstream os; os << value; @@ -306,6 +379,87 @@ std::string TypeName(const FieldDescriptor* field) { } } +std::string PhpSetterTypeName(const FieldDescriptor* field, bool is_descriptor) { + if (field->is_map()) { + return "array|\\Google\\Protobuf\\Internal\\MapField"; + } + string type; + switch (field->type()) { + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_SFIXED32: + case FieldDescriptor::TYPE_ENUM: + type = "int"; + break; + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: + type = "int|string"; + break; + case FieldDescriptor::TYPE_DOUBLE: + case FieldDescriptor::TYPE_FLOAT: + type = "float"; + break; + case FieldDescriptor::TYPE_BOOL: + type = "bool"; + break; + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_BYTES: + type = "string"; + break; + case FieldDescriptor::TYPE_MESSAGE: + type = "\\" + FullClassName(field->message_type(), is_descriptor); + break; + case FieldDescriptor::TYPE_GROUP: + return "null"; + default: assert(false); return ""; + } + if (field->is_repeated()) { + // accommodate for edge case with multiple types. + size_t start_pos = type.find("|"); + if (start_pos != std::string::npos) { + type.replace(start_pos, 1, "[]|"); + } + type += "[]|\\Google\\Protobuf\\Internal\\RepeatedField"; + } + return type; +} + +std::string PhpGetterTypeName(const FieldDescriptor* field, bool is_descriptor) { + if (field->is_map()) { + return "\\Google\\Protobuf\\Internal\\MapField"; + } + if (field->is_repeated()) { + return "\\Google\\Protobuf\\Internal\\RepeatedField"; + } + switch (field->type()) { + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_SFIXED32: + case FieldDescriptor::TYPE_ENUM: return "int"; + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: return "int|string"; + case FieldDescriptor::TYPE_DOUBLE: + case FieldDescriptor::TYPE_FLOAT: return "float"; + case FieldDescriptor::TYPE_BOOL: return "bool"; + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_BYTES: return "string"; + case FieldDescriptor::TYPE_MESSAGE: + return "\\" + FullClassName(field->message_type(), is_descriptor); + case FieldDescriptor::TYPE_GROUP: return "null"; + default: assert(false); return ""; + } +} + std::string EnumOrMessageSuffix( const FieldDescriptor* field, bool is_descriptor) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { @@ -390,7 +544,7 @@ void Outdent(io::Printer* printer) { void GenerateField(const FieldDescriptor* field, io::Printer* printer, bool is_descriptor) { if (field->is_repeated()) { - GenerateFieldDocComment(printer, field); + GenerateFieldDocComment(printer, field, is_descriptor, kFieldProperty); printer->Print( "private $^name^;\n", "name", field->name()); @@ -398,7 +552,7 @@ void GenerateField(const FieldDescriptor* field, io::Printer* printer, // Oneof fields are handled by GenerateOneofField. return; } else { - GenerateFieldDocComment(printer, field); + GenerateFieldDocComment(printer, field, is_descriptor, kFieldProperty); printer->Print( "private $^name^ = ^default^;\n", "name", field->name(), @@ -426,7 +580,7 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, // Generate getter. if (oneof != NULL) { - GenerateFieldDocComment(printer, field); + GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter); printer->Print( "public function get^camel_name^()\n" "{\n" @@ -435,7 +589,7 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, "camel_name", UnderscoresToCamelCase(field->name(), true), "number", IntToString(field->number())); } else { - GenerateFieldDocComment(printer, field); + GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter); printer->Print( "public function get^camel_name^()\n" "{\n" @@ -446,14 +600,11 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, } // Generate setter. - GenerateFieldDocComment(printer, field); + GenerateFieldDocComment(printer, field, is_descriptor, kFieldSetter); printer->Print( - "public function set^camel_name^(^var^)\n" + "public function set^camel_name^($var)\n" "{\n", - "camel_name", UnderscoresToCamelCase(field->name(), true), - "var", (field->is_repeated() || - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ? - "&$var": "$var"); + "camel_name", UnderscoresToCamelCase(field->name(), true)); Indent(printer); @@ -570,13 +721,23 @@ void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) { const EnumValueDescriptor* value = en->value(i); printer->Print( "->value(\"^name^\", ^number^)\n", - "name", ClassNamePrefix(value->name(), en) + value->name(), + "name", ConstantNamePrefix(value->name()) + value->name(), "number", IntToString(value->number())); } printer->Print("->finalizeToPool();\n\n"); Outdent(printer); } +void GenerateServiceMethod(const MethodDescriptor* method, + io::Printer* printer) { + printer->Print( + "public function ^camel_name^(\\^request_name^ $request);\n\n", + "camel_name", UnderscoresToCamelCase(method->name(), false), + "request_name", FullClassName( + method->input_type(), false) + ); +} + void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, io::Printer* printer) { // Don't generate MapEntry messages -- we use the PHP extension's native @@ -758,7 +919,7 @@ void GenerateUseDeclaration(bool is_descriptor, io::Printer* printer) { "use Google\\Protobuf\\Internal\\GPBType;\n" "use Google\\Protobuf\\Internal\\GPBWire;\n" "use Google\\Protobuf\\Internal\\RepeatedField;\n" - "use Google\\Protobuf\\Internal\\InputStream;\n\n" + "use Google\\Protobuf\\Internal\\InputStream;\n" "use Google\\Protobuf\\Internal\\GPBUtil;\n\n"); } } @@ -844,7 +1005,7 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, "name", fullname.substr(0, lastindex)); } - GenerateEnumDocComment(&printer, en); + GenerateEnumDocComment(&printer, en, is_descriptor); if (lastindex != string::npos) { printer.Print( @@ -863,7 +1024,7 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, const EnumValueDescriptor* value = en->value(i); GenerateEnumValueDocComment(&printer, value); printer.Print("const ^name^ = ^number^;\n", - "name", ClassNamePrefix(value->name(), en) + value->name(), + "name", ConstantNamePrefix(value->name()) + value->name(), "number", IntToString(value->number())); } @@ -905,7 +1066,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, GenerateUseDeclaration(is_descriptor, &printer); - GenerateMessageDocComment(&printer, message); + GenerateMessageDocComment(&printer, message, is_descriptor); if (lastindex != string::npos) { printer.Print( "class ^name^ extends \\Google\\Protobuf\\Internal\\Message\n" @@ -953,6 +1114,9 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, for (int i = 0; i < message->oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); printer.Print( + "/**\n" + " * @return string\n" + " */\n" "public function get^camel_name^()\n" "{\n" " return $this->whichOneof(\"^name^\");\n" @@ -975,6 +1139,58 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, } } +void GenerateServiceFile(const FileDescriptor* file, + const ServiceDescriptor* service, bool is_descriptor, + GeneratorContext* generator_context) { + std::string filename = GeneratedServiceFileName(service, is_descriptor); + scoped_ptr<io::ZeroCopyOutputStream> output( + generator_context->Open(filename)); + io::Printer printer(output.get(), '^'); + + GenerateHead(file, &printer); + + std::string fullname = FilenameToClassname(filename); + int lastindex = fullname.find_last_of("\\"); + + if (file->options().has_php_namespace()) { + const string& php_namespace = file->options().php_namespace(); + if (!php_namespace.empty()) { + printer.Print( + "namespace ^name^;\n\n", + "name", php_namespace); + } + } else if (!file->package().empty()) { + printer.Print( + "namespace ^name^;\n\n", + "name", fullname.substr(0, lastindex)); + } + + GenerateServiceDocComment(&printer, service); + + if (lastindex != string::npos) { + printer.Print( + "interface ^name^\n" + "{\n", + "name", fullname.substr(lastindex + 1)); + } else { + printer.Print( + "interface ^name^\n" + "{\n", + "name", fullname); + } + + Indent(&printer); + + for (int i = 0; i < service->method_count(); i++) { + const MethodDescriptor* method = service->method(i); + GenerateServiceMethodDocComment(&printer, method); + GenerateServiceMethod(method, &printer); + } + + Outdent(&printer); + printer.Print("}\n\n"); +} + void GenerateFile(const FileDescriptor* file, bool is_descriptor, GeneratorContext* generator_context) { GenerateMetadataFile(file, is_descriptor, generator_context); @@ -986,6 +1202,12 @@ void GenerateFile(const FileDescriptor* file, bool is_descriptor, GenerateEnumFile(file, file->enum_type(i), is_descriptor, generator_context); } + if (file->options().php_generic_services()) { + for (int i = 0; i < file->service_count(); i++) { + GenerateServiceFile(file, file->service(i), is_descriptor, + generator_context); + } + } } static string EscapePhpdoc(const string& input) { @@ -1019,22 +1241,6 @@ static string EscapePhpdoc(const string& input) { // does not have a corresponding @Deprecated annotation. result.append("@"); break; - case '<': - // Avoid interpretation as HTML. - result.append("<"); - break; - case '>': - // Avoid interpretation as HTML. - result.append(">"); - break; - case '&': - // Avoid interpretation as HTML. - result.append("&"); - break; - case '\\': - // Java interprets Unicode escape sequences anywhere! - result.append("\"); - break; default: result.push_back(c); break; @@ -1053,18 +1259,17 @@ static void GenerateDocCommentBodyForLocation( if (!comments.empty()) { // TODO(teboring): Ideally we should parse the comment text as Markdown and // write it back as HTML, but this requires a Markdown parser. For now - // we just use <pre> to get fixed-width text formatting. + // we just use the proto comments unchanged. // If the comment itself contains block comment start or end markers, // HTML-escape them so that they don't accidentally close the doc comment. comments = EscapePhpdoc(comments); - vector<string> lines = Split(comments, "\n"); + std::vector<string> lines = Split(comments, "\n"); while (!lines.empty() && lines.back().empty()) { lines.pop_back(); } - printer->Print(" * <pre>\n"); for (int i = 0; i < lines.size(); i++) { // Most lines should start with a space. Watch out for lines that start // with a /, since putting that right after the leading asterisk will @@ -1076,7 +1281,6 @@ static void GenerateDocCommentBodyForLocation( } } printer->Print( - " * </pre>\n" " *\n"); } } @@ -1102,17 +1306,28 @@ static string FirstLineOf(const string& value) { } void GenerateMessageDocComment(io::Printer* printer, - const Descriptor* message) { + const Descriptor* message, int is_descriptor) { printer->Print("/**\n"); GenerateDocCommentBody(printer, message); printer->Print( + " * Generated from protobuf message <code>^messagename^</code>\n" + " */\n", + "fullname", EscapePhpdoc(PhpName(message->full_name(), is_descriptor)), + "messagename", EscapePhpdoc(message->full_name())); +} + +void GenerateServiceDocComment(io::Printer* printer, + const ServiceDescriptor* service) { + printer->Print("/**\n"); + GenerateDocCommentBody(printer, service); + printer->Print( " * Protobuf type <code>^fullname^</code>\n" " */\n", - "fullname", EscapePhpdoc(message->full_name())); + "fullname", EscapePhpdoc(service->full_name())); } -void GenerateFieldDocComment(io::Printer* printer, - const FieldDescriptor* field) { +void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, + int is_descriptor, int function_type) { // In theory we should have slightly different comments for setters, getters, // etc., but in practice everyone already knows the difference between these // so it's redundant information. @@ -1124,18 +1339,27 @@ void GenerateFieldDocComment(io::Printer* printer, printer->Print("/**\n"); GenerateDocCommentBody(printer, field); printer->Print( - " * <code>^def^</code>\n", + " * Generated from protobuf field <code>^def^</code>\n", "def", EscapePhpdoc(FirstLineOf(field->DebugString()))); + if (function_type == kFieldSetter) { + printer->Print(" * @param ^php_type^ $var\n", + "php_type", PhpSetterTypeName(field, is_descriptor)); + printer->Print(" * @return $this\n"); + } else if (function_type == kFieldGetter) { + printer->Print(" * @return ^php_type^\n", + "php_type", PhpGetterTypeName(field, is_descriptor)); + } printer->Print(" */\n"); } -void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_) { +void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_, + int is_descriptor) { printer->Print("/**\n"); GenerateDocCommentBody(printer, enum_); printer->Print( " * Protobuf enum <code>^fullname^</code>\n" " */\n", - "fullname", EscapePhpdoc(enum_->full_name())); + "fullname", EscapePhpdoc(PhpName(enum_->full_name(), is_descriptor))); } void GenerateEnumValueDocComment(io::Printer* printer, @@ -1143,11 +1367,28 @@ void GenerateEnumValueDocComment(io::Printer* printer, printer->Print("/**\n"); GenerateDocCommentBody(printer, value); printer->Print( - " * <code>^def^</code>\n" + " * Generated from protobuf enum <code>^def^</code>\n" " */\n", "def", EscapePhpdoc(FirstLineOf(value->DebugString()))); } +void GenerateServiceMethodDocComment(io::Printer* printer, + const MethodDescriptor* method) { + printer->Print("/**\n"); + GenerateDocCommentBody(printer, method); + printer->Print( + " * Method <code>^method_name^</code>\n" + " *\n", + "method_name", EscapePhpdoc(UnderscoresToCamelCase(method->name(), false))); + printer->Print( + " * @param \\^input_type^ $request\n", + "input_type", EscapePhpdoc(FullClassName(method->input_type(), false))); + printer->Print( + " * @return \\^return_type^\n" + " */\n", + "return_type", EscapePhpdoc(FullClassName(method->output_type(), false))); +} + bool Generator::Generate(const FileDescriptor* file, const string& parameter, GeneratorContext* generator_context, string* error) const { @@ -1171,6 +1412,31 @@ bool Generator::Generate(const FileDescriptor* file, const string& parameter, return true; } +std::string GeneratedClassName(const Descriptor* desc) { + std::string classname = desc->name(); + const Descriptor* containing = desc->containing_type(); + while (containing != NULL) { + classname = containing->name() + '_' + classname; + containing = containing->containing_type(); + } + return ClassNamePrefix(classname, desc) + classname; +} + +std::string GeneratedClassName(const EnumDescriptor* desc) { + std::string classname = desc->name(); + const Descriptor* containing = desc->containing_type(); + while (containing != NULL) { + classname = containing->name() + '_' + classname; + containing = containing->containing_type(); + } + return ClassNamePrefix(classname, desc) + classname; +} + +std::string GeneratedClassName(const ServiceDescriptor* desc) { + std::string classname = desc->name(); + return ClassNamePrefix(classname, desc) + classname; +} + } // namespace php } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/php/php_generator.h b/src/google/protobuf/compiler/php/php_generator.h index ce2b000a..67e70bc7 100644 --- a/src/google/protobuf/compiler/php/php_generator.h +++ b/src/google/protobuf/compiler/php/php_generator.h @@ -32,6 +32,7 @@ #define GOOGLE_PROTOBUF_COMPILER_PHP_GENERATOR_H__ #include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/descriptor.h> #include <string> @@ -47,8 +48,16 @@ class LIBPROTOC_EXPORT Generator const string& parameter, GeneratorContext* generator_context, string* error) const; + }; +// To skip reserved keywords in php, some generated classname are prefixed. +// Other code generators may need following API to figure out the actual +// classname. +std::string GeneratedClassName(const google::protobuf::Descriptor* desc); +std::string GeneratedClassName(const google::protobuf::EnumDescriptor* desc); +std::string GeneratedClassName(const google::protobuf::ServiceDescriptor* desc); + } // namespace php } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index 3848101d..bde3d798 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -36,14 +36,7 @@ #include <set> #ifdef _WIN32 -#include <io.h> #include <fcntl.h> -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif #else #include <unistd.h> #endif @@ -54,12 +47,19 @@ #include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/stubs/io_win32.h> namespace google { namespace protobuf { namespace compiler { +#if defined(_WIN32) +// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import +// them like we do below. +using google::protobuf::internal::win32::setmode; +#endif + class GeneratorResponseContext : public GeneratorContext { public: GeneratorResponseContext( @@ -127,6 +127,7 @@ bool GenerateCode(const CodeGeneratorRequest& request, GeneratorResponseContext context( request.compiler_version(), response, parsed_files); + string error; bool succeeded = generator.GenerateAll( parsed_files, request.parameter(), &context, &error); @@ -150,8 +151,8 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { } #ifdef _WIN32 - _setmode(STDIN_FILENO, _O_BINARY); - _setmode(STDOUT_FILENO, _O_BINARY); + setmode(STDIN_FILENO, _O_BINARY); + setmode(STDOUT_FILENO, _O_BINARY); #endif CodeGeneratorRequest request; diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index f7dc1b70..d13ad2b3 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -1,7 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/compiler/plugin.proto -#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION #include <google/protobuf/compiler/plugin.pb.h> #include <algorithm> @@ -15,111 +14,189 @@ #include <google/protobuf/generated_message_reflection.h> #include <google/protobuf/reflection_ops.h> #include <google/protobuf/wire_format.h> +// This is a temporary google only hack +#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS +#include "third_party/protobuf/version.h" +#endif // @@protoc_insertion_point(includes) - namespace google { namespace protobuf { namespace compiler { -class VersionDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Version> { +class VersionDefaultTypeInternal { + public: + ::google::protobuf::internal::ExplicitlyConstructed<Version> + _instance; } _Version_default_instance_; -class CodeGeneratorRequestDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorRequest> { +class CodeGeneratorRequestDefaultTypeInternal { + public: + ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorRequest> + _instance; } _CodeGeneratorRequest_default_instance_; -class CodeGeneratorResponse_FileDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse_File> { +class CodeGeneratorResponse_FileDefaultTypeInternal { + public: + ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse_File> + _instance; } _CodeGeneratorResponse_File_default_instance_; -class CodeGeneratorResponseDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse> { +class CodeGeneratorResponseDefaultTypeInternal { + public: + ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse> + _instance; } _CodeGeneratorResponse_default_instance_; - +} // namespace compiler +} // namespace protobuf +} // namespace google namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto { +void InitDefaultsVersionImpl() { + GOOGLE_PROTOBUF_VERIFY_VERSION; +#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + ::google::protobuf::internal::InitProtobufDefaultsForceUnique(); +#else + ::google::protobuf::internal::InitProtobufDefaults(); +#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + { + void* ptr = &::google::protobuf::compiler::_Version_default_instance_; + new (ptr) ::google::protobuf::compiler::Version(); + ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); + } + ::google::protobuf::compiler::Version::InitAsDefaultInstance(); +} + +void InitDefaultsVersion() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsVersionImpl); +} -namespace { +void InitDefaultsCodeGeneratorRequestImpl() { + GOOGLE_PROTOBUF_VERIFY_VERSION; -::google::protobuf::Metadata file_level_metadata[4]; +#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + ::google::protobuf::internal::InitProtobufDefaultsForceUnique(); +#else + ::google::protobuf::internal::InitProtobufDefaults(); +#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + protobuf_google_2fprotobuf_2fdescriptor_2eproto::InitDefaultsFileDescriptorProto(); + protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsVersion(); + { + void* ptr = &::google::protobuf::compiler::_CodeGeneratorRequest_default_instance_; + new (ptr) ::google::protobuf::compiler::CodeGeneratorRequest(); + ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); + } + ::google::protobuf::compiler::CodeGeneratorRequest::InitAsDefaultInstance(); +} -} // namespace +void InitDefaultsCodeGeneratorRequest() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsCodeGeneratorRequestImpl); +} -PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { - {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, -}; +void InitDefaultsCodeGeneratorResponse_FileImpl() { + GOOGLE_PROTOBUF_VERIFY_VERSION; -PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { - ::google::protobuf::internal::AuxillaryParseTableField(), -}; -PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const - TableStruct::schema[] = { - { NULL, NULL, 0, -1, -1, false }, - { NULL, NULL, 0, -1, -1, false }, - { NULL, NULL, 0, -1, -1, false }, - { NULL, NULL, 0, -1, -1, false }, -}; +#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + ::google::protobuf::internal::InitProtobufDefaultsForceUnique(); +#else + ::google::protobuf::internal::InitProtobufDefaults(); +#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + { + void* ptr = &::google::protobuf::compiler::_CodeGeneratorResponse_File_default_instance_; + new (ptr) ::google::protobuf::compiler::CodeGeneratorResponse_File(); + ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); + } + ::google::protobuf::compiler::CodeGeneratorResponse_File::InitAsDefaultInstance(); +} + +void InitDefaultsCodeGeneratorResponse_File() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsCodeGeneratorResponse_FileImpl); +} + +void InitDefaultsCodeGeneratorResponseImpl() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + +#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + ::google::protobuf::internal::InitProtobufDefaultsForceUnique(); +#else + ::google::protobuf::internal::InitProtobufDefaults(); +#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse_File(); + { + void* ptr = &::google::protobuf::compiler::_CodeGeneratorResponse_default_instance_; + new (ptr) ::google::protobuf::compiler::CodeGeneratorResponse(); + ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); + } + ::google::protobuf::compiler::CodeGeneratorResponse::InitAsDefaultInstance(); +} + +void InitDefaultsCodeGeneratorResponse() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsCodeGeneratorResponseImpl); +} -const ::google::protobuf::uint32 TableStruct::offsets[] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, _has_bits_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, _internal_metadata_), +::google::protobuf::Metadata file_level_metadata[4]; + +const ::google::protobuf::uint32 TableStruct::offsets[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::Version, _has_bits_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::Version, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, major_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, minor_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, patch_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, suffix_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::Version, major_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::Version, minor_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::Version, patch_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::Version, suffix_), 1, 2, 3, 0, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _has_bits_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _has_bits_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, file_to_generate_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, parameter_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, proto_file_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, compiler_version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, file_to_generate_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, parameter_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, proto_file_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, compiler_version_), ~0u, 0, ~0u, 1, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _has_bits_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _has_bits_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, insertion_point_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, content_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, insertion_point_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, content_), 0, 1, 2, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _has_bits_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _has_bits_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, error_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, file_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, error_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, file_), 0, ~0u, }; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { - { 0, 9, sizeof(Version)}, - { 13, 22, sizeof(CodeGeneratorRequest)}, - { 26, 34, sizeof(CodeGeneratorResponse_File)}, - { 37, 44, sizeof(CodeGeneratorResponse)}, +static const ::google::protobuf::internal::MigrationSchema schemas[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { + { 0, 9, sizeof(::google::protobuf::compiler::Version)}, + { 13, 22, sizeof(::google::protobuf::compiler::CodeGeneratorRequest)}, + { 26, 34, sizeof(::google::protobuf::compiler::CodeGeneratorResponse_File)}, + { 37, 44, sizeof(::google::protobuf::compiler::CodeGeneratorResponse)}, }; static ::google::protobuf::Message const * const file_default_instances[] = { - reinterpret_cast<const ::google::protobuf::Message*>(&_Version_default_instance_), - reinterpret_cast<const ::google::protobuf::Message*>(&_CodeGeneratorRequest_default_instance_), - reinterpret_cast<const ::google::protobuf::Message*>(&_CodeGeneratorResponse_File_default_instance_), - reinterpret_cast<const ::google::protobuf::Message*>(&_CodeGeneratorResponse_default_instance_), + reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::compiler::_Version_default_instance_), + reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::compiler::_CodeGeneratorRequest_default_instance_), + reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::compiler::_CodeGeneratorResponse_File_default_instance_), + reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::compiler::_CodeGeneratorResponse_default_instance_), }; -namespace { - void protobuf_AssignDescriptors() { AddDescriptors(); ::google::protobuf::MessageFactory* factory = NULL; @@ -133,45 +210,15 @@ void protobuf_AssignDescriptorsOnce() { ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors); } -void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; +void protobuf_RegisterTypes(const ::std::string&) GOOGLE_PROTOBUF_ATTRIBUTE_COLD; void protobuf_RegisterTypes(const ::std::string&) { protobuf_AssignDescriptorsOnce(); ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4); } -} // namespace - -void TableStruct::Shutdown() { - _Version_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; - _CodeGeneratorRequest_default_instance_.Shutdown(); - delete file_level_metadata[1].reflection; - _CodeGeneratorResponse_File_default_instance_.Shutdown(); - delete file_level_metadata[2].reflection; - _CodeGeneratorResponse_default_instance_.Shutdown(); - delete file_level_metadata[3].reflection; -} - -void TableStruct::InitDefaultsImpl() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - ::google::protobuf::internal::InitProtobufDefaults(); - ::google::protobuf::protobuf_google_2fprotobuf_2fdescriptor_2eproto::InitDefaults(); - _Version_default_instance_.DefaultConstruct(); - _CodeGeneratorRequest_default_instance_.DefaultConstruct(); - _CodeGeneratorResponse_File_default_instance_.DefaultConstruct(); - _CodeGeneratorResponse_default_instance_.DefaultConstruct(); - _CodeGeneratorRequest_default_instance_.get_mutable()->compiler_version_ = const_cast< ::google::protobuf::compiler::Version*>( - ::google::protobuf::compiler::Version::internal_default_instance()); -} - -void InitDefaults() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl); -} void AddDescriptorsImpl() { InitDefaults(); - static const char descriptor[] = { + static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n%google/protobuf/compiler/plugin.proto\022" "\030google.protobuf.compiler\032 google/protob" "uf/descriptor.proto\"F\n\007Version\022\r\n\005major\030" @@ -193,26 +240,28 @@ void AddDescriptorsImpl() { descriptor, 638); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes); - ::google::protobuf::protobuf_google_2fprotobuf_2fdescriptor_2eproto::AddDescriptors(); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); + ::protobuf_google_2fprotobuf_2fdescriptor_2eproto::AddDescriptors(); } void AddDescriptors() { static GOOGLE_PROTOBUF_DECLARE_ONCE(once); ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl); } -// Force AddDescriptors() to be called at static initialization time. +// Force AddDescriptors() to be called at dynamic initialization time. struct StaticDescriptorInitializer { StaticDescriptorInitializer() { AddDescriptors(); } } static_descriptor_initializer; - } // namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto - +namespace google { +namespace protobuf { +namespace compiler { // =================================================================== +void Version::InitAsDefaultInstance() { +} #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int Version::kMajorFieldNumber; const int Version::kMinorFieldNumber; @@ -223,7 +272,7 @@ const int Version::kSuffixFieldNumber; Version::Version() : ::google::protobuf::Message(), _internal_metadata_(NULL) { if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaults(); + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsVersion(); } SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.Version) @@ -239,16 +288,17 @@ Version::Version(const Version& from) suffix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.suffix_); } ::memcpy(&major_, &from.major_, - reinterpret_cast<char*>(&patch_) - - reinterpret_cast<char*>(&major_) + sizeof(patch_)); + static_cast<size_t>(reinterpret_cast<char*>(&patch_) - + reinterpret_cast<char*>(&major_)) + sizeof(patch_)); // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.Version) } void Version::SharedCtor() { _cached_size_ = 0; suffix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - ::memset(&major_, 0, reinterpret_cast<char*>(&patch_) - - reinterpret_cast<char*>(&major_) + sizeof(patch_)); + ::memset(&major_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&patch_) - + reinterpret_cast<char*>(&major_)) + sizeof(patch_)); } Version::~Version() { @@ -266,32 +316,31 @@ void Version::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const ::google::protobuf::Descriptor* Version::descriptor() { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Version& Version::default_instance() { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaults(); + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsVersion(); return *internal_default_instance(); } -Version* Version::New(::google::protobuf::Arena* arena) const { - Version* n = new Version; - if (arena != NULL) { - arena->Own(n); - } - return n; -} void Version::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.Version) - if (has_suffix()) { + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!suffix_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - (*suffix_.UnsafeRawStringPointer())->clear(); + suffix_.UnsafeMutablePointer()->clear(); } - if (_has_bits_[0 / 32] & 14u) { - ::memset(&major_, 0, reinterpret_cast<char*>(&patch_) - - reinterpret_cast<char*>(&major_) + sizeof(patch_)); + if (cached_has_bits & 14u) { + ::memset(&major_, 0, static_cast<size_t>( + reinterpret_cast<char*>(&patch_) - + reinterpret_cast<char*>(&major_)) + sizeof(patch_)); } _has_bits_.Clear(); _internal_metadata_.Clear(); @@ -310,7 +359,7 @@ bool Version::MergePartialFromCodedStream( // optional int32 major = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(8u)) { + static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { set_has_major(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -324,7 +373,7 @@ bool Version::MergePartialFromCodedStream( // optional int32 minor = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { + static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { set_has_minor(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -338,7 +387,7 @@ bool Version::MergePartialFromCodedStream( // optional int32 patch = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(24u)) { + static_cast< ::google::protobuf::uint8>(24u /* 24 & 0xFF */)) { set_has_patch(); DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( @@ -352,11 +401,11 @@ bool Version::MergePartialFromCodedStream( // optional string suffix = 4; case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(34u)) { + static_cast< ::google::protobuf::uint8>(34u /* 34 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_suffix())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->suffix().data(), this->suffix().length(), + this->suffix().data(), static_cast<int>(this->suffix().length()), ::google::protobuf::internal::WireFormat::PARSE, "google.protobuf.compiler.Version.suffix"); } else { @@ -367,13 +416,11 @@ bool Version::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -412,7 +459,7 @@ void Version::SerializeWithCachedSizes( // optional string suffix = 4; if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->suffix().data(), this->suffix().length(), + this->suffix().data(), static_cast<int>(this->suffix().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.Version.suffix"); ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( @@ -421,13 +468,14 @@ void Version::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.Version) } ::google::protobuf::uint8* Version::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { + (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.Version) ::google::protobuf::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -451,7 +499,7 @@ void Version::SerializeWithCachedSizes( // optional string suffix = 4; if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->suffix().data(), this->suffix().length(), + this->suffix().data(), static_cast<int>(this->suffix().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.Version.suffix"); target = @@ -461,7 +509,7 @@ void Version::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.Version) return target; @@ -474,7 +522,7 @@ size_t Version::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } if (_has_bits_[0 / 32] & 15u) { // optional string suffix = 4; @@ -577,162 +625,31 @@ void Version::Swap(Version* other) { InternalSwap(other); } void Version::InternalSwap(Version* other) { + using std::swap; suffix_.Swap(&other->suffix_); - std::swap(major_, other->major_); - std::swap(minor_, other->minor_); - std::swap(patch_, other->patch_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(major_, other->major_); + swap(minor_, other->minor_); + swap(patch_, other->patch_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata Version::GetMetadata() const { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; + return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; } -#if PROTOBUF_INLINE_NOT_IN_HEADERS -// Version - -// optional int32 major = 1; -bool Version::has_major() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -void Version::set_has_major() { - _has_bits_[0] |= 0x00000002u; -} -void Version::clear_has_major() { - _has_bits_[0] &= ~0x00000002u; -} -void Version::clear_major() { - major_ = 0; - clear_has_major(); -} -::google::protobuf::int32 Version::major() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.major) - return major_; -} -void Version::set_major(::google::protobuf::int32 value) { - set_has_major(); - major_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.major) -} - -// optional int32 minor = 2; -bool Version::has_minor() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -void Version::set_has_minor() { - _has_bits_[0] |= 0x00000004u; -} -void Version::clear_has_minor() { - _has_bits_[0] &= ~0x00000004u; -} -void Version::clear_minor() { - minor_ = 0; - clear_has_minor(); -} -::google::protobuf::int32 Version::minor() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.minor) - return minor_; -} -void Version::set_minor(::google::protobuf::int32 value) { - set_has_minor(); - minor_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.minor) -} -// optional int32 patch = 3; -bool Version::has_patch() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -void Version::set_has_patch() { - _has_bits_[0] |= 0x00000008u; -} -void Version::clear_has_patch() { - _has_bits_[0] &= ~0x00000008u; -} -void Version::clear_patch() { - patch_ = 0; - clear_has_patch(); -} -::google::protobuf::int32 Version::patch() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.patch) - return patch_; -} -void Version::set_patch(::google::protobuf::int32 value) { - set_has_patch(); - patch_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.patch) -} +// =================================================================== -// optional string suffix = 4; -bool Version::has_suffix() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -void Version::set_has_suffix() { - _has_bits_[0] |= 0x00000001u; -} -void Version::clear_has_suffix() { - _has_bits_[0] &= ~0x00000001u; -} -void Version::clear_suffix() { - suffix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - clear_has_suffix(); -} -const ::std::string& Version::suffix() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.suffix) - return suffix_.GetNoArena(); -} -void Version::set_suffix(const ::std::string& value) { - set_has_suffix(); - suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix) -} -#if LANG_CXX11 -void Version::set_suffix(::std::string&& value) { - set_has_suffix(); - suffix_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.Version.suffix) +void CodeGeneratorRequest::InitAsDefaultInstance() { + ::google::protobuf::compiler::_CodeGeneratorRequest_default_instance_._instance.get_mutable()->compiler_version_ = const_cast< ::google::protobuf::compiler::Version*>( + ::google::protobuf::compiler::Version::internal_default_instance()); } -#endif -void Version::set_suffix(const char* value) { - GOOGLE_DCHECK(value != NULL); - set_has_suffix(); - suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.Version.suffix) -} -void Version::set_suffix(const char* value, size_t size) { - set_has_suffix(); - suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast<const char*>(value), size)); - // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.Version.suffix) -} -::std::string* Version::mutable_suffix() { - set_has_suffix(); - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.Version.suffix) - return suffix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -::std::string* Version::release_suffix() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix) - clear_has_suffix(); - return suffix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -void Version::set_allocated_suffix(::std::string* suffix) { - if (suffix != NULL) { - set_has_suffix(); - } else { - clear_has_suffix(); - } - suffix_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), suffix); - // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.Version.suffix) +void CodeGeneratorRequest::clear_proto_file() { + proto_file_.Clear(); } - -#endif // PROTOBUF_INLINE_NOT_IN_HEADERS - -// =================================================================== - #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int CodeGeneratorRequest::kFileToGenerateFieldNumber; const int CodeGeneratorRequest::kParameterFieldNumber; @@ -743,7 +660,7 @@ const int CodeGeneratorRequest::kCompilerVersionFieldNumber; CodeGeneratorRequest::CodeGeneratorRequest() : ::google::protobuf::Message(), _internal_metadata_(NULL) { if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaults(); + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorRequest(); } SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorRequest) @@ -781,9 +698,7 @@ CodeGeneratorRequest::~CodeGeneratorRequest() { void CodeGeneratorRequest::SharedDtor() { parameter_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (this != internal_default_instance()) { - delete compiler_version_; - } + if (this != internal_default_instance()) delete compiler_version_; } void CodeGeneratorRequest::SetCachedSize(int size) const { @@ -792,35 +707,33 @@ void CodeGeneratorRequest::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaults(); + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorRequest(); return *internal_default_instance(); } -CodeGeneratorRequest* CodeGeneratorRequest::New(::google::protobuf::Arena* arena) const { - CodeGeneratorRequest* n = new CodeGeneratorRequest; - if (arena != NULL) { - arena->Own(n); - } - return n; -} void CodeGeneratorRequest::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorRequest) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + file_to_generate_.Clear(); proto_file_.Clear(); - if (_has_bits_[0 / 32] & 3u) { - if (has_parameter()) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!parameter_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - (*parameter_.UnsafeRawStringPointer())->clear(); + parameter_.UnsafeMutablePointer()->clear(); } - if (has_compiler_version()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(compiler_version_ != NULL); - compiler_version_->::google::protobuf::compiler::Version::Clear(); + compiler_version_->Clear(); } } _has_bits_.Clear(); @@ -840,12 +753,12 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( // repeated string file_to_generate = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->add_file_to_generate())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->file_to_generate(this->file_to_generate_size() - 1).data(), - this->file_to_generate(this->file_to_generate_size() - 1).length(), + static_cast<int>(this->file_to_generate(this->file_to_generate_size() - 1).length()), ::google::protobuf::internal::WireFormat::PARSE, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate"); } else { @@ -857,11 +770,11 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( // optional string parameter = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_parameter())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->parameter().data(), this->parameter().length(), + this->parameter().data(), static_cast<int>(this->parameter().length()), ::google::protobuf::internal::WireFormat::PARSE, "google.protobuf.compiler.CodeGeneratorRequest.parameter"); } else { @@ -873,8 +786,8 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( // optional .google.protobuf.compiler.Version compiler_version = 3; case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + static_cast< ::google::protobuf::uint8>(26u /* 26 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessage( input, mutable_compiler_version())); } else { goto handle_unusual; @@ -885,8 +798,8 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( // repeated .google.protobuf.FileDescriptorProto proto_file = 15; case 15: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(122u)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + static_cast< ::google::protobuf::uint8>(122u /* 122 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessage( input, add_proto_file())); } else { goto handle_unusual; @@ -896,13 +809,11 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -925,7 +836,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( // repeated string file_to_generate = 1; for (int i = 0, n = this->file_to_generate_size(); i < n; i++) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->file_to_generate(i).data(), this->file_to_generate(i).length(), + this->file_to_generate(i).data(), static_cast<int>(this->file_to_generate(i).length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate"); ::google::protobuf::internal::WireFormatLite::WriteString( @@ -936,7 +847,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( // optional string parameter = 2; if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->parameter().data(), this->parameter().length(), + this->parameter().data(), static_cast<int>(this->parameter().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorRequest.parameter"); ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( @@ -946,24 +857,28 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( // optional .google.protobuf.compiler.Version compiler_version = 3; if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 3, *this->compiler_version_, output); + 3, *compiler_version_, output); } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; - for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) { + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->proto_file_size()); i < n; i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 15, this->proto_file(i), output); + 15, + this->proto_file(static_cast<int>(i)), + output); } if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorRequest) } ::google::protobuf::uint8* CodeGeneratorRequest::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { + (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorRequest) ::google::protobuf::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -971,7 +886,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( // repeated string file_to_generate = 1; for (int i = 0, n = this->file_to_generate_size(); i < n; i++) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->file_to_generate(i).data(), this->file_to_generate(i).length(), + this->file_to_generate(i).data(), static_cast<int>(this->file_to_generate(i).length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate"); target = ::google::protobuf::internal::WireFormatLite:: @@ -982,7 +897,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( // optional string parameter = 2; if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->parameter().data(), this->parameter().length(), + this->parameter().data(), static_cast<int>(this->parameter().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorRequest.parameter"); target = @@ -993,20 +908,21 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( // optional .google.protobuf.compiler.Version compiler_version = 3; if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite:: - InternalWriteMessageNoVirtualToArray( - 3, *this->compiler_version_, deterministic, target); + InternalWriteMessageToArray( + 3, *compiler_version_, deterministic, target); } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; - for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) { + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->proto_file_size()); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - InternalWriteMessageNoVirtualToArray( - 15, this->proto_file(i), deterministic, target); + InternalWriteMessageToArray( + 15, this->proto_file(static_cast<int>(i)), deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorRequest) return target; @@ -1019,7 +935,7 @@ size_t CodeGeneratorRequest::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated string file_to_generate = 1; total_size += 1 * @@ -1031,12 +947,12 @@ size_t CodeGeneratorRequest::ByteSizeLong() const { // repeated .google.protobuf.FileDescriptorProto proto_file = 15; { - unsigned int count = this->proto_file_size(); + unsigned int count = static_cast<unsigned int>(this->proto_file_size()); total_size += 1UL * count; for (unsigned int i = 0; i < count; i++) { total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->proto_file(i)); + ::google::protobuf::internal::WireFormatLite::MessageSize( + this->proto_file(static_cast<int>(i))); } } @@ -1051,8 +967,8 @@ size_t CodeGeneratorRequest::ByteSizeLong() const { // optional .google.protobuf.compiler.Version compiler_version = 3; if (has_compiler_version()) { total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - *this->compiler_version_); + ::google::protobuf::internal::WireFormatLite::MessageSize( + *compiler_version_); } } @@ -1123,234 +1039,26 @@ void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) { InternalSwap(other); } void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { - file_to_generate_.InternalSwap(&other->file_to_generate_); - proto_file_.InternalSwap(&other->proto_file_); + using std::swap; + file_to_generate_.InternalSwap(CastToBase(&other->file_to_generate_)); + CastToBase(&proto_file_)->InternalSwap(CastToBase(&other->proto_file_)); parameter_.Swap(&other->parameter_); - std::swap(compiler_version_, other->compiler_version_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(compiler_version_, other->compiler_version_); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; + return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; } -#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); -} -#if LANG_CXX11 -void CodeGeneratorRequest::set_file_to_generate(int index, ::std::string&& value) { - // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) - file_to_generate_.Mutable(index)->assign(std::move(value)); -} -#endif -void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) { - GOOGLE_DCHECK(value != NULL); - 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() { - // @@protoc_insertion_point(field_add_mutable:google.protobuf.compiler.CodeGeneratorRequest.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) -} -#if LANG_CXX11 -void CodeGeneratorRequest::add_file_to_generate(::std::string&& value) { - file_to_generate_.Add(std::move(value)); - // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) -} -#endif -void CodeGeneratorRequest::add_file_to_generate(const char* value) { - GOOGLE_DCHECK(value != NULL); - 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] & 0x00000001u) != 0; -} -void CodeGeneratorRequest::set_has_parameter() { - _has_bits_[0] |= 0x00000001u; -} -void CodeGeneratorRequest::clear_has_parameter() { - _has_bits_[0] &= ~0x00000001u; -} -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(); -} -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) -} -#if LANG_CXX11 -void CodeGeneratorRequest::set_parameter(::std::string&& value) { - set_has_parameter(); - parameter_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorRequest.parameter) -} -#endif -void CodeGeneratorRequest::set_parameter(const char* value) { - GOOGLE_DCHECK(value != NULL); - 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() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.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(); -} -::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_; -} -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_; -} - -// optional .google.protobuf.compiler.Version compiler_version = 3; -bool CodeGeneratorRequest::has_compiler_version() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -void CodeGeneratorRequest::set_has_compiler_version() { - _has_bits_[0] |= 0x00000002u; -} -void CodeGeneratorRequest::clear_has_compiler_version() { - _has_bits_[0] &= ~0x00000002u; -} -void CodeGeneratorRequest::clear_compiler_version() { - if (compiler_version_ != NULL) compiler_version_->::google::protobuf::compiler::Version::Clear(); - clear_has_compiler_version(); -} -const ::google::protobuf::compiler::Version& CodeGeneratorRequest::compiler_version() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) - return compiler_version_ != NULL ? *compiler_version_ - : *::google::protobuf::compiler::Version::internal_default_instance(); -} -::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() { - set_has_compiler_version(); - if (compiler_version_ == NULL) { - compiler_version_ = new ::google::protobuf::compiler::Version; - } - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) - return compiler_version_; -} -::google::protobuf::compiler::Version* CodeGeneratorRequest::release_compiler_version() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) - clear_has_compiler_version(); - ::google::protobuf::compiler::Version* temp = compiler_version_; - compiler_version_ = NULL; - return temp; -} -void CodeGeneratorRequest::set_allocated_compiler_version(::google::protobuf::compiler::Version* compiler_version) { - delete compiler_version_; - compiler_version_ = compiler_version; - if (compiler_version) { - set_has_compiler_version(); - } else { - clear_has_compiler_version(); - } - // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) -} - -#endif // PROTOBUF_INLINE_NOT_IN_HEADERS // =================================================================== +void CodeGeneratorResponse_File::InitAsDefaultInstance() { +} #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int CodeGeneratorResponse_File::kNameFieldNumber; const int CodeGeneratorResponse_File::kInsertionPointFieldNumber; @@ -1360,7 +1068,7 @@ const int CodeGeneratorResponse_File::kContentFieldNumber; CodeGeneratorResponse_File::CodeGeneratorResponse_File() : ::google::protobuf::Message(), _internal_metadata_(NULL) { if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaults(); + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse_File(); } SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse.File) @@ -1410,37 +1118,35 @@ void CodeGeneratorResponse_File::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaults(); + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse_File(); return *internal_default_instance(); } -CodeGeneratorResponse_File* CodeGeneratorResponse_File::New(::google::protobuf::Arena* arena) const { - CodeGeneratorResponse_File* n = new CodeGeneratorResponse_File; - if (arena != NULL) { - arena->Own(n); - } - return n; -} void CodeGeneratorResponse_File::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse.File) - if (_has_bits_[0 / 32] & 7u) { - if (has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 7u) { + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - (*name_.UnsafeRawStringPointer())->clear(); + name_.UnsafeMutablePointer()->clear(); } - if (has_insertion_point()) { + if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(!insertion_point_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - (*insertion_point_.UnsafeRawStringPointer())->clear(); + insertion_point_.UnsafeMutablePointer()->clear(); } - if (has_content()) { + if (cached_has_bits & 0x00000004u) { GOOGLE_DCHECK(!content_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - (*content_.UnsafeRawStringPointer())->clear(); + content_.UnsafeMutablePointer()->clear(); } } _has_bits_.Clear(); @@ -1460,11 +1166,11 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream( // optional string name = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_name())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), + this->name().data(), static_cast<int>(this->name().length()), ::google::protobuf::internal::WireFormat::PARSE, "google.protobuf.compiler.CodeGeneratorResponse.File.name"); } else { @@ -1476,11 +1182,11 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream( // optional string insertion_point = 2; case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(18u)) { + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_insertion_point())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->insertion_point().data(), this->insertion_point().length(), + this->insertion_point().data(), static_cast<int>(this->insertion_point().length()), ::google::protobuf::internal::WireFormat::PARSE, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point"); } else { @@ -1492,11 +1198,11 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream( // optional string content = 15; case 15: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(122u)) { + static_cast< ::google::protobuf::uint8>(122u /* 122 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_content())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->content().data(), this->content().length(), + this->content().data(), static_cast<int>(this->content().length()), ::google::protobuf::internal::WireFormat::PARSE, "google.protobuf.compiler.CodeGeneratorResponse.File.content"); } else { @@ -1507,13 +1213,11 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -1537,7 +1241,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( // optional string name = 1; if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), + this->name().data(), static_cast<int>(this->name().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorResponse.File.name"); ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( @@ -1547,7 +1251,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( // optional string insertion_point = 2; if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->insertion_point().data(), this->insertion_point().length(), + this->insertion_point().data(), static_cast<int>(this->insertion_point().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point"); ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( @@ -1557,7 +1261,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( // optional string content = 15; if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->content().data(), this->content().length(), + this->content().data(), static_cast<int>(this->content().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorResponse.File.content"); ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( @@ -1566,13 +1270,14 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse.File) } ::google::protobuf::uint8* CodeGeneratorResponse_File::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { + (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse.File) ::google::protobuf::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1581,7 +1286,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( // optional string name = 1; if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), + this->name().data(), static_cast<int>(this->name().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorResponse.File.name"); target = @@ -1592,7 +1297,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( // optional string insertion_point = 2; if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->insertion_point().data(), this->insertion_point().length(), + this->insertion_point().data(), static_cast<int>(this->insertion_point().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point"); target = @@ -1603,7 +1308,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( // optional string content = 15; if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->content().data(), this->content().length(), + this->content().data(), static_cast<int>(this->content().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorResponse.File.content"); target = @@ -1613,7 +1318,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse.File) return target; @@ -1626,7 +1331,7 @@ size_t CodeGeneratorResponse_File::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } if (_has_bits_[0 / 32] & 7u) { // optional string name = 1; @@ -1720,215 +1425,25 @@ void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) { InternalSwap(other); } void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) { + using std::swap; name_.Swap(&other->name_); insertion_point_.Swap(&other->insertion_point_); content_.Swap(&other->content_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; -} - -#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(); -} -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) -} -#if LANG_CXX11 -void CodeGeneratorResponse_File::set_name(::std::string&& value) { - set_has_name(); - name_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.name) -} -#endif -void CodeGeneratorResponse_File::set_name(const char* value) { - GOOGLE_DCHECK(value != NULL); - 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() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.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(); -} -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) -} -#if LANG_CXX11 -void CodeGeneratorResponse_File::set_insertion_point(::std::string&& value) { - set_has_insertion_point(); - insertion_point_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) -} -#endif -void CodeGeneratorResponse_File::set_insertion_point(const char* value) { - GOOGLE_DCHECK(value != NULL); - 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() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.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) + return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; } -// 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(); -} -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) -} -#if LANG_CXX11 -void CodeGeneratorResponse_File::set_content(::std::string&& value) { - set_has_content(); - content_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.content) -} -#endif -void CodeGeneratorResponse_File::set_content(const char* value) { - GOOGLE_DCHECK(value != NULL); - 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() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.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) -} - -#endif // PROTOBUF_INLINE_NOT_IN_HEADERS // =================================================================== +void CodeGeneratorResponse::InitAsDefaultInstance() { +} #if !defined(_MSC_VER) || _MSC_VER >= 1900 const int CodeGeneratorResponse::kErrorFieldNumber; const int CodeGeneratorResponse::kFileFieldNumber; @@ -1937,7 +1452,7 @@ const int CodeGeneratorResponse::kFileFieldNumber; CodeGeneratorResponse::CodeGeneratorResponse() : ::google::protobuf::Message(), _internal_metadata_(NULL) { if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaults(); + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse(); } SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse) @@ -1976,29 +1491,27 @@ void CodeGeneratorResponse::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); + return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() { - protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaults(); + ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse(); return *internal_default_instance(); } -CodeGeneratorResponse* CodeGeneratorResponse::New(::google::protobuf::Arena* arena) const { - CodeGeneratorResponse* n = new CodeGeneratorResponse; - if (arena != NULL) { - arena->Own(n); - } - return n; -} void CodeGeneratorResponse::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + file_.Clear(); - if (has_error()) { + cached_has_bits = _has_bits_[0]; + if (cached_has_bits & 0x00000001u) { GOOGLE_DCHECK(!error_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - (*error_.UnsafeRawStringPointer())->clear(); + error_.UnsafeMutablePointer()->clear(); } _has_bits_.Clear(); _internal_metadata_.Clear(); @@ -2017,11 +1530,11 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream( // optional string error = 1; case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { DO_(::google::protobuf::internal::WireFormatLite::ReadString( input, this->mutable_error())); ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->error().data(), this->error().length(), + this->error().data(), static_cast<int>(this->error().length()), ::google::protobuf::internal::WireFormat::PARSE, "google.protobuf.compiler.CodeGeneratorResponse.error"); } else { @@ -2033,8 +1546,8 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream( // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; case 15: { if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(122u)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + static_cast< ::google::protobuf::uint8>(122u /* 122 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessage( input, add_file())); } else { goto handle_unusual; @@ -2044,13 +1557,11 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream( default: { handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + if (tag == 0) { goto success; } DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); + input, tag, _internal_metadata_.mutable_unknown_fields())); break; } } @@ -2074,7 +1585,7 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( // optional string error = 1; if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->error().data(), this->error().length(), + this->error().data(), static_cast<int>(this->error().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorResponse.error"); ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( @@ -2082,20 +1593,24 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( } // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; - for (unsigned int i = 0, n = this->file_size(); i < n; i++) { + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->file_size()); i < n; i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 15, this->file(i), output); + 15, + this->file(static_cast<int>(i)), + output); } if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); + _internal_metadata_.unknown_fields(), output); } // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse) } ::google::protobuf::uint8* CodeGeneratorResponse::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { + (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse) ::google::protobuf::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -2104,7 +1619,7 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( // optional string error = 1; if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->error().data(), this->error().length(), + this->error().data(), static_cast<int>(this->error().length()), ::google::protobuf::internal::WireFormat::SERIALIZE, "google.protobuf.compiler.CodeGeneratorResponse.error"); target = @@ -2113,15 +1628,16 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( } // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; - for (unsigned int i = 0, n = this->file_size(); i < n; i++) { + for (unsigned int i = 0, + n = static_cast<unsigned int>(this->file_size()); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - InternalWriteMessageNoVirtualToArray( - 15, this->file(i), deterministic, target); + InternalWriteMessageToArray( + 15, this->file(static_cast<int>(i)), deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); + _internal_metadata_.unknown_fields(), target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse) return target; @@ -2134,16 +1650,16 @@ size_t CodeGeneratorResponse::ByteSizeLong() const { if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); + _internal_metadata_.unknown_fields()); } // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; { - unsigned int count = this->file_size(); + unsigned int count = static_cast<unsigned int>(this->file_size()); total_size += 1UL * count; for (unsigned int i = 0; i < count; i++) { total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->file(i)); + ::google::protobuf::internal::WireFormatLite::MessageSize( + this->file(static_cast<int>(i))); } } @@ -2213,119 +1729,38 @@ void CodeGeneratorResponse::Swap(CodeGeneratorResponse* other) { InternalSwap(other); } void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { - file_.InternalSwap(&other->file_); + using std::swap; + CastToBase(&file_)->InternalSwap(CastToBase(&other->file_)); error_.Swap(&other->error_); - std::swap(_has_bits_[0], other->_has_bits_[0]); + swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); + swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; + return ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; } -#if PROTOBUF_INLINE_NOT_IN_HEADERS -// 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(); -} -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) -} -#if LANG_CXX11 -void CodeGeneratorResponse::set_error(::std::string&& value) { - set_has_error(); - error_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.error) -} -#endif -void CodeGeneratorResponse::set_error(const char* value) { - GOOGLE_DCHECK(value != NULL); - 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() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.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); +// @@protoc_insertion_point(namespace_scope) +} // namespace compiler +} // namespace protobuf +} // namespace google +namespace google { +namespace protobuf { +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::Version* Arena::Create< ::google::protobuf::compiler::Version >(Arena* arena) { + return Arena::CreateInternal< ::google::protobuf::compiler::Version >(arena); } -::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() { - // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file) - return file_.Add(); +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::CodeGeneratorRequest* Arena::Create< ::google::protobuf::compiler::CodeGeneratorRequest >(Arena* arena) { + return Arena::CreateInternal< ::google::protobuf::compiler::CodeGeneratorRequest >(arena); } -::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* -CodeGeneratorResponse::mutable_file() { - // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file) - return &file_; +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::CodeGeneratorResponse_File* Arena::Create< ::google::protobuf::compiler::CodeGeneratorResponse_File >(Arena* arena) { + return Arena::CreateInternal< ::google::protobuf::compiler::CodeGeneratorResponse_File >(arena); } -const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& -CodeGeneratorResponse::file() const { - // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file) - return file_; +template<> GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE ::google::protobuf::compiler::CodeGeneratorResponse* Arena::Create< ::google::protobuf::compiler::CodeGeneratorResponse >(Arena* arena) { + return Arena::CreateInternal< ::google::protobuf::compiler::CodeGeneratorResponse >(arena); } - -#endif // PROTOBUF_INLINE_NOT_IN_HEADERS - -// @@protoc_insertion_point(namespace_scope) - -} // namespace compiler } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 4f8befb6..a6c1300e 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -1,19 +1,19 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/compiler/plugin.proto -#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED -#define PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED +#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto_INCLUDED +#define PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto_INCLUDED #include <string> #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 3003000 +#if GOOGLE_PROTOBUF_VERSION < 3005000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -37,83 +37,35 @@ #ifdef minor #undef minor #endif + +namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto { +// Internal implementation detail -- do not use these members. +struct LIBPROTOC_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[4]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; + static const ::google::protobuf::uint32 offsets[]; +}; +void LIBPROTOC_EXPORT AddDescriptors(); +void LIBPROTOC_EXPORT InitDefaultsVersionImpl(); +void LIBPROTOC_EXPORT InitDefaultsVersion(); +void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorRequestImpl(); +void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorRequest(); +void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorResponse_FileImpl(); +void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorResponse_File(); +void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorResponseImpl(); +void LIBPROTOC_EXPORT InitDefaultsCodeGeneratorResponse(); +inline void LIBPROTOC_EXPORT InitDefaults() { + InitDefaultsVersion(); + InitDefaultsCodeGeneratorRequest(); + InitDefaultsCodeGeneratorResponse_File(); + InitDefaultsCodeGeneratorResponse(); +} +} // namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto namespace google { namespace protobuf { -class DescriptorProto; -class DescriptorProtoDefaultTypeInternal; -LIBPROTOC_EXPORT extern DescriptorProtoDefaultTypeInternal _DescriptorProto_default_instance_; -class DescriptorProto_ExtensionRange; -class DescriptorProto_ExtensionRangeDefaultTypeInternal; -LIBPROTOC_EXPORT extern DescriptorProto_ExtensionRangeDefaultTypeInternal _DescriptorProto_ExtensionRange_default_instance_; -class DescriptorProto_ReservedRange; -class DescriptorProto_ReservedRangeDefaultTypeInternal; -LIBPROTOC_EXPORT extern DescriptorProto_ReservedRangeDefaultTypeInternal _DescriptorProto_ReservedRange_default_instance_; -class EnumDescriptorProto; -class EnumDescriptorProtoDefaultTypeInternal; -LIBPROTOC_EXPORT extern EnumDescriptorProtoDefaultTypeInternal _EnumDescriptorProto_default_instance_; -class EnumOptions; -class EnumOptionsDefaultTypeInternal; -LIBPROTOC_EXPORT extern EnumOptionsDefaultTypeInternal _EnumOptions_default_instance_; -class EnumValueDescriptorProto; -class EnumValueDescriptorProtoDefaultTypeInternal; -LIBPROTOC_EXPORT extern EnumValueDescriptorProtoDefaultTypeInternal _EnumValueDescriptorProto_default_instance_; -class EnumValueOptions; -class EnumValueOptionsDefaultTypeInternal; -LIBPROTOC_EXPORT extern EnumValueOptionsDefaultTypeInternal _EnumValueOptions_default_instance_; -class FieldDescriptorProto; -class FieldDescriptorProtoDefaultTypeInternal; -LIBPROTOC_EXPORT extern FieldDescriptorProtoDefaultTypeInternal _FieldDescriptorProto_default_instance_; -class FieldOptions; -class FieldOptionsDefaultTypeInternal; -LIBPROTOC_EXPORT extern FieldOptionsDefaultTypeInternal _FieldOptions_default_instance_; -class FileDescriptorProto; -class FileDescriptorProtoDefaultTypeInternal; -LIBPROTOC_EXPORT extern FileDescriptorProtoDefaultTypeInternal _FileDescriptorProto_default_instance_; -class FileDescriptorSet; -class FileDescriptorSetDefaultTypeInternal; -LIBPROTOC_EXPORT extern FileDescriptorSetDefaultTypeInternal _FileDescriptorSet_default_instance_; -class FileOptions; -class FileOptionsDefaultTypeInternal; -LIBPROTOC_EXPORT extern FileOptionsDefaultTypeInternal _FileOptions_default_instance_; -class GeneratedCodeInfo; -class GeneratedCodeInfoDefaultTypeInternal; -LIBPROTOC_EXPORT extern GeneratedCodeInfoDefaultTypeInternal _GeneratedCodeInfo_default_instance_; -class GeneratedCodeInfo_Annotation; -class GeneratedCodeInfo_AnnotationDefaultTypeInternal; -LIBPROTOC_EXPORT extern GeneratedCodeInfo_AnnotationDefaultTypeInternal _GeneratedCodeInfo_Annotation_default_instance_; -class MessageOptions; -class MessageOptionsDefaultTypeInternal; -LIBPROTOC_EXPORT extern MessageOptionsDefaultTypeInternal _MessageOptions_default_instance_; -class MethodDescriptorProto; -class MethodDescriptorProtoDefaultTypeInternal; -LIBPROTOC_EXPORT extern MethodDescriptorProtoDefaultTypeInternal _MethodDescriptorProto_default_instance_; -class MethodOptions; -class MethodOptionsDefaultTypeInternal; -LIBPROTOC_EXPORT extern MethodOptionsDefaultTypeInternal _MethodOptions_default_instance_; -class OneofDescriptorProto; -class OneofDescriptorProtoDefaultTypeInternal; -LIBPROTOC_EXPORT extern OneofDescriptorProtoDefaultTypeInternal _OneofDescriptorProto_default_instance_; -class OneofOptions; -class OneofOptionsDefaultTypeInternal; -LIBPROTOC_EXPORT extern OneofOptionsDefaultTypeInternal _OneofOptions_default_instance_; -class ServiceDescriptorProto; -class ServiceDescriptorProtoDefaultTypeInternal; -LIBPROTOC_EXPORT extern ServiceDescriptorProtoDefaultTypeInternal _ServiceDescriptorProto_default_instance_; -class ServiceOptions; -class ServiceOptionsDefaultTypeInternal; -LIBPROTOC_EXPORT extern ServiceOptionsDefaultTypeInternal _ServiceOptions_default_instance_; -class SourceCodeInfo; -class SourceCodeInfoDefaultTypeInternal; -LIBPROTOC_EXPORT extern SourceCodeInfoDefaultTypeInternal _SourceCodeInfo_default_instance_; -class SourceCodeInfo_Location; -class SourceCodeInfo_LocationDefaultTypeInternal; -LIBPROTOC_EXPORT extern SourceCodeInfo_LocationDefaultTypeInternal _SourceCodeInfo_Location_default_instance_; -class UninterpretedOption; -class UninterpretedOptionDefaultTypeInternal; -LIBPROTOC_EXPORT extern UninterpretedOptionDefaultTypeInternal _UninterpretedOption_default_instance_; -class UninterpretedOption_NamePart; -class UninterpretedOption_NamePartDefaultTypeInternal; -LIBPROTOC_EXPORT extern UninterpretedOption_NamePartDefaultTypeInternal _UninterpretedOption_NamePart_default_instance_; namespace compiler { class CodeGeneratorRequest; class CodeGeneratorRequestDefaultTypeInternal; @@ -130,25 +82,18 @@ LIBPROTOC_EXPORT extern VersionDefaultTypeInternal _Version_default_instance_; } // namespace compiler } // namespace protobuf } // namespace google - +namespace google { +namespace protobuf { +template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorRequest* Arena::Create< ::google::protobuf::compiler::CodeGeneratorRequest>(Arena*); +template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorResponse* Arena::Create< ::google::protobuf::compiler::CodeGeneratorResponse>(Arena*); +template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::CodeGeneratorResponse_File* Arena::Create< ::google::protobuf::compiler::CodeGeneratorResponse_File>(Arena*); +template<> LIBPROTOC_EXPORT ::google::protobuf::compiler::Version* Arena::Create< ::google::protobuf::compiler::Version>(Arena*); +} // namespace protobuf +} // namespace google namespace google { namespace protobuf { namespace compiler { -namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto { -// Internal implementation detail -- do not call these. -struct LIBPROTOC_EXPORT TableStruct { - static const ::google::protobuf::internal::ParseTableField entries[]; - static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; - static const ::google::protobuf::internal::ParseTable schema[]; - static const ::google::protobuf::uint32 offsets[]; - static void InitDefaultsImpl(); - static void Shutdown(); -}; -void LIBPROTOC_EXPORT AddDescriptors(); -void LIBPROTOC_EXPORT InitDefaults(); -} // namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto - // =================================================================== class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.Version) */ { @@ -162,11 +107,24 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ CopyFrom(from); return *this; } + #if LANG_CXX11 + Version(Version&& from) noexcept + : Version() { + *this = ::std::move(from); + } + inline Version& operator=(Version&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { return _internal_metadata_.unknown_fields(); } - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { return _internal_metadata_.mutable_unknown_fields(); } @@ -174,6 +132,7 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ static const ::google::protobuf::Descriptor* descriptor(); static const Version& default_instance(); + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Version* internal_default_instance() { return reinterpret_cast<const Version*>( &_Version_default_instance_); @@ -182,12 +141,19 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ 0; void Swap(Version* other); + friend void swap(Version& a, Version& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- - inline Version* New() const PROTOBUF_FINAL { return New(NULL); } + inline Version* New() const PROTOBUF_FINAL { + return ::google::protobuf::Arena::Create<Version>(NULL); + } - Version* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; + Version* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL { + return ::google::protobuf::Arena::Create<Version>(arena); + } void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; void CopyFrom(const Version& from); @@ -277,7 +243,8 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ ::google::protobuf::int32 major_; ::google::protobuf::int32 minor_; ::google::protobuf::int32 patch_; - friend struct protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend void ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsVersionImpl(); }; // ------------------------------------------------------------------- @@ -292,11 +259,24 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message CopyFrom(from); return *this; } + #if LANG_CXX11 + CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept + : CodeGeneratorRequest() { + *this = ::std::move(from); + } + inline CodeGeneratorRequest& operator=(CodeGeneratorRequest&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { return _internal_metadata_.unknown_fields(); } - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { return _internal_metadata_.mutable_unknown_fields(); } @@ -304,6 +284,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message static const ::google::protobuf::Descriptor* descriptor(); static const CodeGeneratorRequest& default_instance(); + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const CodeGeneratorRequest* internal_default_instance() { return reinterpret_cast<const CodeGeneratorRequest*>( &_CodeGeneratorRequest_default_instance_); @@ -312,12 +293,19 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message 1; void Swap(CodeGeneratorRequest* other); + friend void swap(CodeGeneratorRequest& a, CodeGeneratorRequest& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- - inline CodeGeneratorRequest* New() const PROTOBUF_FINAL { return New(NULL); } + inline CodeGeneratorRequest* New() const PROTOBUF_FINAL { + return ::google::protobuf::Arena::Create<CodeGeneratorRequest>(NULL); + } - CodeGeneratorRequest* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; + CodeGeneratorRequest* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL { + return ::google::protobuf::Arena::Create<CodeGeneratorRequest>(arena); + } void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; void CopyFrom(const CodeGeneratorRequest& from); @@ -379,11 +367,11 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message int proto_file_size() const; void clear_proto_file(); static const int kProtoFileFieldNumber = 15; - const ::google::protobuf::FileDescriptorProto& proto_file(int index) const; ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index); - ::google::protobuf::FileDescriptorProto* add_proto_file(); ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* mutable_proto_file(); + const ::google::protobuf::FileDescriptorProto& proto_file(int index) const; + ::google::protobuf::FileDescriptorProto* add_proto_file(); const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& proto_file() const; @@ -407,8 +395,8 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message void clear_compiler_version(); static const int kCompilerVersionFieldNumber = 3; const ::google::protobuf::compiler::Version& compiler_version() const; - ::google::protobuf::compiler::Version* mutable_compiler_version(); ::google::protobuf::compiler::Version* release_compiler_version(); + ::google::protobuf::compiler::Version* mutable_compiler_version(); void set_allocated_compiler_version(::google::protobuf::compiler::Version* compiler_version); // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) @@ -425,7 +413,8 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_; ::google::protobuf::internal::ArenaStringPtr parameter_; ::google::protobuf::compiler::Version* compiler_version_; - friend struct protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend void ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorRequestImpl(); }; // ------------------------------------------------------------------- @@ -440,11 +429,24 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M CopyFrom(from); return *this; } + #if LANG_CXX11 + CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept + : CodeGeneratorResponse_File() { + *this = ::std::move(from); + } + inline CodeGeneratorResponse_File& operator=(CodeGeneratorResponse_File&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { return _internal_metadata_.unknown_fields(); } - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { return _internal_metadata_.mutable_unknown_fields(); } @@ -452,6 +454,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M static const ::google::protobuf::Descriptor* descriptor(); static const CodeGeneratorResponse_File& default_instance(); + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const CodeGeneratorResponse_File* internal_default_instance() { return reinterpret_cast<const CodeGeneratorResponse_File*>( &_CodeGeneratorResponse_File_default_instance_); @@ -460,12 +463,19 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M 2; void Swap(CodeGeneratorResponse_File* other); + friend void swap(CodeGeneratorResponse_File& a, CodeGeneratorResponse_File& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- - inline CodeGeneratorResponse_File* New() const PROTOBUF_FINAL { return New(NULL); } + inline CodeGeneratorResponse_File* New() const PROTOBUF_FINAL { + return ::google::protobuf::Arena::Create<CodeGeneratorResponse_File>(NULL); + } - CodeGeneratorResponse_File* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; + CodeGeneratorResponse_File* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL { + return ::google::protobuf::Arena::Create<CodeGeneratorResponse_File>(arena); + } void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; void CopyFrom(const CodeGeneratorResponse_File& from); @@ -561,7 +571,8 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::internal::ArenaStringPtr insertion_point_; ::google::protobuf::internal::ArenaStringPtr content_; - friend struct protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend void ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponse_FileImpl(); }; // ------------------------------------------------------------------- @@ -576,11 +587,24 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag CopyFrom(from); return *this; } + #if LANG_CXX11 + CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept + : CodeGeneratorResponse() { + *this = ::std::move(from); + } + inline CodeGeneratorResponse& operator=(CodeGeneratorResponse&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { return _internal_metadata_.unknown_fields(); } - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { return _internal_metadata_.mutable_unknown_fields(); } @@ -588,6 +612,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag static const ::google::protobuf::Descriptor* descriptor(); static const CodeGeneratorResponse& default_instance(); + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const CodeGeneratorResponse* internal_default_instance() { return reinterpret_cast<const CodeGeneratorResponse*>( &_CodeGeneratorResponse_default_instance_); @@ -596,12 +621,19 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag 3; void Swap(CodeGeneratorResponse* other); + friend void swap(CodeGeneratorResponse& a, CodeGeneratorResponse& b) { + a.Swap(&b); + } // implements Message ---------------------------------------------- - inline CodeGeneratorResponse* New() const PROTOBUF_FINAL { return New(NULL); } + inline CodeGeneratorResponse* New() const PROTOBUF_FINAL { + return ::google::protobuf::Arena::Create<CodeGeneratorResponse>(NULL); + } - CodeGeneratorResponse* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; + CodeGeneratorResponse* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL { + return ::google::protobuf::Arena::Create<CodeGeneratorResponse>(arena); + } void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; void CopyFrom(const CodeGeneratorResponse& from); @@ -643,11 +675,11 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag int file_size() const; void clear_file(); static const int kFileFieldNumber = 15; - 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(); ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* mutable_file(); + const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const; + ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file(); const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& file() const; @@ -676,14 +708,18 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_; ::google::protobuf::internal::ArenaStringPtr error_; - friend struct protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend struct ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::TableStruct; + friend void ::protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::InitDefaultsCodeGeneratorResponseImpl(); }; // =================================================================== // =================================================================== -#if !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ // Version // optional int32 major = 1; @@ -961,26 +997,23 @@ inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* paramet inline int CodeGeneratorRequest::proto_file_size() const { return proto_file_.size(); } -inline void CodeGeneratorRequest::clear_proto_file() { - proto_file_.Clear(); -} -inline 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); -} inline ::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); } -inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() { - // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file) - return proto_file_.Add(); -} inline ::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_; } +inline 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); +} +inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() { + // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file) + return proto_file_.Add(); +} inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& CodeGeneratorRequest::proto_file() const { // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file) @@ -998,21 +1031,14 @@ inline void CodeGeneratorRequest::clear_has_compiler_version() { _has_bits_[0] &= ~0x00000002u; } inline void CodeGeneratorRequest::clear_compiler_version() { - if (compiler_version_ != NULL) compiler_version_->::google::protobuf::compiler::Version::Clear(); + if (compiler_version_ != NULL) compiler_version_->Clear(); clear_has_compiler_version(); } inline const ::google::protobuf::compiler::Version& CodeGeneratorRequest::compiler_version() const { + const ::google::protobuf::compiler::Version* p = compiler_version_; // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) - return compiler_version_ != NULL ? *compiler_version_ - : *::google::protobuf::compiler::Version::internal_default_instance(); -} -inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() { - set_has_compiler_version(); - if (compiler_version_ == NULL) { - compiler_version_ = new ::google::protobuf::compiler::Version; - } - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) - return compiler_version_; + return p != NULL ? *p : *reinterpret_cast<const ::google::protobuf::compiler::Version*>( + &::google::protobuf::compiler::_Version_default_instance_); } inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::release_compiler_version() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) @@ -1021,14 +1047,31 @@ inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::release_comp compiler_version_ = NULL; return temp; } +inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() { + set_has_compiler_version(); + if (compiler_version_ == NULL) { + compiler_version_ = ::google::protobuf::Arena::Create< ::google::protobuf::compiler::Version >( + GetArenaNoVirtual()); + } + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) + return compiler_version_; +} inline void CodeGeneratorRequest::set_allocated_compiler_version(::google::protobuf::compiler::Version* compiler_version) { - delete compiler_version_; - compiler_version_ = compiler_version; + ::google::protobuf::Arena* message_arena = GetArenaNoVirtual(); + if (message_arena == NULL) { + delete compiler_version_; + } if (compiler_version) { + ::google::protobuf::Arena* submessage_arena = NULL; + if (message_arena != submessage_arena) { + compiler_version = ::google::protobuf::internal::GetOwnedMessage( + message_arena, compiler_version, submessage_arena); + } set_has_compiler_version(); } else { clear_has_compiler_version(); } + compiler_version_ = compiler_version; // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) } @@ -1299,30 +1342,32 @@ inline int CodeGeneratorResponse::file_size() const { inline void CodeGeneratorResponse::clear_file() { file_.Clear(); } -inline 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); -} inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) { // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file) return file_.Mutable(index); } -inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() { - // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file) - return file_.Add(); -} inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* CodeGeneratorResponse::mutable_file() { // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file) return &file_; } +inline 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); +} +inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() { + // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file) + return file_.Add(); +} inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& CodeGeneratorResponse::file() const { // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file) return file_; } -#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ // ------------------------------------------------------------------- // ------------------------------------------------------------------- @@ -1332,11 +1377,10 @@ CodeGeneratorResponse::file() const { // @@protoc_insertion_point(namespace_scope) - } // namespace compiler } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) -#endif // PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED +#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 f04dc73c..5b557452 100644 --- a/src/google/protobuf/compiler/plugin.proto +++ b/src/google/protobuf/compiler/plugin.proto @@ -91,6 +91,7 @@ message CodeGeneratorRequest { // The version number of protocol compiler. optional Version compiler_version = 3; + } // The plugin writes an encoded CodeGeneratorResponse to stdout. diff --git a/src/google/protobuf/compiler/profile.pb.cc b/src/google/protobuf/compiler/profile.pb.cc deleted file mode 100644 index c185e4f9..00000000 --- a/src/google/protobuf/compiler/profile.pb.cc +++ /dev/null @@ -1,1442 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/compiler/profile.proto - -#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION -#include <google/protobuf/compiler/profile.pb.h> - -#include <algorithm> - -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/port.h> -#include <google/protobuf/stubs/once.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/wire_format_lite_inl.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/generated_message_reflection.h> -#include <google/protobuf/reflection_ops.h> -#include <google/protobuf/wire_format.h> -// @@protoc_insertion_point(includes) - -namespace google { -namespace protobuf { -namespace compiler { -class FieldAccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<FieldAccessInfo> { -} _FieldAccessInfo_default_instance_; -class MessageAccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<MessageAccessInfo> { -} _MessageAccessInfo_default_instance_; -class AccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<AccessInfo> { -} _AccessInfo_default_instance_; - -namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto { - - -namespace { - -::google::protobuf::Metadata file_level_metadata[3]; - -} // namespace - -PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField - const TableStruct::entries[] = { - {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, -}; - -PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField - const TableStruct::aux[] = { - ::google::protobuf::internal::AuxillaryParseTableField(), -}; -PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const - TableStruct::schema[] = { - { NULL, NULL, 0, -1, -1, false }, - { NULL, NULL, 0, -1, -1, false }, - { NULL, NULL, 0, -1, -1, false }, -}; - -const ::google::protobuf::uint32 TableStruct::offsets[] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, _has_bits_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, getters_count_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, setters_count_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, configs_count_), - 0, - 1, - 2, - 3, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, _has_bits_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, name_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, count_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, field_), - 0, - 1, - ~0u, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AccessInfo, _has_bits_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AccessInfo, _internal_metadata_), - ~0u, // no _extensions_ - ~0u, // no _oneof_case_ - ~0u, // no _weak_field_map_ - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AccessInfo, message_), - ~0u, -}; - -static const ::google::protobuf::internal::MigrationSchema schemas[] = { - { 0, 9, sizeof(FieldAccessInfo)}, - { 13, 21, sizeof(MessageAccessInfo)}, - { 24, 30, sizeof(AccessInfo)}, -}; - -static ::google::protobuf::Message const * const file_default_instances[] = { - reinterpret_cast<const ::google::protobuf::Message*>(&_FieldAccessInfo_default_instance_), - reinterpret_cast<const ::google::protobuf::Message*>(&_MessageAccessInfo_default_instance_), - reinterpret_cast<const ::google::protobuf::Message*>(&_AccessInfo_default_instance_), -}; - -namespace { - -void protobuf_AssignDescriptors() { - AddDescriptors(); - ::google::protobuf::MessageFactory* factory = NULL; - AssignDescriptors( - "google/protobuf/compiler/profile.proto", schemas, file_default_instances, TableStruct::offsets, factory, - file_level_metadata, NULL, NULL); -} - -void protobuf_AssignDescriptorsOnce() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors); -} - -void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; -void protobuf_RegisterTypes(const ::std::string&) { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 3); -} - -} // namespace - -void TableStruct::Shutdown() { - _FieldAccessInfo_default_instance_.Shutdown(); - delete file_level_metadata[0].reflection; - _MessageAccessInfo_default_instance_.Shutdown(); - delete file_level_metadata[1].reflection; - _AccessInfo_default_instance_.Shutdown(); - delete file_level_metadata[2].reflection; -} - -void TableStruct::InitDefaultsImpl() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - ::google::protobuf::internal::InitProtobufDefaults(); - _FieldAccessInfo_default_instance_.DefaultConstruct(); - _MessageAccessInfo_default_instance_.DefaultConstruct(); - _AccessInfo_default_instance_.DefaultConstruct(); -} - -void InitDefaults() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl); -} -void AddDescriptorsImpl() { - InitDefaults(); - static const char descriptor[] = { - "\n&google/protobuf/compiler/profile.proto" - "\022\030google.protobuf.compiler\"d\n\017FieldAcces" - "sInfo\022\014\n\004name\030\001 \001(\t\022\025\n\rgetters_count\030\002 \001" - "(\004\022\025\n\rsetters_count\030\003 \001(\004\022\025\n\rconfigs_cou" - "nt\030\004 \001(\004\"j\n\021MessageAccessInfo\022\014\n\004name\030\001 " - "\001(\t\022\r\n\005count\030\002 \001(\004\0228\n\005field\030\003 \003(\0132).goog" - "le.protobuf.compiler.FieldAccessInfo\"J\n\n" - "AccessInfo\022<\n\007message\030\001 \003(\0132+.google.pro" - "tobuf.compiler.MessageAccessInfo" - }; - ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - descriptor, 352); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( - "google/protobuf/compiler/profile.proto", &protobuf_RegisterTypes); - ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); -} - -void AddDescriptors() { - static GOOGLE_PROTOBUF_DECLARE_ONCE(once); - ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl); -} -// Force AddDescriptors() to be called at static initialization time. -struct StaticDescriptorInitializer { - StaticDescriptorInitializer() { - AddDescriptors(); - } -} static_descriptor_initializer; - -} // namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto - - -// =================================================================== - -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int FieldAccessInfo::kNameFieldNumber; -const int FieldAccessInfo::kGettersCountFieldNumber; -const int FieldAccessInfo::kSettersCountFieldNumber; -const int FieldAccessInfo::kConfigsCountFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -FieldAccessInfo::FieldAccessInfo() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); - } - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.compiler.FieldAccessInfo) -} -FieldAccessInfo::FieldAccessInfo(const FieldAccessInfo& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL), - _has_bits_(from._has_bits_), - _cached_size_(0) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (from.has_name()) { - name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); - } - ::memcpy(&getters_count_, &from.getters_count_, - reinterpret_cast<char*>(&configs_count_) - - reinterpret_cast<char*>(&getters_count_) + sizeof(configs_count_)); - // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.FieldAccessInfo) -} - -void FieldAccessInfo::SharedCtor() { - _cached_size_ = 0; - name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - ::memset(&getters_count_, 0, reinterpret_cast<char*>(&configs_count_) - - reinterpret_cast<char*>(&getters_count_) + sizeof(configs_count_)); -} - -FieldAccessInfo::~FieldAccessInfo() { - // @@protoc_insertion_point(destructor:google.protobuf.compiler.FieldAccessInfo) - SharedDtor(); -} - -void FieldAccessInfo::SharedDtor() { - name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -void FieldAccessInfo::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* FieldAccessInfo::descriptor() { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; -} - -const FieldAccessInfo& FieldAccessInfo::default_instance() { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); - return *internal_default_instance(); -} - -FieldAccessInfo* FieldAccessInfo::New(::google::protobuf::Arena* arena) const { - FieldAccessInfo* n = new FieldAccessInfo; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void FieldAccessInfo::Clear() { -// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.FieldAccessInfo) - if (has_name()) { - GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - (*name_.UnsafeRawStringPointer())->clear(); - } - if (_has_bits_[0 / 32] & 14u) { - ::memset(&getters_count_, 0, reinterpret_cast<char*>(&configs_count_) - - reinterpret_cast<char*>(&getters_count_) + sizeof(configs_count_)); - } - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -bool FieldAccessInfo::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:google.protobuf.compiler.FieldAccessInfo) - for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE, - "google.protobuf.compiler.FieldAccessInfo.name"); - } else { - goto handle_unusual; - } - break; - } - - // optional uint64 getters_count = 2; - case 2: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { - set_has_getters_count(); - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( - input, &getters_count_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint64 setters_count = 3; - case 3: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(24u)) { - set_has_setters_count(); - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( - input, &setters_count_))); - } else { - goto handle_unusual; - } - break; - } - - // optional uint64 configs_count = 4; - case 4: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(32u)) { - set_has_configs_count(); - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( - input, &configs_count_))); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - goto success; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:google.protobuf.compiler.FieldAccessInfo) - return true; -failure: - // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.FieldAccessInfo) - return false; -#undef DO_ -} - -void FieldAccessInfo::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.FieldAccessInfo) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional string name = 1; - if (cached_has_bits & 0x00000001u) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "google.protobuf.compiler.FieldAccessInfo.name"); - ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->name(), output); - } - - // optional uint64 getters_count = 2; - if (cached_has_bits & 0x00000002u) { - ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->getters_count(), output); - } - - // optional uint64 setters_count = 3; - if (cached_has_bits & 0x00000004u) { - ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->setters_count(), output); - } - - // optional uint64 configs_count = 4; - if (cached_has_bits & 0x00000008u) { - ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->configs_count(), output); - } - - if (_internal_metadata_.have_unknown_fields()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } - // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.FieldAccessInfo) -} - -::google::protobuf::uint8* FieldAccessInfo::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.FieldAccessInfo) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional string name = 1; - if (cached_has_bits & 0x00000001u) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "google.protobuf.compiler.FieldAccessInfo.name"); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // optional uint64 getters_count = 2; - if (cached_has_bits & 0x00000002u) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->getters_count(), target); - } - - // optional uint64 setters_count = 3; - if (cached_has_bits & 0x00000004u) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->setters_count(), target); - } - - // optional uint64 configs_count = 4; - if (cached_has_bits & 0x00000008u) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->configs_count(), target); - } - - if (_internal_metadata_.have_unknown_fields()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.FieldAccessInfo) - return target; -} - -size_t FieldAccessInfo::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.FieldAccessInfo) - size_t total_size = 0; - - if (_internal_metadata_.have_unknown_fields()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - if (_has_bits_[0 / 32] & 15u) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional uint64 getters_count = 2; - if (has_getters_count()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt64Size( - this->getters_count()); - } - - // optional uint64 setters_count = 3; - if (has_setters_count()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt64Size( - this->setters_count()); - } - - // optional uint64 configs_count = 4; - if (has_configs_count()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt64Size( - this->configs_count()); - } - - } - int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = cached_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void FieldAccessInfo::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.FieldAccessInfo) - GOOGLE_DCHECK_NE(&from, this); - const FieldAccessInfo* source = - ::google::protobuf::internal::DynamicCastToGenerated<const FieldAccessInfo>( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.FieldAccessInfo) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.FieldAccessInfo) - MergeFrom(*source); - } -} - -void FieldAccessInfo::MergeFrom(const FieldAccessInfo& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.FieldAccessInfo) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 15u) { - if (cached_has_bits & 0x00000001u) { - set_has_name(); - name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); - } - if (cached_has_bits & 0x00000002u) { - getters_count_ = from.getters_count_; - } - if (cached_has_bits & 0x00000004u) { - setters_count_ = from.setters_count_; - } - if (cached_has_bits & 0x00000008u) { - configs_count_ = from.configs_count_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void FieldAccessInfo::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.FieldAccessInfo) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void FieldAccessInfo::CopyFrom(const FieldAccessInfo& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.FieldAccessInfo) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool FieldAccessInfo::IsInitialized() const { - return true; -} - -void FieldAccessInfo::Swap(FieldAccessInfo* other) { - if (other == this) return; - InternalSwap(other); -} -void FieldAccessInfo::InternalSwap(FieldAccessInfo* other) { - name_.Swap(&other->name_); - std::swap(getters_count_, other->getters_count_); - std::swap(setters_count_, other->setters_count_); - std::swap(configs_count_, other->configs_count_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); -} - -::google::protobuf::Metadata FieldAccessInfo::GetMetadata() const { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages]; -} - -#if PROTOBUF_INLINE_NOT_IN_HEADERS -// FieldAccessInfo - -// optional string name = 1; -bool FieldAccessInfo::has_name() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -void FieldAccessInfo::set_has_name() { - _has_bits_[0] |= 0x00000001u; -} -void FieldAccessInfo::clear_has_name() { - _has_bits_[0] &= ~0x00000001u; -} -void FieldAccessInfo::clear_name() { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - clear_has_name(); -} -const ::std::string& FieldAccessInfo::name() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.name) - return name_.GetNoArena(); -} -void FieldAccessInfo::set_name(const ::std::string& value) { - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.name) -} -#if LANG_CXX11 -void FieldAccessInfo::set_name(::std::string&& value) { - set_has_name(); - name_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.FieldAccessInfo.name) -} -#endif -void FieldAccessInfo::set_name(const char* value) { - GOOGLE_DCHECK(value != NULL); - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.FieldAccessInfo.name) -} -void FieldAccessInfo::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.FieldAccessInfo.name) -} -::std::string* FieldAccessInfo::mutable_name() { - set_has_name(); - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.FieldAccessInfo.name) - return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -::std::string* FieldAccessInfo::release_name() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.FieldAccessInfo.name) - clear_has_name(); - return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -void FieldAccessInfo::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.FieldAccessInfo.name) -} - -// optional uint64 getters_count = 2; -bool FieldAccessInfo::has_getters_count() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -void FieldAccessInfo::set_has_getters_count() { - _has_bits_[0] |= 0x00000002u; -} -void FieldAccessInfo::clear_has_getters_count() { - _has_bits_[0] &= ~0x00000002u; -} -void FieldAccessInfo::clear_getters_count() { - getters_count_ = GOOGLE_ULONGLONG(0); - clear_has_getters_count(); -} -::google::protobuf::uint64 FieldAccessInfo::getters_count() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.getters_count) - return getters_count_; -} -void FieldAccessInfo::set_getters_count(::google::protobuf::uint64 value) { - set_has_getters_count(); - getters_count_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.getters_count) -} - -// optional uint64 setters_count = 3; -bool FieldAccessInfo::has_setters_count() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -void FieldAccessInfo::set_has_setters_count() { - _has_bits_[0] |= 0x00000004u; -} -void FieldAccessInfo::clear_has_setters_count() { - _has_bits_[0] &= ~0x00000004u; -} -void FieldAccessInfo::clear_setters_count() { - setters_count_ = GOOGLE_ULONGLONG(0); - clear_has_setters_count(); -} -::google::protobuf::uint64 FieldAccessInfo::setters_count() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.setters_count) - return setters_count_; -} -void FieldAccessInfo::set_setters_count(::google::protobuf::uint64 value) { - set_has_setters_count(); - setters_count_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.setters_count) -} - -// optional uint64 configs_count = 4; -bool FieldAccessInfo::has_configs_count() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -void FieldAccessInfo::set_has_configs_count() { - _has_bits_[0] |= 0x00000008u; -} -void FieldAccessInfo::clear_has_configs_count() { - _has_bits_[0] &= ~0x00000008u; -} -void FieldAccessInfo::clear_configs_count() { - configs_count_ = GOOGLE_ULONGLONG(0); - clear_has_configs_count(); -} -::google::protobuf::uint64 FieldAccessInfo::configs_count() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.configs_count) - return configs_count_; -} -void FieldAccessInfo::set_configs_count(::google::protobuf::uint64 value) { - set_has_configs_count(); - configs_count_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.configs_count) -} - -#endif // PROTOBUF_INLINE_NOT_IN_HEADERS - -// =================================================================== - -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int MessageAccessInfo::kNameFieldNumber; -const int MessageAccessInfo::kCountFieldNumber; -const int MessageAccessInfo::kFieldFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -MessageAccessInfo::MessageAccessInfo() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); - } - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.compiler.MessageAccessInfo) -} -MessageAccessInfo::MessageAccessInfo(const MessageAccessInfo& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL), - _has_bits_(from._has_bits_), - _cached_size_(0), - field_(from.field_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (from.has_name()) { - name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); - } - count_ = from.count_; - // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.MessageAccessInfo) -} - -void MessageAccessInfo::SharedCtor() { - _cached_size_ = 0; - name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - count_ = GOOGLE_ULONGLONG(0); -} - -MessageAccessInfo::~MessageAccessInfo() { - // @@protoc_insertion_point(destructor:google.protobuf.compiler.MessageAccessInfo) - SharedDtor(); -} - -void MessageAccessInfo::SharedDtor() { - name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} - -void MessageAccessInfo::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* MessageAccessInfo::descriptor() { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; -} - -const MessageAccessInfo& MessageAccessInfo::default_instance() { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); - return *internal_default_instance(); -} - -MessageAccessInfo* MessageAccessInfo::New(::google::protobuf::Arena* arena) const { - MessageAccessInfo* n = new MessageAccessInfo; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void MessageAccessInfo::Clear() { -// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.MessageAccessInfo) - field_.Clear(); - if (has_name()) { - GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - (*name_.UnsafeRawStringPointer())->clear(); - } - count_ = GOOGLE_ULONGLONG(0); - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -bool MessageAccessInfo::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:google.protobuf.compiler.MessageAccessInfo) - for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // optional string name = 1; - case 1: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_name())); - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::PARSE, - "google.protobuf.compiler.MessageAccessInfo.name"); - } else { - goto handle_unusual; - } - break; - } - - // optional uint64 count = 2; - case 2: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(16u)) { - set_has_count(); - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( - input, &count_))); - } else { - goto handle_unusual; - } - break; - } - - // repeated .google.protobuf.compiler.FieldAccessInfo field = 3; - case 3: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(26u)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_field())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - goto success; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:google.protobuf.compiler.MessageAccessInfo) - return true; -failure: - // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.MessageAccessInfo) - return false; -#undef DO_ -} - -void MessageAccessInfo::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.MessageAccessInfo) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional string name = 1; - if (cached_has_bits & 0x00000001u) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "google.protobuf.compiler.MessageAccessInfo.name"); - ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( - 1, this->name(), output); - } - - // optional uint64 count = 2; - if (cached_has_bits & 0x00000002u) { - ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->count(), output); - } - - // repeated .google.protobuf.compiler.FieldAccessInfo field = 3; - for (unsigned int i = 0, n = this->field_size(); i < n; i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 3, this->field(i), output); - } - - if (_internal_metadata_.have_unknown_fields()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } - // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.MessageAccessInfo) -} - -::google::protobuf::uint8* MessageAccessInfo::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.MessageAccessInfo) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - cached_has_bits = _has_bits_[0]; - // optional string name = 1; - if (cached_has_bits & 0x00000001u) { - ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( - this->name().data(), this->name().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE, - "google.protobuf.compiler.MessageAccessInfo.name"); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 1, this->name(), target); - } - - // optional uint64 count = 2; - if (cached_has_bits & 0x00000002u) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->count(), target); - } - - // repeated .google.protobuf.compiler.FieldAccessInfo field = 3; - for (unsigned int i = 0, n = this->field_size(); i < n; i++) { - target = ::google::protobuf::internal::WireFormatLite:: - InternalWriteMessageNoVirtualToArray( - 3, this->field(i), deterministic, target); - } - - if (_internal_metadata_.have_unknown_fields()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.MessageAccessInfo) - return target; -} - -size_t MessageAccessInfo::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.MessageAccessInfo) - size_t total_size = 0; - - if (_internal_metadata_.have_unknown_fields()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - // repeated .google.protobuf.compiler.FieldAccessInfo field = 3; - { - unsigned int count = this->field_size(); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->field(i)); - } - } - - if (_has_bits_[0 / 32] & 3u) { - // optional string name = 1; - if (has_name()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->name()); - } - - // optional uint64 count = 2; - if (has_count()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt64Size( - this->count()); - } - - } - int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = cached_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void MessageAccessInfo::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.MessageAccessInfo) - GOOGLE_DCHECK_NE(&from, this); - const MessageAccessInfo* source = - ::google::protobuf::internal::DynamicCastToGenerated<const MessageAccessInfo>( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.MessageAccessInfo) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.MessageAccessInfo) - MergeFrom(*source); - } -} - -void MessageAccessInfo::MergeFrom(const MessageAccessInfo& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.MessageAccessInfo) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - field_.MergeFrom(from.field_); - cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 3u) { - if (cached_has_bits & 0x00000001u) { - set_has_name(); - name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); - } - if (cached_has_bits & 0x00000002u) { - count_ = from.count_; - } - _has_bits_[0] |= cached_has_bits; - } -} - -void MessageAccessInfo::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.MessageAccessInfo) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void MessageAccessInfo::CopyFrom(const MessageAccessInfo& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.MessageAccessInfo) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool MessageAccessInfo::IsInitialized() const { - return true; -} - -void MessageAccessInfo::Swap(MessageAccessInfo* other) { - if (other == this) return; - InternalSwap(other); -} -void MessageAccessInfo::InternalSwap(MessageAccessInfo* other) { - field_.InternalSwap(&other->field_); - name_.Swap(&other->name_); - std::swap(count_, other->count_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); -} - -::google::protobuf::Metadata MessageAccessInfo::GetMetadata() const { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages]; -} - -#if PROTOBUF_INLINE_NOT_IN_HEADERS -// MessageAccessInfo - -// optional string name = 1; -bool MessageAccessInfo::has_name() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -void MessageAccessInfo::set_has_name() { - _has_bits_[0] |= 0x00000001u; -} -void MessageAccessInfo::clear_has_name() { - _has_bits_[0] &= ~0x00000001u; -} -void MessageAccessInfo::clear_name() { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - clear_has_name(); -} -const ::std::string& MessageAccessInfo::name() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.name) - return name_.GetNoArena(); -} -void MessageAccessInfo::set_name(const ::std::string& value) { - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.name) -} -#if LANG_CXX11 -void MessageAccessInfo::set_name(::std::string&& value) { - set_has_name(); - name_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.MessageAccessInfo.name) -} -#endif -void MessageAccessInfo::set_name(const char* value) { - GOOGLE_DCHECK(value != NULL); - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.MessageAccessInfo.name) -} -void MessageAccessInfo::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.MessageAccessInfo.name) -} -::std::string* MessageAccessInfo::mutable_name() { - set_has_name(); - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.name) - return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -::std::string* MessageAccessInfo::release_name() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.MessageAccessInfo.name) - clear_has_name(); - return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -void MessageAccessInfo::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.MessageAccessInfo.name) -} - -// optional uint64 count = 2; -bool MessageAccessInfo::has_count() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -void MessageAccessInfo::set_has_count() { - _has_bits_[0] |= 0x00000002u; -} -void MessageAccessInfo::clear_has_count() { - _has_bits_[0] &= ~0x00000002u; -} -void MessageAccessInfo::clear_count() { - count_ = GOOGLE_ULONGLONG(0); - clear_has_count(); -} -::google::protobuf::uint64 MessageAccessInfo::count() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.count) - return count_; -} -void MessageAccessInfo::set_count(::google::protobuf::uint64 value) { - set_has_count(); - count_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.count) -} - -// repeated .google.protobuf.compiler.FieldAccessInfo field = 3; -int MessageAccessInfo::field_size() const { - return field_.size(); -} -void MessageAccessInfo::clear_field() { - field_.Clear(); -} -const ::google::protobuf::compiler::FieldAccessInfo& MessageAccessInfo::field(int index) const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.field) - return field_.Get(index); -} -::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::mutable_field(int index) { - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.field) - return field_.Mutable(index); -} -::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::add_field() { - // @@protoc_insertion_point(field_add:google.protobuf.compiler.MessageAccessInfo.field) - return field_.Add(); -} -::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >* -MessageAccessInfo::mutable_field() { - // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.MessageAccessInfo.field) - return &field_; -} -const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >& -MessageAccessInfo::field() const { - // @@protoc_insertion_point(field_list:google.protobuf.compiler.MessageAccessInfo.field) - return field_; -} - -#endif // PROTOBUF_INLINE_NOT_IN_HEADERS - -// =================================================================== - -#if !defined(_MSC_VER) || _MSC_VER >= 1900 -const int AccessInfo::kMessageFieldNumber; -#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 - -AccessInfo::AccessInfo() - : ::google::protobuf::Message(), _internal_metadata_(NULL) { - if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); - } - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.compiler.AccessInfo) -} -AccessInfo::AccessInfo(const AccessInfo& from) - : ::google::protobuf::Message(), - _internal_metadata_(NULL), - _has_bits_(from._has_bits_), - _cached_size_(0), - message_(from.message_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); - // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.AccessInfo) -} - -void AccessInfo::SharedCtor() { - _cached_size_ = 0; -} - -AccessInfo::~AccessInfo() { - // @@protoc_insertion_point(destructor:google.protobuf.compiler.AccessInfo) - SharedDtor(); -} - -void AccessInfo::SharedDtor() { -} - -void AccessInfo::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* AccessInfo::descriptor() { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; -} - -const AccessInfo& AccessInfo::default_instance() { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); - return *internal_default_instance(); -} - -AccessInfo* AccessInfo::New(::google::protobuf::Arena* arena) const { - AccessInfo* n = new AccessInfo; - if (arena != NULL) { - arena->Own(n); - } - return n; -} - -void AccessInfo::Clear() { -// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.AccessInfo) - message_.Clear(); - _has_bits_.Clear(); - _internal_metadata_.Clear(); -} - -bool AccessInfo::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure - ::google::protobuf::uint32 tag; - // @@protoc_insertion_point(parse_start:google.protobuf.compiler.AccessInfo) - for (;;) { - ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); - tag = p.first; - if (!p.second) goto handle_unusual; - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .google.protobuf.compiler.MessageAccessInfo message = 1; - case 1: { - if (static_cast< ::google::protobuf::uint8>(tag) == - static_cast< ::google::protobuf::uint8>(10u)) { - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, add_message())); - } else { - goto handle_unusual; - } - break; - } - - default: { - handle_unusual: - if (tag == 0 || - ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - goto success; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } -success: - // @@protoc_insertion_point(parse_success:google.protobuf.compiler.AccessInfo) - return true; -failure: - // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.AccessInfo) - return false; -#undef DO_ -} - -void AccessInfo::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.AccessInfo) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // repeated .google.protobuf.compiler.MessageAccessInfo message = 1; - for (unsigned int i = 0, n = this->message_size(); i < n; i++) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 1, this->message(i), output); - } - - if (_internal_metadata_.have_unknown_fields()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } - // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.AccessInfo) -} - -::google::protobuf::uint8* AccessInfo::InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const { - // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.AccessInfo) - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - // repeated .google.protobuf.compiler.MessageAccessInfo message = 1; - for (unsigned int i = 0, n = this->message_size(); i < n; i++) { - target = ::google::protobuf::internal::WireFormatLite:: - InternalWriteMessageNoVirtualToArray( - 1, this->message(i), deterministic, target); - } - - if (_internal_metadata_.have_unknown_fields()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.AccessInfo) - return target; -} - -size_t AccessInfo::ByteSizeLong() const { -// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.AccessInfo) - size_t total_size = 0; - - if (_internal_metadata_.have_unknown_fields()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - // repeated .google.protobuf.compiler.MessageAccessInfo message = 1; - { - unsigned int count = this->message_size(); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->message(i)); - } - } - - int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = cached_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void AccessInfo::MergeFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.AccessInfo) - GOOGLE_DCHECK_NE(&from, this); - const AccessInfo* source = - ::google::protobuf::internal::DynamicCastToGenerated<const AccessInfo>( - &from); - if (source == NULL) { - // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.AccessInfo) - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.AccessInfo) - MergeFrom(*source); - } -} - -void AccessInfo::MergeFrom(const AccessInfo& from) { -// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.AccessInfo) - GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); - ::google::protobuf::uint32 cached_has_bits = 0; - (void) cached_has_bits; - - message_.MergeFrom(from.message_); -} - -void AccessInfo::CopyFrom(const ::google::protobuf::Message& from) { -// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.AccessInfo) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void AccessInfo::CopyFrom(const AccessInfo& from) { -// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.AccessInfo) - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool AccessInfo::IsInitialized() const { - return true; -} - -void AccessInfo::Swap(AccessInfo* other) { - if (other == this) return; - InternalSwap(other); -} -void AccessInfo::InternalSwap(AccessInfo* other) { - message_.InternalSwap(&other->message_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _internal_metadata_.Swap(&other->_internal_metadata_); - std::swap(_cached_size_, other->_cached_size_); -} - -::google::protobuf::Metadata AccessInfo::GetMetadata() const { - protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages]; -} - -#if PROTOBUF_INLINE_NOT_IN_HEADERS -// AccessInfo - -// repeated .google.protobuf.compiler.MessageAccessInfo message = 1; -int AccessInfo::message_size() const { - return message_.size(); -} -void AccessInfo::clear_message() { - message_.Clear(); -} -const ::google::protobuf::compiler::MessageAccessInfo& AccessInfo::message(int index) const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.AccessInfo.message) - return message_.Get(index); -} -::google::protobuf::compiler::MessageAccessInfo* AccessInfo::mutable_message(int index) { - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.AccessInfo.message) - return message_.Mutable(index); -} -::google::protobuf::compiler::MessageAccessInfo* AccessInfo::add_message() { - // @@protoc_insertion_point(field_add:google.protobuf.compiler.AccessInfo.message) - return message_.Add(); -} -::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >* -AccessInfo::mutable_message() { - // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.AccessInfo.message) - return &message_; -} -const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >& -AccessInfo::message() const { - // @@protoc_insertion_point(field_list:google.protobuf.compiler.AccessInfo.message) - return message_; -} - -#endif // PROTOBUF_INLINE_NOT_IN_HEADERS - -// @@protoc_insertion_point(namespace_scope) - -} // namespace compiler -} // namespace protobuf -} // namespace google - -// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/compiler/profile.pb.h b/src/google/protobuf/compiler/profile.pb.h deleted file mode 100644 index d20b87ed..00000000 --- a/src/google/protobuf/compiler/profile.pb.h +++ /dev/null @@ -1,728 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/compiler/profile.proto - -#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED -#define PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED - -#include <string> - -#include <google/protobuf/stubs/common.h> - -#if GOOGLE_PROTOBUF_VERSION < 3003000 -#error This file was generated by a newer version of protoc which is -#error incompatible with your Protocol Buffer headers. Please update -#error your headers. -#endif -#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION -#error This file was generated by an older version of protoc which is -#error incompatible with your Protocol Buffer headers. Please -#error regenerate this file with a newer version of protoc. -#endif - -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/arena.h> -#include <google/protobuf/arenastring.h> -#include <google/protobuf/generated_message_table_driven.h> -#include <google/protobuf/generated_message_util.h> -#include <google/protobuf/metadata.h> -#include <google/protobuf/message.h> -#include <google/protobuf/repeated_field.h> // IWYU pragma: export -#include <google/protobuf/extension_set.h> // IWYU pragma: export -#include <google/protobuf/unknown_field_set.h> -// @@protoc_insertion_point(includes) -namespace google { -namespace protobuf { -namespace compiler { -class AccessInfo; -class AccessInfoDefaultTypeInternal; -LIBPROTOC_EXPORT extern AccessInfoDefaultTypeInternal _AccessInfo_default_instance_; -class FieldAccessInfo; -class FieldAccessInfoDefaultTypeInternal; -LIBPROTOC_EXPORT extern FieldAccessInfoDefaultTypeInternal _FieldAccessInfo_default_instance_; -class MessageAccessInfo; -class MessageAccessInfoDefaultTypeInternal; -LIBPROTOC_EXPORT extern MessageAccessInfoDefaultTypeInternal _MessageAccessInfo_default_instance_; -} // namespace compiler -} // namespace protobuf -} // namespace google - -namespace google { -namespace protobuf { -namespace compiler { - -namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto { -// Internal implementation detail -- do not call these. -struct LIBPROTOC_EXPORT TableStruct { - static const ::google::protobuf::internal::ParseTableField entries[]; - static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; - static const ::google::protobuf::internal::ParseTable schema[]; - static const ::google::protobuf::uint32 offsets[]; - static void InitDefaultsImpl(); - static void Shutdown(); -}; -void LIBPROTOC_EXPORT AddDescriptors(); -void LIBPROTOC_EXPORT InitDefaults(); -} // namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto - -// =================================================================== - -class LIBPROTOC_EXPORT FieldAccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.FieldAccessInfo) */ { - public: - FieldAccessInfo(); - virtual ~FieldAccessInfo(); - - FieldAccessInfo(const FieldAccessInfo& from); - - inline FieldAccessInfo& operator=(const FieldAccessInfo& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const FieldAccessInfo& default_instance(); - - static inline const FieldAccessInfo* internal_default_instance() { - return reinterpret_cast<const FieldAccessInfo*>( - &_FieldAccessInfo_default_instance_); - } - static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 0; - - void Swap(FieldAccessInfo* other); - - // implements Message ---------------------------------------------- - - inline FieldAccessInfo* New() const PROTOBUF_FINAL { return New(NULL); } - - FieldAccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; - void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; - void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; - void CopyFrom(const FieldAccessInfo& from); - void MergeFrom(const FieldAccessInfo& from); - void Clear() PROTOBUF_FINAL; - bool IsInitialized() const PROTOBUF_FINAL; - - size_t ByteSizeLong() const PROTOBUF_FINAL; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const PROTOBUF_FINAL; - void InternalSwap(FieldAccessInfo* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return NULL; - } - inline void* MaybeArenaPtr() const { - return NULL; - } - public: - - ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // optional string name = 1; - bool has_name() const; - void clear_name(); - static const int kNameFieldNumber = 1; - const ::std::string& name() const; - void set_name(const ::std::string& value); - #if LANG_CXX11 - void set_name(::std::string&& value); - #endif - 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 uint64 getters_count = 2; - bool has_getters_count() const; - void clear_getters_count(); - static const int kGettersCountFieldNumber = 2; - ::google::protobuf::uint64 getters_count() const; - void set_getters_count(::google::protobuf::uint64 value); - - // optional uint64 setters_count = 3; - bool has_setters_count() const; - void clear_setters_count(); - static const int kSettersCountFieldNumber = 3; - ::google::protobuf::uint64 setters_count() const; - void set_setters_count(::google::protobuf::uint64 value); - - // optional uint64 configs_count = 4; - bool has_configs_count() const; - void clear_configs_count(); - static const int kConfigsCountFieldNumber = 4; - ::google::protobuf::uint64 configs_count() const; - void set_configs_count(::google::protobuf::uint64 value); - - // @@protoc_insertion_point(class_scope:google.protobuf.compiler.FieldAccessInfo) - private: - void set_has_name(); - void clear_has_name(); - void set_has_getters_count(); - void clear_has_getters_count(); - void set_has_setters_count(); - void clear_has_setters_count(); - void set_has_configs_count(); - void clear_has_configs_count(); - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::internal::HasBits<1> _has_bits_; - mutable int _cached_size_; - ::google::protobuf::internal::ArenaStringPtr name_; - ::google::protobuf::uint64 getters_count_; - ::google::protobuf::uint64 setters_count_; - ::google::protobuf::uint64 configs_count_; - friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct; -}; -// ------------------------------------------------------------------- - -class LIBPROTOC_EXPORT MessageAccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.MessageAccessInfo) */ { - public: - MessageAccessInfo(); - virtual ~MessageAccessInfo(); - - MessageAccessInfo(const MessageAccessInfo& from); - - inline MessageAccessInfo& operator=(const MessageAccessInfo& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const MessageAccessInfo& default_instance(); - - static inline const MessageAccessInfo* internal_default_instance() { - return reinterpret_cast<const MessageAccessInfo*>( - &_MessageAccessInfo_default_instance_); - } - static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 1; - - void Swap(MessageAccessInfo* other); - - // implements Message ---------------------------------------------- - - inline MessageAccessInfo* New() const PROTOBUF_FINAL { return New(NULL); } - - MessageAccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; - void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; - void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; - void CopyFrom(const MessageAccessInfo& from); - void MergeFrom(const MessageAccessInfo& from); - void Clear() PROTOBUF_FINAL; - bool IsInitialized() const PROTOBUF_FINAL; - - size_t ByteSizeLong() const PROTOBUF_FINAL; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const PROTOBUF_FINAL; - void InternalSwap(MessageAccessInfo* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return NULL; - } - inline void* MaybeArenaPtr() const { - return NULL; - } - public: - - ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // repeated .google.protobuf.compiler.FieldAccessInfo field = 3; - int field_size() const; - void clear_field(); - static const int kFieldFieldNumber = 3; - const ::google::protobuf::compiler::FieldAccessInfo& field(int index) const; - ::google::protobuf::compiler::FieldAccessInfo* mutable_field(int index); - ::google::protobuf::compiler::FieldAccessInfo* add_field(); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >* - mutable_field(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >& - field() const; - - // optional string name = 1; - bool has_name() const; - void clear_name(); - static const int kNameFieldNumber = 1; - const ::std::string& name() const; - void set_name(const ::std::string& value); - #if LANG_CXX11 - void set_name(::std::string&& value); - #endif - 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 uint64 count = 2; - bool has_count() const; - void clear_count(); - static const int kCountFieldNumber = 2; - ::google::protobuf::uint64 count() const; - void set_count(::google::protobuf::uint64 value); - - // @@protoc_insertion_point(class_scope:google.protobuf.compiler.MessageAccessInfo) - private: - void set_has_name(); - void clear_has_name(); - void set_has_count(); - void clear_has_count(); - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::internal::HasBits<1> _has_bits_; - mutable int _cached_size_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo > field_; - ::google::protobuf::internal::ArenaStringPtr name_; - ::google::protobuf::uint64 count_; - friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct; -}; -// ------------------------------------------------------------------- - -class LIBPROTOC_EXPORT AccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.AccessInfo) */ { - public: - AccessInfo(); - virtual ~AccessInfo(); - - AccessInfo(const AccessInfo& from); - - inline AccessInfo& operator=(const AccessInfo& from) { - CopyFrom(from); - return *this; - } - - inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); - } - - inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); - } - - static const ::google::protobuf::Descriptor* descriptor(); - static const AccessInfo& default_instance(); - - static inline const AccessInfo* internal_default_instance() { - return reinterpret_cast<const AccessInfo*>( - &_AccessInfo_default_instance_); - } - static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = - 2; - - void Swap(AccessInfo* other); - - // implements Message ---------------------------------------------- - - inline AccessInfo* New() const PROTOBUF_FINAL { return New(NULL); } - - AccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; - void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; - void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; - void CopyFrom(const AccessInfo& from); - void MergeFrom(const AccessInfo& from); - void Clear() PROTOBUF_FINAL; - bool IsInitialized() const PROTOBUF_FINAL; - - size_t ByteSizeLong() const PROTOBUF_FINAL; - bool MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; - void SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( - bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } - private: - void SharedCtor(); - void SharedDtor(); - void SetCachedSize(int size) const PROTOBUF_FINAL; - void InternalSwap(AccessInfo* other); - private: - inline ::google::protobuf::Arena* GetArenaNoVirtual() const { - return NULL; - } - inline void* MaybeArenaPtr() const { - return NULL; - } - public: - - ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL; - - // nested types ---------------------------------------------------- - - // accessors ------------------------------------------------------- - - // repeated .google.protobuf.compiler.MessageAccessInfo message = 1; - int message_size() const; - void clear_message(); - static const int kMessageFieldNumber = 1; - const ::google::protobuf::compiler::MessageAccessInfo& message(int index) const; - ::google::protobuf::compiler::MessageAccessInfo* mutable_message(int index); - ::google::protobuf::compiler::MessageAccessInfo* add_message(); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >* - mutable_message(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >& - message() const; - - // @@protoc_insertion_point(class_scope:google.protobuf.compiler.AccessInfo) - private: - - ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; - ::google::protobuf::internal::HasBits<1> _has_bits_; - mutable int _cached_size_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo > message_; - friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct; -}; -// =================================================================== - - -// =================================================================== - -#if !PROTOBUF_INLINE_NOT_IN_HEADERS -// FieldAccessInfo - -// optional string name = 1; -inline bool FieldAccessInfo::has_name() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void FieldAccessInfo::set_has_name() { - _has_bits_[0] |= 0x00000001u; -} -inline void FieldAccessInfo::clear_has_name() { - _has_bits_[0] &= ~0x00000001u; -} -inline void FieldAccessInfo::clear_name() { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - clear_has_name(); -} -inline const ::std::string& FieldAccessInfo::name() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.name) - return name_.GetNoArena(); -} -inline void FieldAccessInfo::set_name(const ::std::string& value) { - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.name) -} -#if LANG_CXX11 -inline void FieldAccessInfo::set_name(::std::string&& value) { - set_has_name(); - name_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.FieldAccessInfo.name) -} -#endif -inline void FieldAccessInfo::set_name(const char* value) { - GOOGLE_DCHECK(value != NULL); - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.FieldAccessInfo.name) -} -inline void FieldAccessInfo::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.FieldAccessInfo.name) -} -inline ::std::string* FieldAccessInfo::mutable_name() { - set_has_name(); - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.FieldAccessInfo.name) - return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline ::std::string* FieldAccessInfo::release_name() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.FieldAccessInfo.name) - clear_has_name(); - return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void FieldAccessInfo::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.FieldAccessInfo.name) -} - -// optional uint64 getters_count = 2; -inline bool FieldAccessInfo::has_getters_count() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void FieldAccessInfo::set_has_getters_count() { - _has_bits_[0] |= 0x00000002u; -} -inline void FieldAccessInfo::clear_has_getters_count() { - _has_bits_[0] &= ~0x00000002u; -} -inline void FieldAccessInfo::clear_getters_count() { - getters_count_ = GOOGLE_ULONGLONG(0); - clear_has_getters_count(); -} -inline ::google::protobuf::uint64 FieldAccessInfo::getters_count() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.getters_count) - return getters_count_; -} -inline void FieldAccessInfo::set_getters_count(::google::protobuf::uint64 value) { - set_has_getters_count(); - getters_count_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.getters_count) -} - -// optional uint64 setters_count = 3; -inline bool FieldAccessInfo::has_setters_count() const { - return (_has_bits_[0] & 0x00000004u) != 0; -} -inline void FieldAccessInfo::set_has_setters_count() { - _has_bits_[0] |= 0x00000004u; -} -inline void FieldAccessInfo::clear_has_setters_count() { - _has_bits_[0] &= ~0x00000004u; -} -inline void FieldAccessInfo::clear_setters_count() { - setters_count_ = GOOGLE_ULONGLONG(0); - clear_has_setters_count(); -} -inline ::google::protobuf::uint64 FieldAccessInfo::setters_count() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.setters_count) - return setters_count_; -} -inline void FieldAccessInfo::set_setters_count(::google::protobuf::uint64 value) { - set_has_setters_count(); - setters_count_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.setters_count) -} - -// optional uint64 configs_count = 4; -inline bool FieldAccessInfo::has_configs_count() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void FieldAccessInfo::set_has_configs_count() { - _has_bits_[0] |= 0x00000008u; -} -inline void FieldAccessInfo::clear_has_configs_count() { - _has_bits_[0] &= ~0x00000008u; -} -inline void FieldAccessInfo::clear_configs_count() { - configs_count_ = GOOGLE_ULONGLONG(0); - clear_has_configs_count(); -} -inline ::google::protobuf::uint64 FieldAccessInfo::configs_count() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.configs_count) - return configs_count_; -} -inline void FieldAccessInfo::set_configs_count(::google::protobuf::uint64 value) { - set_has_configs_count(); - configs_count_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.configs_count) -} - -// ------------------------------------------------------------------- - -// MessageAccessInfo - -// optional string name = 1; -inline bool MessageAccessInfo::has_name() const { - return (_has_bits_[0] & 0x00000001u) != 0; -} -inline void MessageAccessInfo::set_has_name() { - _has_bits_[0] |= 0x00000001u; -} -inline void MessageAccessInfo::clear_has_name() { - _has_bits_[0] &= ~0x00000001u; -} -inline void MessageAccessInfo::clear_name() { - name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - clear_has_name(); -} -inline const ::std::string& MessageAccessInfo::name() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.name) - return name_.GetNoArena(); -} -inline void MessageAccessInfo::set_name(const ::std::string& value) { - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); - // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.name) -} -#if LANG_CXX11 -inline void MessageAccessInfo::set_name(::std::string&& value) { - set_has_name(); - name_.SetNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); - // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.MessageAccessInfo.name) -} -#endif -inline void MessageAccessInfo::set_name(const char* value) { - GOOGLE_DCHECK(value != NULL); - set_has_name(); - name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); - // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.MessageAccessInfo.name) -} -inline void MessageAccessInfo::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.MessageAccessInfo.name) -} -inline ::std::string* MessageAccessInfo::mutable_name() { - set_has_name(); - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.name) - return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline ::std::string* MessageAccessInfo::release_name() { - // @@protoc_insertion_point(field_release:google.protobuf.compiler.MessageAccessInfo.name) - clear_has_name(); - return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); -} -inline void MessageAccessInfo::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.MessageAccessInfo.name) -} - -// optional uint64 count = 2; -inline bool MessageAccessInfo::has_count() const { - return (_has_bits_[0] & 0x00000002u) != 0; -} -inline void MessageAccessInfo::set_has_count() { - _has_bits_[0] |= 0x00000002u; -} -inline void MessageAccessInfo::clear_has_count() { - _has_bits_[0] &= ~0x00000002u; -} -inline void MessageAccessInfo::clear_count() { - count_ = GOOGLE_ULONGLONG(0); - clear_has_count(); -} -inline ::google::protobuf::uint64 MessageAccessInfo::count() const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.count) - return count_; -} -inline void MessageAccessInfo::set_count(::google::protobuf::uint64 value) { - set_has_count(); - count_ = value; - // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.count) -} - -// repeated .google.protobuf.compiler.FieldAccessInfo field = 3; -inline int MessageAccessInfo::field_size() const { - return field_.size(); -} -inline void MessageAccessInfo::clear_field() { - field_.Clear(); -} -inline const ::google::protobuf::compiler::FieldAccessInfo& MessageAccessInfo::field(int index) const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.field) - return field_.Get(index); -} -inline ::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::mutable_field(int index) { - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.field) - return field_.Mutable(index); -} -inline ::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::add_field() { - // @@protoc_insertion_point(field_add:google.protobuf.compiler.MessageAccessInfo.field) - return field_.Add(); -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >* -MessageAccessInfo::mutable_field() { - // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.MessageAccessInfo.field) - return &field_; -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >& -MessageAccessInfo::field() const { - // @@protoc_insertion_point(field_list:google.protobuf.compiler.MessageAccessInfo.field) - return field_; -} - -// ------------------------------------------------------------------- - -// AccessInfo - -// repeated .google.protobuf.compiler.MessageAccessInfo message = 1; -inline int AccessInfo::message_size() const { - return message_.size(); -} -inline void AccessInfo::clear_message() { - message_.Clear(); -} -inline const ::google::protobuf::compiler::MessageAccessInfo& AccessInfo::message(int index) const { - // @@protoc_insertion_point(field_get:google.protobuf.compiler.AccessInfo.message) - return message_.Get(index); -} -inline ::google::protobuf::compiler::MessageAccessInfo* AccessInfo::mutable_message(int index) { - // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.AccessInfo.message) - return message_.Mutable(index); -} -inline ::google::protobuf::compiler::MessageAccessInfo* AccessInfo::add_message() { - // @@protoc_insertion_point(field_add:google.protobuf.compiler.AccessInfo.message) - return message_.Add(); -} -inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >* -AccessInfo::mutable_message() { - // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.AccessInfo.message) - return &message_; -} -inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >& -AccessInfo::message() const { - // @@protoc_insertion_point(field_list:google.protobuf.compiler.AccessInfo.message) - return message_; -} - -#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS -// ------------------------------------------------------------------- - -// ------------------------------------------------------------------- - - -// @@protoc_insertion_point(namespace_scope) - - -} // namespace compiler -} // namespace protobuf -} // namespace google - -// @@protoc_insertion_point(global_scope) - -#endif // PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc index 21a7e158..5ca6b4ee 100644 --- a/src/google/protobuf/compiler/python/python_generator.cc +++ b/src/google/protobuf/compiler/python/python_generator.cc @@ -63,11 +63,12 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/stringprintf.h> #include <google/protobuf/io/printer.h> -#include <google/protobuf/descriptor.h> #include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/descriptor.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> + namespace google { namespace protobuf { namespace compiler { @@ -75,12 +76,21 @@ namespace python { namespace { +// Reimplemented here because we can't bring in +// absl/strings/string_view_utils.h because it needs C++11. +bool StrStartsWith(StringPiece sp, StringPiece x) { + return sp.size() >= x.size() && sp.substr(0, x.size()) == x; +} +bool StrEndsWith(StringPiece sp, StringPiece x) { + return sp.size() >= x.size() && sp.substr(sp.size() - x.size()) == x; +} + // Returns a copy of |filename| with any trailing ".protodevel" or ".proto // suffix stripped. // TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc. string StripProto(const string& filename) { - const char* suffix = HasSuffixString(filename, ".protodevel") - ? ".protodevel" : ".proto"; + const char* suffix = + StrEndsWith(filename, ".protodevel") ? ".protodevel" : ".proto"; return StripSuffixString(filename, suffix); } @@ -350,7 +360,9 @@ bool Generator::Generate(const FileDescriptor* file, // can only be successfully parsed after we register corresponding // extensions. Therefore we parse all options again here to recognize // custom options that may be unknown when we define the descriptors. + // This does not apply to services because they are not used by extensions. FixAllDescriptorOptions(); + PrintServiceDescriptors(); if (HasGenericServices(file)) { PrintServices(); } @@ -562,9 +574,16 @@ void Generator::PrintMessageDescriptors() const { } } -void Generator::PrintServices() const { +void Generator::PrintServiceDescriptors() const { for (int i = 0; i < file_->service_count(); ++i) { PrintServiceDescriptor(*file_->service(i)); + AddServiceToFileDescriptor(*file_->service(i)); + printer_->Print("\n"); + } +} + +void Generator::PrintServices() const { + for (int i = 0; i < file_->service_count(); ++i) { PrintServiceClass(*file_->service(i)); PrintServiceStub(*file_->service(i)); printer_->Print("\n"); @@ -628,7 +647,10 @@ void Generator::PrintServiceDescriptor( } printer_->Outdent(); - printer_->Print("])\n\n"); + printer_->Print("])\n"); + printer_->Print("_sym_db.RegisterServiceDescriptor($name$)\n", "name", + service_name); + printer_->Print("\n"); } @@ -887,6 +909,18 @@ void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const { printer_->Print(m, file_descriptor_template); } +void Generator::AddServiceToFileDescriptor( + const ServiceDescriptor& descriptor) const { + std::map<string, string> m; + m["descriptor_name"] = kDescriptorKey; + m["service_name"] = descriptor.name(); + m["service_descriptor_name"] = ModuleLevelServiceDescriptorName(descriptor); + const char file_descriptor_template[] = + "$descriptor_name$.services_by_name['$service_name$'] = " + "$service_descriptor_name$\n"; + printer_->Print(m, file_descriptor_template); +} + void Generator::AddEnumToFileDescriptor( const EnumDescriptor& descriptor) const { std::map<string, string> m; @@ -1117,7 +1151,7 @@ void Generator::PrintFieldDescriptor( " has_default_value=$has_default_value$, default_value=$default_value$,\n" " message_type=None, enum_type=None, containing_type=None,\n" " is_extension=$is_extension$, extension_scope=None,\n" - " options=$options$$json_name$)"; + " options=$options$$json_name$, file=DESCRIPTOR)"; printer_->Print(m, field_descriptor_decl); } diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h index 594260af..2b5a028b 100644 --- a/src/google/protobuf/compiler/python/python_generator.h +++ b/src/google/protobuf/compiler/python/python_generator.h @@ -112,6 +112,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { void AddMessageToFileDescriptor(const Descriptor& descriptor) const; void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const; void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const; + void AddServiceToFileDescriptor(const ServiceDescriptor& descriptor) const; string FieldReferencingExpression(const Descriptor* containing_type, const FieldDescriptor& field, const string& python_dict_name) const; @@ -126,11 +127,12 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const; void PrintServices() const; + void PrintServiceDescriptors() const; void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const; void PrintServiceClass(const ServiceDescriptor& descriptor) const; void PrintServiceStub(const ServiceDescriptor& descriptor) const; void PrintDescriptorKeyAndModuleName( - const ServiceDescriptor& descriptor) const ; + const ServiceDescriptor& descriptor) const; void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const; string OptionsValue(const string& class_name, diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc index 933450fa..2e5a89ac 100644 --- a/src/google/protobuf/compiler/subprocess.cc +++ b/src/google/protobuf/compiler/subprocess.cc @@ -33,6 +33,7 @@ #include <google/protobuf/compiler/subprocess.h> #include <algorithm> +#include <cstring> #include <iostream> #ifndef _WIN32 @@ -47,11 +48,20 @@ #include <google/protobuf/message.h> #include <google/protobuf/stubs/substitute.h> - namespace google { namespace protobuf { namespace compiler { +namespace { +char* portable_strdup(const char* s) { + char* ns = (char*) malloc(strlen(s) + 1); + if (ns != NULL) { + strcpy(ns, s); + } + return ns; +} +} // namespace + #ifdef _WIN32 static void CloseHandleOrDie(HANDLE handle) { @@ -115,7 +125,7 @@ void Subprocess::Start(const string& program, SearchMode search_mode) { } // CreateProcess() mutates its second parameter. WTF? - char* name_copy = strdup(program.c_str()); + char* name_copy = portable_strdup(program.c_str()); // Create the process. PROCESS_INFORMATION process_info; @@ -299,7 +309,7 @@ void Subprocess::Start(const string& program, SearchMode search_mode) { GOOGLE_CHECK(pipe(stdin_pipe) != -1); GOOGLE_CHECK(pipe(stdout_pipe) != -1); - char* argv[2] = { strdup(program.c_str()), NULL }; + char* argv[2] = { portable_strdup(program.c_str()), NULL }; child_pid_ = fork(); if (child_pid_ == -1) { @@ -347,7 +357,6 @@ void Subprocess::Start(const string& program, SearchMode search_mode) { bool Subprocess::Communicate(const Message& input, Message* output, string* error) { - GOOGLE_CHECK_NE(child_stdin_, -1) << "Must call Start() first."; // The "sighandler_t" typedef is GNU-specific, so define our own. diff --git a/src/google/protobuf/compiler/subprocess.h b/src/google/protobuf/compiler/subprocess.h index 25138631..9d980b06 100644 --- a/src/google/protobuf/compiler/subprocess.h +++ b/src/google/protobuf/compiler/subprocess.h @@ -44,7 +44,6 @@ #include <string> - namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/zip_output_unittest.sh b/src/google/protobuf/compiler/zip_output_unittest.sh index 6fc7136d..f8597912 100755 --- a/src/google/protobuf/compiler/zip_output_unittest.sh +++ b/src/google/protobuf/compiler/zip_output_unittest.sh @@ -41,6 +41,8 @@ fail() { TEST_TMPDIR=. PROTOC=./protoc +JAR=jar +UNZIP=unzip echo ' syntax = "proto2"; @@ -57,8 +59,9 @@ $PROTOC \ || fail 'protoc failed.' echo "Testing output to zip..." -if unzip -h > /dev/null; then - unzip -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list || fail 'unzip failed.' +if $UNZIP -h > /dev/null; then + $UNZIP -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list \ + || fail 'unzip failed.' grep 'testing: testzip\.pb\.cc *OK$' $TEST_TMPDIR/testzip.list > /dev/null \ || fail 'testzip.pb.cc not found in output zip.' @@ -73,8 +76,14 @@ else fi echo "Testing output to jar..." -if jar c $TEST_TMPDIR/testzip.proto > /dev/null; then - jar tf $TEST_TMPDIR/testzip.jar > $TEST_TMPDIR/testzip.list || fail 'jar failed.' +if $JAR c $TEST_TMPDIR/testzip.proto > /dev/null; then + $JAR tf $TEST_TMPDIR/testzip.jar > $TEST_TMPDIR/testzip.list \ + || fail 'jar failed.' + + # Check that -interface.jar timestamps are normalized: + if [[ "$(TZ=UTC $JAR tvf $TEST_TMPDIR/testzip.jar)" != *'Tue Jan 01 00:00:00 UTC 1980'* ]]; then + fail 'Zip did not contain normalized timestamps' + fi grep '^test/jar/Foo\.java$' $TEST_TMPDIR/testzip.list > /dev/null \ || fail 'Foo.java not found in output jar.' diff --git a/src/google/protobuf/compiler/zip_writer.cc b/src/google/protobuf/compiler/zip_writer.cc index 458cced2..1799af6a 100644 --- a/src/google/protobuf/compiler/zip_writer.cc +++ b/src/google/protobuf/compiler/zip_writer.cc @@ -70,6 +70,10 @@ namespace google { namespace protobuf { namespace compiler { +// January 1, 1980 as a DOS date. +// see https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx +static const uint16 kDosEpoch = 1 << 5 | 1; + static const uint32 kCRC32Table[256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, @@ -154,7 +158,7 @@ bool ZipWriter::Write(const string& filename, const string& contents) { WriteShort(&output, 0); // flags WriteShort(&output, 0); // compression method: stored WriteShort(&output, 0); // last modified time - WriteShort(&output, 0); // last modified date + WriteShort(&output, kDosEpoch); // last modified date output.WriteLittleEndian32(info.crc32); // crc-32 output.WriteLittleEndian32(info.size); // compressed size output.WriteLittleEndian32(info.size); // uncompressed size @@ -185,7 +189,7 @@ bool ZipWriter::WriteDirectory() { WriteShort(&output, 0); // flags WriteShort(&output, 0); // compression method: stored WriteShort(&output, 0); // last modified time - WriteShort(&output, 0); // last modified date + WriteShort(&output, kDosEpoch); // last modified date output.WriteLittleEndian32(crc32); // crc-32 output.WriteLittleEndian32(size); // compressed size output.WriteLittleEndian32(size); // uncompressed size |