aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google
diff options
context:
space:
mode:
authorGravatar liujisi@google.com <liujisi@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2010-11-02 13:14:58 +0000
committerGravatar liujisi@google.com <liujisi@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2010-11-02 13:14:58 +0000
commit33165fe0d5c265c92f2a67fc2b437b567c24e294 (patch)
tree52def0850ddd2e976da238d1a437fbda79c96e44 /src/google
parent80aa23df6c63750e8cdfdcf3996fbc37d63cac61 (diff)
Submit recent changes from internal branch. See CHANGES.txt for more details.
Diffstat (limited to 'src/google')
-rw-r--r--src/google/protobuf/compiler/code_generator.cc11
-rw-r--r--src/google/protobuf/compiler/code_generator.h24
-rw-r--r--src/google/protobuf/compiler/command_line_interface.cc82
-rw-r--r--src/google/protobuf/compiler/command_line_interface.h8
-rw-r--r--src/google/protobuf/compiler/command_line_interface_unittest.cc65
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc32
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.cc2
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_generator.cc6
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_generator.h2
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc265
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.cc11
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc22
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_primitive_field.cc4
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc58
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto4
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc46
-rw-r--r--src/google/protobuf/compiler/java/java_enum.cc20
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.cc294
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.h24
-rw-r--r--src/google/protobuf/compiler/java/java_extension.cc175
-rw-r--r--src/google/protobuf/compiler/java/java_extension.h2
-rw-r--r--src/google/protobuf/compiler/java/java_field.cc45
-rw-r--r--src/google/protobuf/compiler/java/java_field.h12
-rw-r--r--src/google/protobuf/compiler/java/java_file.cc60
-rw-r--r--src/google/protobuf/compiler/java/java_file.h6
-rw-r--r--src/google/protobuf/compiler/java/java_generator.cc28
-rw-r--r--src/google/protobuf/compiler/java/java_generator.h2
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.cc143
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.h52
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc478
-rw-r--r--src/google/protobuf/compiler/java/java_message.h13
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.cc781
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.h38
-rw-r--r--src/google/protobuf/compiler/java/java_plugin_unittest.cc19
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.cc394
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.h24
-rw-r--r--src/google/protobuf/compiler/java/java_service.cc2
-rw-r--r--src/google/protobuf/compiler/java/java_string_field.cc605
-rw-r--r--src/google/protobuf/compiler/java/java_string_field.h120
-rw-r--r--src/google/protobuf/compiler/mock_code_generator.cc52
-rw-r--r--src/google/protobuf/compiler/mock_code_generator.h9
-rw-r--r--src/google/protobuf/compiler/parser.cc692
-rw-r--r--src/google/protobuf/compiler/parser.h168
-rw-r--r--src/google/protobuf/compiler/parser_unittest.cc866
-rw-r--r--src/google/protobuf/compiler/plugin.cc35
-rw-r--r--src/google/protobuf/compiler/plugin.h2
-rw-r--r--src/google/protobuf/compiler/plugin.pb.cc75
-rw-r--r--src/google/protobuf/compiler/plugin.pb.h267
-rw-r--r--src/google/protobuf/compiler/plugin.proto2
-rw-r--r--src/google/protobuf/compiler/python/python_generator.cc26
-rw-r--r--src/google/protobuf/compiler/python/python_generator.h3
-rw-r--r--src/google/protobuf/compiler/python/python_plugin_unittest.cc14
-rw-r--r--src/google/protobuf/compiler/subprocess.cc3
-rw-r--r--src/google/protobuf/compiler/subprocess.h3
-rwxr-xr-xsrc/google/protobuf/compiler/zip_output_unittest.sh36
-rw-r--r--src/google/protobuf/compiler/zip_writer.cc34
-rw-r--r--src/google/protobuf/compiler/zip_writer.h34
-rw-r--r--src/google/protobuf/descriptor.cc107
-rw-r--r--src/google/protobuf/descriptor.pb.cc1394
-rw-r--r--src/google/protobuf/descriptor.pb.h2010
-rw-r--r--src/google/protobuf/descriptor.proto114
-rw-r--r--src/google/protobuf/descriptor_unittest.cc102
-rw-r--r--src/google/protobuf/extension_set.cc12
-rw-r--r--src/google/protobuf/extension_set.h4
-rw-r--r--src/google/protobuf/generated_message_reflection.cc3
-rw-r--r--src/google/protobuf/generated_message_util.cc2
-rw-r--r--src/google/protobuf/generated_message_util.h9
-rw-r--r--src/google/protobuf/io/coded_stream.cc11
-rw-r--r--src/google/protobuf/io/coded_stream.h10
-rw-r--r--src/google/protobuf/io/coded_stream_unittest.cc28
-rw-r--r--src/google/protobuf/io/gzip_stream.cc41
-rw-r--r--src/google/protobuf/io/printer.cc11
-rw-r--r--src/google/protobuf/io/printer.h6
-rw-r--r--src/google/protobuf/io/tokenizer.cc7
-rw-r--r--src/google/protobuf/io/tokenizer.h10
-rw-r--r--src/google/protobuf/io/tokenizer_unittest.cc95
-rw-r--r--src/google/protobuf/io/zero_copy_stream_unittest.cc141
-rw-r--r--src/google/protobuf/message.h1
-rw-r--r--src/google/protobuf/repeated_field.cc5
-rw-r--r--src/google/protobuf/repeated_field.h73
-rw-r--r--src/google/protobuf/repeated_field_unittest.cc102
-rw-r--r--src/google/protobuf/text_format.cc114
-rw-r--r--src/google/protobuf/text_format.h47
-rw-r--r--src/google/protobuf/text_format_unittest.cc87
-rw-r--r--src/google/protobuf/unittest.proto11
-rw-r--r--src/google/protobuf/unittest_custom_options.proto91
-rw-r--r--src/google/protobuf/unittest_no_generic_services.proto4
-rw-r--r--src/google/protobuf/wire_format_lite_inl.h93
89 files changed, 8810 insertions, 2236 deletions
diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc
index 3413a36a..455c239a 100644
--- a/src/google/protobuf/compiler/code_generator.cc
+++ b/src/google/protobuf/compiler/code_generator.cc
@@ -42,14 +42,19 @@ namespace protobuf {
namespace compiler {
CodeGenerator::~CodeGenerator() {}
-OutputDirectory::~OutputDirectory() {}
+GeneratorContext::~GeneratorContext() {}
-io::ZeroCopyOutputStream* OutputDirectory::OpenForInsert(
+io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert(
const string& filename, const string& insertion_point) {
- GOOGLE_LOG(FATAL) << "This OutputDirectory does not support insertion.";
+ GOOGLE_LOG(FATAL) << "This GeneratorContext does not support insertion.";
return NULL; // make compiler happy
}
+void GeneratorContext::ListParsedFiles(
+ vector<const FileDescriptor*>* output) {
+ GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles";
+}
+
// Parses a set of comma-delimited name/value pairs.
void ParseGeneratorParameter(const string& text,
vector<pair<string, string> >* output) {
diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h
index ea094cdd..252f68d1 100644
--- a/src/google/protobuf/compiler/code_generator.h
+++ b/src/google/protobuf/compiler/code_generator.h
@@ -53,7 +53,7 @@ namespace compiler {
// Defined in this file.
class CodeGenerator;
-class OutputDirectory;
+class GeneratorContext;
// The abstract interface to a class which generates code implementing a
// particular proto file in a particular language. A number of these may
@@ -76,7 +76,7 @@ class LIBPROTOC_EXPORT CodeGenerator {
// the problem (e.g. "invalid parameter") and returns false.
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error) const = 0;
private:
@@ -85,11 +85,12 @@ class LIBPROTOC_EXPORT CodeGenerator {
// CodeGenerators generate one or more files in a given directory. This
// abstract interface represents the directory to which the CodeGenerator is
-// to write.
-class LIBPROTOC_EXPORT OutputDirectory {
+// to write and other information about the context in which the Generator
+// runs.
+class LIBPROTOC_EXPORT GeneratorContext {
public:
- inline OutputDirectory() {}
- virtual ~OutputDirectory();
+ inline GeneratorContext() {}
+ virtual ~GeneratorContext();
// Opens the given file, truncating it if it exists, and returns a
// ZeroCopyOutputStream that writes to the file. The caller takes ownership
@@ -112,10 +113,19 @@ class LIBPROTOC_EXPORT OutputDirectory {
virtual io::ZeroCopyOutputStream* OpenForInsert(
const string& filename, const string& insertion_point);
+ // Returns a vector of FileDescriptors for all the files being compiled
+ // in this run. Useful for languages, such as Go, that treat files
+ // differently when compiled as a set rather than individually.
+ virtual void ListParsedFiles(vector<const FileDescriptor*>* output);
+
private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OutputDirectory);
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext);
};
+// The type GeneratorContext was once called OutputDirectory. This typedef
+// provides backward compatibility.
+typedef GeneratorContext OutputDirectory;
+
// Several code generators treat the parameter argument as holding a
// list of options separated by commas. This helper function parses
// a set of comma-delimited name/value pairs: e.g.,
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index 02c3e0f9..9e9849cf 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -48,6 +48,9 @@
#include <iostream>
#include <ctype.h>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.pb.h>
@@ -58,12 +61,10 @@
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/stubs/common.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-inl.h>
-#include <google/protobuf/stubs/hash.h>
namespace google {
@@ -182,7 +183,7 @@ bool TryCreateParentDirectory(const string& prefix, const string& filename) {
class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
public io::ErrorCollector {
public:
- ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL)
+ ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL)
: format_(format), tree_(tree) {}
~ErrorPrinter() {}
@@ -191,8 +192,8 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
const string& message) {
// Print full path when running under MSVS
- std::string dfile;
- if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS &&
+ string dfile;
+ if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS &&
tree_ != NULL &&
tree_->VirtualFileToDiskFile(filename, &dfile)) {
cerr << dfile;
@@ -229,12 +230,12 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
// -------------------------------------------------------------------
-// An OutputDirectory implementation that buffers files in memory, then dumps
+// A GeneratorContext implementation that buffers files in memory, then dumps
// them all to disk on demand.
-class CommandLineInterface::MemoryOutputDirectory : public OutputDirectory {
+class CommandLineInterface::GeneratorContextImpl : public GeneratorContext {
public:
- MemoryOutputDirectory();
- ~MemoryOutputDirectory();
+ GeneratorContextImpl(const vector<const FileDescriptor*>& parsed_files);
+ ~GeneratorContextImpl();
// Write all files in the directory to disk at the given output location,
// which must end in a '/'.
@@ -248,10 +249,13 @@ class CommandLineInterface::MemoryOutputDirectory : public OutputDirectory {
// format, unless one has already been written.
void AddJarManifest();
- // implements OutputDirectory --------------------------------------
+ // implements GeneratorContext --------------------------------------
io::ZeroCopyOutputStream* Open(const string& filename);
io::ZeroCopyOutputStream* OpenForInsert(
const string& filename, const string& insertion_point);
+ void ListParsedFiles(vector<const FileDescriptor*>* output) {
+ *output = parsed_files_;
+ }
private:
friend class MemoryOutputStream;
@@ -259,14 +263,15 @@ class CommandLineInterface::MemoryOutputDirectory : public OutputDirectory {
// map instead of hash_map so that files are written in order (good when
// writing zips).
map<string, string*> files_;
+ const vector<const FileDescriptor*>& parsed_files_;
bool had_error_;
};
class CommandLineInterface::MemoryOutputStream
: public io::ZeroCopyOutputStream {
public:
- MemoryOutputStream(MemoryOutputDirectory* directory, const string& filename);
- MemoryOutputStream(MemoryOutputDirectory* directory, const string& filename,
+ MemoryOutputStream(GeneratorContextImpl* directory, const string& filename);
+ MemoryOutputStream(GeneratorContextImpl* directory, const string& filename,
const string& insertion_point);
virtual ~MemoryOutputStream();
@@ -277,7 +282,7 @@ class CommandLineInterface::MemoryOutputStream
private:
// Where to insert the string when it's done.
- MemoryOutputDirectory* directory_;
+ GeneratorContextImpl* directory_;
string filename_;
string insertion_point_;
@@ -290,14 +295,17 @@ class CommandLineInterface::MemoryOutputStream
// -------------------------------------------------------------------
-CommandLineInterface::MemoryOutputDirectory::MemoryOutputDirectory()
- : had_error_(false) {}
+CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl(
+ const vector<const FileDescriptor*>& parsed_files)
+ : parsed_files_(parsed_files),
+ had_error_(false) {
+}
-CommandLineInterface::MemoryOutputDirectory::~MemoryOutputDirectory() {
+CommandLineInterface::GeneratorContextImpl::~GeneratorContextImpl() {
STLDeleteValues(&files_);
}
-bool CommandLineInterface::MemoryOutputDirectory::WriteAllToDisk(
+bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk(
const string& prefix) {
if (had_error_) {
return false;
@@ -372,7 +380,7 @@ bool CommandLineInterface::MemoryOutputDirectory::WriteAllToDisk(
return true;
}
-bool CommandLineInterface::MemoryOutputDirectory::WriteAllToZip(
+bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip(
const string& filename) {
if (had_error_) {
return false;
@@ -413,7 +421,7 @@ bool CommandLineInterface::MemoryOutputDirectory::WriteAllToZip(
return true;
}
-void CommandLineInterface::MemoryOutputDirectory::AddJarManifest() {
+void CommandLineInterface::GeneratorContextImpl::AddJarManifest() {
string** map_slot = &files_["META-INF/MANIFEST.MF"];
if (*map_slot == NULL) {
*map_slot = new string(
@@ -423,13 +431,13 @@ void CommandLineInterface::MemoryOutputDirectory::AddJarManifest() {
}
}
-io::ZeroCopyOutputStream* CommandLineInterface::MemoryOutputDirectory::Open(
+io::ZeroCopyOutputStream* CommandLineInterface::GeneratorContextImpl::Open(
const string& filename) {
return new MemoryOutputStream(this, filename);
}
io::ZeroCopyOutputStream*
-CommandLineInterface::MemoryOutputDirectory::OpenForInsert(
+CommandLineInterface::GeneratorContextImpl::OpenForInsert(
const string& filename, const string& insertion_point) {
return new MemoryOutputStream(this, filename, insertion_point);
}
@@ -437,14 +445,14 @@ CommandLineInterface::MemoryOutputDirectory::OpenForInsert(
// -------------------------------------------------------------------
CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
- MemoryOutputDirectory* directory, const string& filename)
+ GeneratorContextImpl* directory, const string& filename)
: directory_(directory),
filename_(filename),
inner_(new io::StringOutputStream(&data_)) {
}
CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
- MemoryOutputDirectory* directory, const string& filename,
+ GeneratorContextImpl* directory, const string& filename,
const string& insertion_point)
: directory_(directory),
filename_(filename),
@@ -613,11 +621,11 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
}
}
- // We construct a separate OutputDirectory for each output location. Note
+ // 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 OutputDirectory (so that OpenForInsert() works).
- typedef hash_map<string, MemoryOutputDirectory*> OutputDirectoryMap;
- OutputDirectoryMap output_directories;
+ // they should share a single GeneratorContext so that OpenForInsert() works.
+ typedef hash_map<string, GeneratorContextImpl*> GeneratorContextMap;
+ GeneratorContextMap output_directories;
// Generate output.
if (mode_ == MODE_COMPILE) {
@@ -627,11 +635,11 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
!HasSuffixString(output_location, ".jar")) {
AddTrailingSlash(&output_location);
}
- MemoryOutputDirectory** map_slot = &output_directories[output_location];
+ GeneratorContextImpl** map_slot = &output_directories[output_location];
if (*map_slot == NULL) {
// First time we've seen this output location.
- *map_slot = new MemoryOutputDirectory;
+ *map_slot = new GeneratorContextImpl(parsed_files);
}
if (!GenerateOutput(parsed_files, output_directives_[i], *map_slot)) {
@@ -642,10 +650,10 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
}
// Write all output to disk.
- for (OutputDirectoryMap::iterator iter = output_directories.begin();
+ for (GeneratorContextMap::iterator iter = output_directories.begin();
iter != output_directories.end(); ++iter) {
const string& location = iter->first;
- MemoryOutputDirectory* directory = iter->second;
+ GeneratorContextImpl* directory = iter->second;
if (HasSuffixString(location, "/")) {
if (!directory->WriteAllToDisk(location)) {
STLDeleteValues(&output_directories);
@@ -1107,7 +1115,7 @@ void CommandLineInterface::PrintHelpText() {
bool CommandLineInterface::GenerateOutput(
const vector<const FileDescriptor*>& parsed_files,
const OutputDirective& output_directive,
- OutputDirectory* output_directory) {
+ GeneratorContext* generator_context) {
// Call the generator.
string error;
if (output_directive.generator == NULL) {
@@ -1122,7 +1130,7 @@ bool CommandLineInterface::GenerateOutput(
if (!GeneratePluginOutput(parsed_files, plugin_name,
output_directive.parameter,
- output_directory, &error)) {
+ generator_context, &error)) {
cerr << output_directive.name << ": " << error << endl;
return false;
}
@@ -1131,7 +1139,7 @@ bool CommandLineInterface::GenerateOutput(
for (int i = 0; i < parsed_files.size(); i++) {
if (!output_directive.generator->Generate(
parsed_files[i], output_directive.parameter,
- output_directory, &error)) {
+ generator_context, &error)) {
// Generator returned an error.
cerr << output_directive.name << ": " << parsed_files[i]->name() << ": "
<< error << endl;
@@ -1147,7 +1155,7 @@ bool CommandLineInterface::GeneratePluginOutput(
const vector<const FileDescriptor*>& parsed_files,
const string& plugin_name,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error) {
CodeGeneratorRequest request;
CodeGeneratorResponse response;
@@ -1190,14 +1198,14 @@ bool CommandLineInterface::GeneratePluginOutput(
// We reset current_output to NULL first so that the old file is closed
// before the new one is opened.
current_output.reset();
- current_output.reset(output_directory->OpenForInsert(
+ current_output.reset(generator_context->OpenForInsert(
output_file.name(), output_file.insertion_point()));
} else if (!output_file.name().empty()) {
// Starting a new file. Open it.
// We reset current_output to NULL first so that the old file is closed
// before the new one is opened.
current_output.reset();
- current_output.reset(output_directory->Open(output_file.name()));
+ current_output.reset(generator_context->Open(output_file.name()));
} else if (current_output == NULL) {
*error = strings::Substitute(
"$0: First file chunk returned by plugin did not specify a file name.",
diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h
index d25a50e6..0b507d80 100644
--- a/src/google/protobuf/compiler/command_line_interface.h
+++ b/src/google/protobuf/compiler/command_line_interface.h
@@ -56,7 +56,7 @@ template<typename T> class RepeatedPtrField; // repeated_field.h
namespace compiler {
class CodeGenerator; // code_generator.h
-class OutputDirectory; // code_generator.h
+class GeneratorContext; // code_generator.h
class DiskSourceTree; // importer.h
// This class implements the command-line interface to the protocol compiler.
@@ -174,7 +174,7 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// -----------------------------------------------------------------
class ErrorPrinter;
- class MemoryOutputDirectory;
+ class GeneratorContextImpl;
class MemoryOutputStream;
// Clear state from previous Run().
@@ -212,11 +212,11 @@ class LIBPROTOC_EXPORT CommandLineInterface {
struct OutputDirective; // see below
bool GenerateOutput(const vector<const FileDescriptor*>& parsed_files,
const OutputDirective& output_directive,
- OutputDirectory* output_directory);
+ GeneratorContext* generator_context);
bool GeneratePluginOutput(const vector<const FileDescriptor*>& parsed_files,
const string& plugin_name,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error);
// Implements --encode and --decode.
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index bdf37ad1..6634b676 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -143,6 +143,10 @@ class CommandLineInterfaceTest : public testing::Test {
const string& proto_name,
const string& message_name,
const string& output_directory);
+ void ExpectGeneratedWithMultipleInputs(const string& generator_name,
+ const string& all_proto_names,
+ const string& proto_name,
+ const string& message_name);
void ExpectGeneratedWithInsertions(const string& generator_name,
const string& parameter,
const string& insertions,
@@ -190,7 +194,7 @@ class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator {
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
called_ = true;
parameter_ = parameter;
@@ -251,7 +255,6 @@ void CommandLineInterfaceTest::Run(const string& command) {
if (!disallow_plugins_) {
cli_.AllowPlugins("prefix-");
-
const char* possible_paths[] = {
// When building with shared libraries, libtool hides the real executable
// in .libs and puts a fake wrapper in the current directory.
@@ -353,7 +356,8 @@ void CommandLineInterfaceTest::ExpectGenerated(
const string& proto_name,
const string& message_name) {
MockCodeGenerator::ExpectGenerated(
- generator_name, parameter, "", proto_name, message_name, temp_directory_);
+ generator_name, parameter, "", proto_name, message_name, proto_name,
+ temp_directory_);
}
void CommandLineInterfaceTest::ExpectGenerated(
@@ -363,10 +367,21 @@ void CommandLineInterfaceTest::ExpectGenerated(
const string& message_name,
const string& output_directory) {
MockCodeGenerator::ExpectGenerated(
- generator_name, parameter, "", proto_name, message_name,
+ generator_name, parameter, "", proto_name, message_name, proto_name,
temp_directory_ + "/" + output_directory);
}
+void CommandLineInterfaceTest::ExpectGeneratedWithMultipleInputs(
+ const string& generator_name,
+ const string& all_proto_names,
+ const string& proto_name,
+ const string& message_name) {
+ MockCodeGenerator::ExpectGenerated(
+ generator_name, "", "", proto_name, message_name,
+ all_proto_names,
+ temp_directory_);
+}
+
void CommandLineInterfaceTest::ExpectGeneratedWithInsertions(
const string& generator_name,
const string& parameter,
@@ -375,7 +390,7 @@ void CommandLineInterfaceTest::ExpectGeneratedWithInsertions(
const string& message_name) {
MockCodeGenerator::ExpectGenerated(
generator_name, parameter, insertions, proto_name, message_name,
- temp_directory_);
+ proto_name, temp_directory_);
}
void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled(
@@ -455,8 +470,44 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs) {
"--proto_path=$tmpdir foo.proto bar.proto");
ExpectNoErrors();
- ExpectGenerated("test_generator", "", "foo.proto", "Foo");
- ExpectGenerated("test_generator", "", "bar.proto", "Bar");
+ 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.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"baz.proto\";\n"
+ "message Bar {\n"
+ " optional Baz a = 1;\n"
+ "}\n");
+ CreateTempFile("baz.proto",
+ "syntax = \"proto2\";\n"
+ "message Baz {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--proto_path=$tmpdir 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, CreateDirectory) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index 30b1d2bf..bcfa5020 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -79,10 +79,10 @@ class MockErrorCollector : public MultiFileErrorCollector {
}
};
-class MockOutputDirectory : public OutputDirectory {
+class MockGeneratorContext : public GeneratorContext {
public:
- MockOutputDirectory() {}
- ~MockOutputDirectory() {
+ MockGeneratorContext() {}
+ ~MockGeneratorContext() {
STLDeleteValues(&files_);
}
@@ -102,7 +102,7 @@ class MockOutputDirectory : public OutputDirectory {
"to your CL.";
}
- // implements OutputDirectory --------------------------------------
+ // implements GeneratorContext --------------------------------------
virtual io::ZeroCopyOutputStream* Open(const string& filename) {
string** map_slot = &files_[filename];
@@ -130,24 +130,24 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) {
ASSERT_TRUE(plugin_proto_file != NULL);
CppGenerator generator;
- MockOutputDirectory output_directory;
+ MockGeneratorContext context;
string error;
string parameter;
parameter = "dllexport_decl=LIBPROTOBUF_EXPORT";
ASSERT_TRUE(generator.Generate(proto_file, parameter,
- &output_directory, &error));
+ &context, &error));
parameter = "dllexport_decl=LIBPROTOC_EXPORT";
ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter,
- &output_directory, &error));
-
- output_directory.ExpectFileMatches("google/protobuf/descriptor.pb.h",
- "google/protobuf/descriptor.pb.h");
- output_directory.ExpectFileMatches("google/protobuf/descriptor.pb.cc",
- "google/protobuf/descriptor.pb.cc");
- output_directory.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h",
- "google/protobuf/compiler/plugin.pb.h");
- output_directory.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc",
- "google/protobuf/compiler/plugin.pb.cc");
+ &context, &error));
+
+ context.ExpectFileMatches("google/protobuf/descriptor.pb.h",
+ "google/protobuf/descriptor.pb.h");
+ context.ExpectFileMatches("google/protobuf/descriptor.pb.cc",
+ "google/protobuf/descriptor.pb.cc");
+ context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h",
+ "google/protobuf/compiler/plugin.pb.h");
+ context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc",
+ "google/protobuf/compiler/plugin.pb.cc");
}
} // namespace
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index 91ce493a..a369f417 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -85,7 +85,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
" GOOGLE_DCHECK($type$_IsValid(value));\n"
- " _set_bit($index$);\n"
+ " set_has_$name$();\n"
" $name$_ = value;\n"
"}\n");
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index e31cb425..22d6fdba 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -283,6 +283,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\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"
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc
index d67d3504..bb84e2ab 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -53,7 +53,7 @@ CppGenerator::~CppGenerator() {}
bool CppGenerator::Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error) const {
vector<pair<string, string> > options;
ParseGeneratorParameter(parameter, &options);
@@ -100,7 +100,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
// Generate header.
{
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(basename + ".h"));
+ generator_context->Open(basename + ".h"));
io::Printer printer(output.get(), '$');
file_generator.GenerateHeader(&printer);
}
@@ -108,7 +108,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
// Generate cc file.
{
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(basename + ".cc"));
+ generator_context->Open(basename + ".cc"));
io::Printer printer(output.get(), '$');
file_generator.GenerateSource(&printer);
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.h b/src/google/protobuf/compiler/cpp/cpp_generator.h
index f52e886a..a90e84d7 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.h
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.h
@@ -57,7 +57,7 @@ class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator {
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error) const;
private:
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index cbdcce8f..c4e6fb2c 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -35,6 +35,7 @@
#include <algorithm>
#include <google/protobuf/stubs/hash.h>
#include <map>
+#include <utility>
#include <vector>
#include <google/protobuf/compiler/cpp/cpp_message.h>
#include <google/protobuf/compiler/cpp/cpp_field.h>
@@ -143,6 +144,137 @@ static bool HasRequiredFields(const Descriptor* type) {
return HasRequiredFields(type, &already_seen);
}
+// 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;
+ 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.
+}
+
+// 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 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_;
+ vector<const FieldDescriptor*> fields_;
+ // We rely on the default copy constructor and operator= so this type can be
+ // used in a vector.
+};
+
+// Reorder 'fields' so that if the fields are output into a c++ class in the new
+// order, the alignment padding is minimized. We try to do this while keeping
+// each field as close as possible to its original position so that we don't
+// reduce cache locality much for function that access each field in order.
+void OptimizePadding(vector<const FieldDescriptor*>* fields) {
+ // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
+ vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
+ for (int i = 0; i < fields->size(); ++i) {
+ switch (EstimateAlignmentSize((*fields)[i])) {
+ case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
+ case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
+ case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
+ default:
+ GOOGLE_LOG(FATAL) << "Unknown alignment size.";
+ }
+ }
+
+ // 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.size(); i += 4) {
+ FieldGroup field_group;
+ for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
+ field_group.Append(aligned_to_1[j]);
+ }
+ aligned_to_4.push_back(field_group);
+ }
+ // Sort by preferred location to keep fields as close to their original
+ // location as possible.
+ sort(aligned_to_4.begin(), aligned_to_4.end());
+
+ // Now group fields aligned to 4 bytes (or the 4-field groups created above)
+ // into pairs, and treat those like a single field aligned to 8 bytes.
+ for (int i = 0; i < aligned_to_4.size(); i += 2) {
+ FieldGroup field_group;
+ for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
+ field_group.Append(aligned_to_4[j]);
+ }
+ if (i == aligned_to_4.size() - 1) {
+ // Move incomplete 4-byte block to the end.
+ field_group.SetPreferredLocation(fields->size() + 1);
+ }
+ aligned_to_8.push_back(field_group);
+ }
+ // Sort by preferred location to keep fields as close to their original
+ // location as possible.
+ sort(aligned_to_8.begin(), aligned_to_8.end());
+
+ // Now pull out all the FieldDescriptors in order.
+ fields->clear();
+ for (int i = 0; i < aligned_to_8.size(); ++i) {
+ fields->insert(fields->end(),
+ aligned_to_8[i].fields().begin(),
+ aligned_to_8[i].fields().end());
+ }
+}
+
}
// ===================================================================
@@ -264,10 +396,20 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) {
"}\n");
} else {
// Singular field.
+ char buffer[kFastToBufferSize];
+ vars["has_array_index"] = SimpleItoa(field->index() / 32);
+ vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer);
printer->Print(vars,
"inline bool $classname$::has_$name$() const {\n"
- " return _has_bit($index$);\n"
- "}\n");
+ " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
+ "}\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"
+ " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
+ "}\n"
+ );
}
// Generate clear_$name$()
@@ -279,7 +421,8 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) {
printer->Outdent();
if (!field->is_repeated()) {
- printer->Print(vars, " _clear_bit($index$);\n");
+ printer->Print(vars,
+ " clear_has_$name$();\n");
}
printer->Print("}\n");
@@ -444,28 +587,74 @@ GenerateClassDefinition(io::Printer* printer) {
"// @@protoc_insertion_point(class_scope:$full_name$)\n",
"full_name", descriptor_->full_name());
- // Generate private members for fields.
+ // Generate private members.
printer->Outdent();
printer->Print(" private:\n");
printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->is_repeated()) {
+ printer->Print(
+ "inline void set_has_$name$();\n",
+ "name", FieldName(descriptor_->field(i)));
+ printer->Print(
+ "inline void clear_has_$name$();\n",
+ "name", FieldName(descriptor_->field(i)));
+ }
+ }
+ printer->Print("\n");
+
+ // To minimize padding, data members are divided into three sections:
+ // (1) members assumed to align to 8 bytes
+ // (2) members corresponding to message fields, re-ordered to optimize
+ // alignment.
+ // (3) members assumed to align to 4 bytes.
+
+ // Members assumed to align to 8 bytes:
+
if (descriptor_->extension_range_count() > 0) {
printer->Print(
- "::google::protobuf::internal::ExtensionSet _extensions_;\n");
+ "::google::protobuf::internal::ExtensionSet _extensions_;\n"
+ "\n");
}
if (HasUnknownFields(descriptor_->file())) {
printer->Print(
- "::google::protobuf::UnknownFieldSet _unknown_fields_;\n");
+ "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
+ "\n");
+ }
+
+ // Field members:
+
+ vector<const FieldDescriptor*> fields;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ fields.push_back(descriptor_->field(i));
+ }
+ OptimizePadding(&fields);
+ for (int i = 0; i < fields.size(); ++i) {
+ field_generators_.get(fields[i]).GeneratePrivateMembers(printer);
}
+ // Members assumed to align to 4 bytes:
+
// TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
printer->Print(
- "mutable int _cached_size_;\n"
- "\n");
- for (int i = 0; i < descriptor_->field_count(); i++) {
- field_generators_.get(descriptor_->field(i))
- .GeneratePrivateMembers(printer);
+ "\n"
+ "mutable int _cached_size_;\n");
+
+ // Generate _has_bits_.
+ if (descriptor_->field_count() > 0) {
+ printer->Print(vars,
+ "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n"
+ "\n");
+ } else {
+ // Zero-size arrays aren't technically allowed, and MSVC in particular
+ // doesn't like them. We still need to declare these arrays to make
+ // other code compile. Since this is an uncommon case, we'll just declare
+ // them with size 1 and waste some space. Oh well.
+ printer->Print(
+ "::google::protobuf::uint32 _has_bits_[1];\n"
+ "\n");
}
// Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
@@ -484,32 +673,7 @@ GenerateClassDefinition(io::Printer* printer) {
GlobalAssignDescriptorsName(descriptor_->file()->name()),
"shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
- // Generate offsets and _has_bits_ boilerplate.
- if (descriptor_->field_count() > 0) {
- printer->Print(vars,
- "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n");
- } else {
- // Zero-size arrays aren't technically allowed, and MSVC in particular
- // doesn't like them. We still need to declare these arrays to make
- // other code compile. Since this is an uncommon case, we'll just declare
- // them with size 1 and waste some space. Oh well.
- printer->Print(
- "::google::protobuf::uint32 _has_bits_[1];\n");
- }
-
printer->Print(
- "\n"
- "// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?\n"
- "inline bool _has_bit(int index) const {\n"
- " return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;\n"
- "}\n"
- "inline void _set_bit(int index) {\n"
- " _has_bits_[index / 32] |= (1u << (index % 32));\n"
- "}\n"
- "inline void _clear_bit(int index) {\n"
- " _has_bits_[index / 32] &= ~(1u << (index % 32));\n"
- "}\n"
- "\n"
"void InitAsDefaultInstance();\n"
"static $classname$* default_instance_;\n",
"classname", classname_);
@@ -961,9 +1125,6 @@ GenerateClear(io::Printer* printer) {
const FieldDescriptor* field = descriptor_->field(i);
if (!field->is_repeated()) {
- map<string, string> vars;
- vars["index"] = SimpleItoa(field->index());
-
// We can use the fact that _has_bits_ is a giant bitfield to our
// advantage: We can check up to 32 bits at a time for equality to
// zero, and skip the whole range if so. This can improve the speed
@@ -975,8 +1136,9 @@ GenerateClear(io::Printer* printer) {
printer->Outdent();
printer->Print("}\n");
}
- printer->Print(vars,
- "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
+ printer->Print(
+ "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
+ "index", SimpleItoa(field->index()));
printer->Indent();
}
last_index = i;
@@ -989,7 +1151,9 @@ GenerateClear(io::Printer* printer) {
field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
if (should_check_bit) {
- printer->Print(vars, "if (_has_bit($index$)) {\n");
+ printer->Print(
+ "if (has_$name$()) {\n",
+ "name", FieldName(field));
printer->Indent();
}
@@ -1129,24 +1293,23 @@ GenerateMergeFrom(io::Printer* printer) {
const FieldDescriptor* field = descriptor_->field(i);
if (!field->is_repeated()) {
- map<string, string> vars;
- vars["index"] = SimpleItoa(field->index());
-
// See above in GenerateClear for an explanation of this.
if (i / 8 != last_index / 8 || last_index < 0) {
if (last_index >= 0) {
printer->Outdent();
printer->Print("}\n");
}
- printer->Print(vars,
- "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
+ printer->Print(
+ "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
+ "index", SimpleItoa(field->index()));
printer->Indent();
}
last_index = i;
- printer->Print(vars,
- "if (from._has_bit($index$)) {\n");
+ printer->Print(
+ "if (from.has_$name$()) {\n",
+ "name", FieldName(field));
printer->Indent();
field_generators_.get(field).GenerateMergingCode(printer);
@@ -1423,8 +1586,8 @@ void MessageGenerator::GenerateSerializeOneField(
if (!field->is_repeated()) {
printer->Print(
- "if (_has_bit($index$)) {\n",
- "index", SimpleItoa(field->index()));
+ "if (has_$name$()) {\n",
+ "name", FieldName(field));
printer->Indent();
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index c04bdc66..23e75b87 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -75,7 +75,8 @@ void MessageFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
"inline const $type$& $name$() const$deprecation$;\n"
- "inline $type$* mutable_$name$()$deprecation$;\n");
+ "inline $type$* mutable_$name$()$deprecation$;\n"
+ "inline $type$* release_$name$()$deprecation$;\n");
}
void MessageFieldGenerator::
@@ -85,9 +86,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
" return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n"
"}\n"
"inline $type$* $classname$::mutable_$name$() {\n"
- " _set_bit($index$);\n"
+ " set_has_$name$();\n"
" if ($name$_ == NULL) $name$_ = new $type$;\n"
" return $name$_;\n"
+ "}\n"
+ "inline $type$* $classname$::release_$name$() {\n"
+ " clear_has_$name$();\n"
+ " $type$* temp = $name$_;\n"
+ " $name$_ = NULL;\n"
+ " return temp;\n"
"}\n");
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
index 440b7166..5c4aa4fb 100644
--- a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
@@ -56,24 +56,24 @@ class TestGenerator : public CodeGenerator {
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
- TryInsert("test.pb.h", "includes", output_directory);
- TryInsert("test.pb.h", "namespace_scope", output_directory);
- TryInsert("test.pb.h", "global_scope", output_directory);
- TryInsert("test.pb.h", "class_scope:foo.Bar", output_directory);
- TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", output_directory);
+ TryInsert("test.pb.h", "includes", context);
+ TryInsert("test.pb.h", "namespace_scope", context);
+ TryInsert("test.pb.h", "global_scope", context);
+ TryInsert("test.pb.h", "class_scope:foo.Bar", context);
+ TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", context);
- TryInsert("test.pb.cc", "includes", output_directory);
- TryInsert("test.pb.cc", "namespace_scope", output_directory);
- TryInsert("test.pb.cc", "global_scope", output_directory);
+ TryInsert("test.pb.cc", "includes", context);
+ TryInsert("test.pb.cc", "namespace_scope", context);
+ TryInsert("test.pb.cc", "global_scope", context);
return true;
}
void TryInsert(const string& filename, const string& insertion_point,
- OutputDirectory* output_directory) const {
+ GeneratorContext* context) const {
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->OpenForInsert(filename, insertion_point));
+ context->OpenForInsert(filename, insertion_point));
io::Printer printer(output.get(), '$');
printer.Print("// inserted $name$\n", "name", insertion_point);
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index a69c48b5..5e8df0f4 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -125,7 +125,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
" return $name$_;\n"
"}\n"
"inline void $classname$::set_$name$($type$ value) {\n"
- " _set_bit($index$);\n"
+ " set_has_$name$();\n"
" $name$_ = value;\n"
"}\n");
}
@@ -156,7 +156,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
"DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
" $type$, $wire_format_field_type$>(\n"
" input, &$name$_)));\n"
- "_set_bit($index$);\n");
+ "set_has_$name$();\n");
}
void PrimitiveFieldGenerator::
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index ea6809a9..67d7eae6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -50,6 +50,9 @@ void SetStringVariables(const FieldDescriptor* descriptor,
SetCommonFieldVariables(descriptor, variables);
(*variables)["default"] =
"\"" + CEscape(descriptor->default_value_string()) + "\"";
+ (*variables)["default_variable"] = descriptor->default_value_string().empty()
+ ? "::google::protobuf::internal::kEmptyString"
+ : "_default_" + FieldName(descriptor) + "_";
(*variables)["pointer_type"] =
descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
}
@@ -68,9 +71,10 @@ StringFieldGenerator::~StringFieldGenerator() {}
void StringFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
- printer->Print(variables_,
- "::std::string* $name$_;\n"
- "static const ::std::string _default_$name$_;\n");
+ printer->Print(variables_, "::std::string* $name$_;\n");
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_, "static const ::std::string $default_variable$;\n");
+ }
}
void StringFieldGenerator::
@@ -105,7 +109,8 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
"inline void set_$name$(const char* value)$deprecation$;\n"
"inline void set_$name$(const $pointer_type$* value, size_t size)"
"$deprecation$;\n"
- "inline ::std::string* mutable_$name$()$deprecation$;\n");
+ "inline ::std::string* mutable_$name$()$deprecation$;\n"
+ "inline ::std::string* release_$name$()$deprecation$;\n");
if (descriptor_->options().ctype() != FieldOptions::STRING) {
printer->Outdent();
@@ -121,51 +126,58 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const {
" return *$name$_;\n"
"}\n"
"inline void $classname$::set_$name$(const ::std::string& value) {\n"
- " _set_bit($index$);\n"
- " if ($name$_ == &_default_$name$_) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == &$default_variable$) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(value);\n"
"}\n"
"inline void $classname$::set_$name$(const char* value) {\n"
- " _set_bit($index$);\n"
- " if ($name$_ == &_default_$name$_) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == &$default_variable$) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(value);\n"
"}\n"
"inline "
"void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
- " _set_bit($index$);\n"
- " if ($name$_ == &_default_$name$_) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == &$default_variable$) {\n"
" $name$_ = new ::std::string;\n"
" }\n"
" $name$_->assign(reinterpret_cast<const char*>(value), size);\n"
"}\n"
"inline ::std::string* $classname$::mutable_$name$() {\n"
- " _set_bit($index$);\n"
- " if ($name$_ == &_default_$name$_) {\n");
+ " set_has_$name$();\n"
+ " if ($name$_ == &$default_variable$) {\n");
if (descriptor_->default_value_string().empty()) {
printer->Print(variables_,
" $name$_ = new ::std::string;\n");
} else {
printer->Print(variables_,
- " $name$_ = new ::std::string(_default_$name$_);\n");
+ " $name$_ = new ::std::string($default_variable$);\n");
}
printer->Print(variables_,
" }\n"
" return $name$_;\n"
+ "}\n"
+ "inline ::std::string* $classname$::release_$name$() {\n"
+ " clear_has_$name$();\n"
+ " if ($name$_ == &$default_variable$) {\n"
+ " return NULL;\n"
+ " } else {\n"
+ " ::std::string* temp = $name$_;\n"
+ " $name$_ = const_cast< ::std::string*>(&$default_variable$);\n"
+ " return temp;\n"
+ " }\n"
"}\n");
}
void StringFieldGenerator::
GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
- if (descriptor_->default_value_string().empty()) {
- printer->Print(variables_,
- "const ::std::string $classname$::_default_$name$_;\n");
- } else {
+ if (!descriptor_->default_value_string().empty()) {
printer->Print(variables_,
- "const ::std::string $classname$::_default_$name$_($default$);\n");
+ "const ::std::string $classname$::$default_variable$($default$);\n");
}
}
@@ -173,13 +185,13 @@ void StringFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
if (descriptor_->default_value_string().empty()) {
printer->Print(variables_,
- "if ($name$_ != &_default_$name$_) {\n"
+ "if ($name$_ != &$default_variable$) {\n"
" $name$_->clear();\n"
"}\n");
} else {
printer->Print(variables_,
- "if ($name$_ != &_default_$name$_) {\n"
- " $name$_->assign(_default_$name$_);\n"
+ "if ($name$_ != &$default_variable$) {\n"
+ " $name$_->assign($default_variable$);\n"
"}\n");
}
}
@@ -197,13 +209,13 @@ GenerateSwappingCode(io::Printer* printer) const {
void StringFieldGenerator::
GenerateConstructorCode(io::Printer* printer) const {
printer->Print(variables_,
- "$name$_ = const_cast< ::std::string*>(&_default_$name$_);\n");
+ "$name$_ = const_cast< ::std::string*>(&$default_variable$);\n");
}
void StringFieldGenerator::
GenerateDestructorCode(io::Printer* printer) const {
printer->Print(variables_,
- "if ($name$_ != &_default_$name$_) {\n"
+ "if ($name$_ != &$default_variable$) {\n"
" delete $name$_;\n"
"}\n");
}
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 79971a95..54d830fc 100644
--- a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
+++ b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
@@ -36,6 +36,10 @@
// though the same identifiers are used internally by the C++ code generator.
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
package protobuf_unittest;
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index a7e852de..41ba5e43 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -195,6 +195,48 @@ TEST(GeneratedMessageTest, MutableStringDefault) {
EXPECT_EQ("hello", *message.mutable_default_string());
}
+TEST(GeneratedMessageTest, ReleaseString) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ unittest::TestAllTypes message;
+
+ EXPECT_EQ(NULL, message.release_default_string());
+ EXPECT_FALSE(message.has_default_string());
+ EXPECT_EQ("hello", message.default_string());
+
+ message.set_default_string("blah");
+ EXPECT_TRUE(message.has_default_string());
+ string* str = message.release_default_string();
+ EXPECT_FALSE(message.has_default_string());
+ ASSERT_TRUE(str != NULL);
+ EXPECT_EQ("blah", *str);
+ delete str;
+
+ EXPECT_EQ(NULL, message.release_default_string());
+ EXPECT_FALSE(message.has_default_string());
+ EXPECT_EQ("hello", message.default_string());
+}
+
+TEST(GeneratedMessageTest, ReleaseMessage) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ unittest::TestAllTypes message;
+
+ EXPECT_EQ(NULL, message.release_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_nested_message());
+
+ message.mutable_optional_nested_message()->set_bb(1);
+ unittest::TestAllTypes::NestedMessage* nest =
+ message.release_optional_nested_message();
+ EXPECT_FALSE(message.has_optional_nested_message());
+ ASSERT_TRUE(nest != NULL);
+ EXPECT_EQ(1, nest->bb());
+ delete nest;
+
+ EXPECT_EQ(NULL, message.release_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_nested_message());
+}
+
TEST(GeneratedMessageTest, Clear) {
// Set every field to a unique value, clear the message, then check that
// it is cleared.
@@ -282,6 +324,7 @@ TEST(GeneratedMessageTest, CopyFrom) {
TestUtil::ExpectAllFieldsSet(message2);
}
+
TEST(GeneratedMessageTest, SwapWithEmpty) {
unittest::TestAllTypes message1, message2;
TestUtil::SetAllFields(&message1);
@@ -376,7 +419,7 @@ TEST(GeneratedMessageTest, CopyAssignmentOperator) {
TestUtil::ExpectAllFieldsSet(message2);
// Make sure that self-assignment does something sane.
- message2 = message2;
+ message2.operator=(message2);
TestUtil::ExpectAllFieldsSet(message2);
}
@@ -718,6 +761,7 @@ TEST(GeneratedMessageTest, TestSpaceUsed) {
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
TEST(GeneratedMessageTest, FieldConstantValues) {
unittest::TestRequired message;
EXPECT_EQ(unittest::TestAllTypes_NestedMessage::kBbFieldNumber, 1);
diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc
index e796587f..9d7bcab6 100644
--- a/src/google/protobuf/compiler/java/java_enum.cc
+++ b/src/google/protobuf/compiler/java/java_enum.cc
@@ -104,6 +104,15 @@ void EnumGenerator::Generate(io::Printer* printer) {
"public static final $classname$ $name$ = $canonical_name$;\n");
}
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ map<string, string> vars;
+ vars["name"] = descriptor_->value(i)->name();
+ vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+ printer->Print(vars,
+ "public static final int $name$_VALUE = $number$;\n");
+ }
+ printer->Print("\n");
+
// -----------------------------------------------------------------
printer->Print(
@@ -219,17 +228,6 @@ void EnumGenerator::Generate(io::Printer* printer) {
" this.value = value;\n"
"}\n");
- if (HasDescriptorMethods(descriptor_)) {
- // Force the static initialization code for the file to run, since it may
- // initialize static variables declared in this class.
- printer->Print(
- "\n"
- "static {\n"
- " $file$.getDescriptor();\n"
- "}\n",
- "file", ClassName(descriptor_->file()));
- }
-
printer->Print(
"\n"
"// @@protoc_insertion_point(enum_scope:$full_name$)\n",
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
index af6b1cd2..72caa10b 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -52,17 +52,44 @@ namespace {
// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
// repeat code between this and the other field types.
void SetEnumVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
map<string, string>* variables) {
(*variables)["name"] =
UnderscoresToCamelCase(descriptor);
(*variables)["capitalized_name"] =
UnderscoresToCapitalizedCamelCase(descriptor);
+ (*variables)["constant_name"] = FieldConstantName(descriptor);
(*variables)["number"] = SimpleItoa(descriptor->number());
(*variables)["type"] = ClassName(descriptor->enum_type());
(*variables)["default"] = DefaultValue(descriptor);
(*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
(*variables)["tag_size"] = SimpleItoa(
internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? "@java.lang.Deprecated " : "";
+ (*variables)["on_changed"] =
+ HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex);
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
}
} // namespace
@@ -70,52 +97,88 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
// ===================================================================
EnumFieldGenerator::
-EnumFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetEnumVariables(descriptor, &variables_);
+EnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, &variables_);
}
EnumFieldGenerator::~EnumFieldGenerator() {}
+int EnumFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int EnumFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void EnumFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n"
+ "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
void EnumFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private boolean has$capitalized_name$;\n"
"private $type$ $name$_;\n"
- "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
- "public $type$ get$capitalized_name$() { return $name$_; }\n");
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
}
void EnumFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
- "public boolean has$capitalized_name$() {\n"
- " return result.has$capitalized_name$();\n"
+ "private $type$ $name$_ = $default$;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
"}\n"
- "public $type$ get$capitalized_name$() {\n"
- " return result.get$capitalized_name$();\n"
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
"}\n"
- "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"
- " result.has$capitalized_name$ = true;\n"
- " result.$name$_ = value;\n"
+ " $set_has_field_bit_builder$;\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
" return this;\n"
"}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.has$capitalized_name$ = false;\n"
- " result.$name$_ = $default$;\n"
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_builder$;\n"
+ " $name$_ = $default$;\n"
+ " $on_changed$\n"
" return this;\n"
"}\n");
}
void EnumFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for enums
+}
+
+void EnumFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
printer->Print(variables_, "$name$_ = $default$;\n");
}
void EnumFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$;\n");
+}
+
+void EnumFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
printer->Print(variables_,
"if (other.has$capitalized_name$()) {\n"
@@ -125,7 +188,11 @@ GenerateMergingCode(io::Printer* printer) const {
void EnumFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
- // Nothing to do here for enum types.
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
}
void EnumFieldGenerator::
@@ -143,27 +210,42 @@ GenerateParsingCode(io::Printer* printer) const {
"if (value != null) {\n");
}
printer->Print(variables_,
- " set$capitalized_name$(value);\n"
+ " $set_has_field_bit_builder$;\n"
+ " $name$_ = value;\n"
"}\n");
}
void EnumFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
- " output.writeEnum($number$, get$capitalized_name$().getNumber());\n"
+ "if ($get_has_field_bit_message$) {\n"
+ " output.writeEnum($number$, $name$_.getNumber());\n"
"}\n");
}
void EnumFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
+ "if ($get_has_field_bit_message$) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .computeEnumSize($number$, get$capitalized_name$().getNumber());\n"
+ " .computeEnumSize($number$, $name$_.getNumber());\n"
"}\n");
}
+void EnumFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result &&\n"
+ " (get$capitalized_name$() == other.get$capitalized_name$());\n");
+}
+
+void EnumFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n"
+ "hash = (53 * hash) + hashEnum(get$capitalized_name$());\n");
+}
+
string EnumFieldGenerator::GetBoxedType() const {
return ClassName(descriptor_->enum_type());
}
@@ -171,23 +253,43 @@ string EnumFieldGenerator::GetBoxedType() const {
// ===================================================================
RepeatedEnumFieldGenerator::
-RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetEnumVariables(descriptor, &variables_);
+RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, &variables_);
}
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+int RepeatedEnumFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedEnumFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n"
+ "$deprecation$int get$capitalized_name$Count();\n"
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+}
+
void RepeatedEnumFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private java.util.List<$type$> $name$_ =\n"
- " java.util.Collections.emptyList();\n"
- "public java.util.List<$type$> get$capitalized_name$List() {\n"
+ "private java.util.List<$type$> $name$_;\n"
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
"}\n"
- "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
- "public $type$ get$capitalized_name$(int index) {\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n");
@@ -201,73 +303,119 @@ GenerateMembers(io::Printer* printer) const {
void RepeatedEnumFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
+ // One field is the list and the other field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ "private java.util.List<$type$> $name$_ =\n"
+ " java.util.Collections.emptyList();\n"
+
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n"
+
// Note: We return an unmodifiable list because otherwise the caller
// 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.
- "public java.util.List<$type$> get$capitalized_name$List() {\n"
- " return java.util.Collections.unmodifiableList(result.$name$_);\n"
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
"}\n"
- "public int get$capitalized_name$Count() {\n"
- " return result.get$capitalized_name$Count();\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
"}\n"
- "public $type$ get$capitalized_name$(int index) {\n"
- " return result.get$capitalized_name$(index);\n"
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
"}\n"
- "public Builder set$capitalized_name$(int index, $type$ value) {\n"
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$ value) {\n"
" if (value == null) {\n"
" throw new NullPointerException();\n"
" }\n"
- " result.$name$_.set(index, value);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
" return this;\n"
"}\n"
- "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"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
- " }\n"
- " result.$name$_.add(value);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
" return this;\n"
"}\n"
- "public Builder addAll$capitalized_name$(\n"
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
" java.lang.Iterable<? extends $type$> values) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
- " }\n"
- " super.addAll(values, result.$name$_);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " super.addAll(values, $name$_);\n"
+ " $on_changed$\n"
" return this;\n"
"}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.$name$_ = java.util.Collections.emptyList();\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");
}
void RepeatedEnumFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for enums
+}
+
+void RepeatedEnumFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- // Initialized inline.
+ printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n");
}
void RepeatedEnumFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
+ // The code below does two optimizations:
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
printer->Print(variables_,
"if (!other.$name$_.isEmpty()) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
" }\n"
- " result.$name$_.addAll(other.$name$_);\n"
+ " $on_changed$\n"
"}\n");
}
void RepeatedEnumFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
printer->Print(variables_,
- "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
- " result.$name$_ =\n"
- " java.util.Collections.unmodifiableList(result.$name$_);\n"
- "}\n");
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
}
void RepeatedEnumFieldGenerator::
@@ -316,13 +464,13 @@ GenerateSerializationCode(io::Printer* printer) const {
" output.writeRawVarint32($tag$);\n"
" output.writeRawVarint32($name$MemoizedSerializedSize);\n"
"}\n"
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.writeEnumNoTag(element.getNumber());\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeEnumNoTag($name$_.get(i).getNumber());\n"
"}\n");
} else {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.writeEnum($number$, element.getNumber());\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeEnum($number$, $name$_.get(i).getNumber());\n"
"}\n");
}
}
@@ -335,9 +483,9 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Indent();
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
" dataSize += com.google.protobuf.CodedOutputStream\n"
- " .computeEnumSizeNoTag(element.getNumber());\n"
+ " .computeEnumSizeNoTag($name$_.get(i).getNumber());\n"
"}\n");
printer->Print(
"size += dataSize;\n");
@@ -350,7 +498,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
"}");
} else {
printer->Print(variables_,
- "size += $tag_size$ * get$capitalized_name$List().size();\n");
+ "size += $tag_size$ * $name$_.size();\n");
}
// cache the data size for packed fields.
@@ -363,6 +511,22 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print("}\n");
}
+void RepeatedEnumFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + hashEnumList(get$capitalized_name$List());\n"
+ "}\n");
+}
+
string RepeatedEnumFieldGenerator::GetBoxedType() const {
return ClassName(descriptor_->enum_type());
}
diff --git a/src/google/protobuf/compiler/java/java_enum_field.h b/src/google/protobuf/compiler/java/java_enum_field.h
index c54a0faf..0cad6be0 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.h
+++ b/src/google/protobuf/compiler/java/java_enum_field.h
@@ -46,49 +46,69 @@ namespace java {
class EnumFieldGenerator : public FieldGenerator {
public:
- explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
+ explicit EnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
~EnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
private:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
};
class RepeatedEnumFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor);
+ explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
~RepeatedEnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingCodeFromPacked(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
private:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
};
diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc
index 903b0a9b..9b147c77 100644
--- a/src/google/protobuf/compiler/java/java_extension.cc
+++ b/src/google/protobuf/compiler/java/java_extension.cc
@@ -86,108 +86,123 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor)
ExtensionGenerator::~ExtensionGenerator() {}
-void ExtensionGenerator::Generate(io::Printer* printer) {
- map<string, string> vars;
- vars["name"] = UnderscoresToCamelCase(descriptor_);
- vars["containing_type"] = ClassName(descriptor_->containing_type());
- vars["number"] = SimpleItoa(descriptor_->number());
- vars["constant_name"] = FieldConstantName(descriptor_);
- vars["lite"] = HasDescriptorMethods(descriptor_->file()) ? "" : "Lite";
+// Initializes the vars referenced in the generated code templates.
+void InitTemplateVars(const FieldDescriptor* descriptor,
+ const string& scope,
+ map<string, string>* vars_pointer) {
+ map<string, string> &vars = *vars_pointer;
+ vars["scope"] = scope;
+ vars["name"] = UnderscoresToCamelCase(descriptor);
+ vars["containing_type"] = ClassName(descriptor->containing_type());
+ vars["number"] = SimpleItoa(descriptor->number());
+ vars["constant_name"] = FieldConstantName(descriptor);
+ vars["index"] = SimpleItoa(descriptor->index());
+ vars["default"] =
+ descriptor->is_repeated() ? "" : DefaultValue(descriptor);
+ vars["type_constant"] = TypeName(GetType(descriptor));
+ vars["packed"] = descriptor->options().packed() ? "true" : "false";
+ vars["enum_map"] = "null";
+ vars["prototype"] = "null";
- JavaType java_type = GetJavaType(descriptor_);
+ JavaType java_type = GetJavaType(descriptor);
string singular_type;
switch (java_type) {
case JAVATYPE_MESSAGE:
- vars["type"] = ClassName(descriptor_->message_type());
+ singular_type = ClassName(descriptor->message_type());
+ vars["prototype"] = singular_type + ".getDefaultInstance()";
break;
case JAVATYPE_ENUM:
- vars["type"] = ClassName(descriptor_->enum_type());
+ singular_type = ClassName(descriptor->enum_type());
+ vars["enum_map"] = singular_type + ".internalGetValueMap()";
break;
default:
- vars["type"] = BoxedPrimitiveTypeName(java_type);
+ singular_type = BoxedPrimitiveTypeName(java_type);
break;
}
-
- printer->Print(vars,
- "public static final int $constant_name$ = $number$;\n");
- if (descriptor_->is_repeated()) {
- printer->Print(vars,
- "public static final\n"
- " com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n"
- " $containing_type$,\n"
- " java.util.List<$type$>> $name$ =\n"
- " com.google.protobuf.GeneratedMessage$lite$\n"
- " .newGeneratedExtension();\n");
- } else {
- printer->Print(vars,
- "public static final\n"
- " com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n"
- " $containing_type$,\n"
- " $type$> $name$ =\n"
- " com.google.protobuf.GeneratedMessage$lite$\n"
- " .newGeneratedExtension();\n");
- }
+ vars["type"] = descriptor->is_repeated() ?
+ "java.util.List<" + singular_type + ">" : singular_type;
+ vars["singular_type"] = singular_type;
}
-void ExtensionGenerator::GenerateInitializationCode(io::Printer* printer) {
+void ExtensionGenerator::Generate(io::Printer* printer) {
map<string, string> vars;
- vars["name"] = UnderscoresToCamelCase(descriptor_);
- vars["scope"] = scope_;
- vars["index"] = SimpleItoa(descriptor_->index());
- vars["extendee"] = ClassName(descriptor_->containing_type());
- vars["default"] = descriptor_->is_repeated() ? "" : DefaultValue(descriptor_);
- vars["number"] = SimpleItoa(descriptor_->number());
- vars["type_constant"] = TypeName(GetType(descriptor_));
- vars["packed"] = descriptor_->options().packed() ? "true" : "false";
- vars["enum_map"] = "null";
- vars["prototype"] = "null";
-
- JavaType java_type = GetJavaType(descriptor_);
- string singular_type;
- switch (java_type) {
- case JAVATYPE_MESSAGE:
- vars["type"] = ClassName(descriptor_->message_type());
- vars["prototype"] = ClassName(descriptor_->message_type()) +
- ".getDefaultInstance()";
- break;
- case JAVATYPE_ENUM:
- vars["type"] = ClassName(descriptor_->enum_type());
- vars["enum_map"] = ClassName(descriptor_->enum_type()) +
- ".internalGetValueMap()";
- break;
- default:
- vars["type"] = BoxedPrimitiveTypeName(java_type);
- break;
- }
+ InitTemplateVars(descriptor_, scope_, &vars);
+ printer->Print(vars,
+ "public static final int $constant_name$ = $number$;\n");
if (HasDescriptorMethods(descriptor_->file())) {
- printer->Print(vars,
- "$scope$.$name$.internalInit(\n"
- " $scope$.getDescriptor().getExtensions().get($index$),\n"
- " $type$.class);\n");
+ // Non-lite extensions
+ if (descriptor_->extension_scope() == NULL) {
+ // Non-nested
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
+ " .newFileScopedGeneratedExtension(\n"
+ " $singular_type$.class,\n"
+ " $prototype$);\n");
+ } else {
+ // Nested
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
+ " .newMessageScopedGeneratedExtension(\n"
+ " $scope$.getDefaultInstance(),\n"
+ " $index$,\n"
+ " $singular_type$.class,\n"
+ " $prototype$);\n");
+ }
} else {
+ // Lite extensions
if (descriptor_->is_repeated()) {
- printer->Print(vars,
- "$scope$.$name$.internalInitRepeated(\n"
- " $extendee$.getDefaultInstance(),\n"
- " $prototype$,\n"
- " $enum_map$,\n"
- " $number$,\n"
- " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
- " $packed$);\n");
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
+ " .newRepeatedGeneratedExtension(\n"
+ " $containing_type$.getDefaultInstance(),\n"
+ " $prototype$,\n"
+ " $enum_map$,\n"
+ " $number$,\n"
+ " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
+ " $packed$);\n");
} else {
- printer->Print(vars,
- "$scope$.$name$.internalInitSingular(\n"
- " $extendee$.getDefaultInstance(),\n"
- " $default$,\n"
- " $prototype$,\n"
- " $enum_map$,\n"
- " $number$,\n"
- " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n");
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
+ " .newSingularGeneratedExtension(\n"
+ " $containing_type$.getDefaultInstance(),\n"
+ " $default$,\n"
+ " $prototype$,\n"
+ " $enum_map$,\n"
+ " $number$,\n"
+ " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n");
}
}
}
+void ExtensionGenerator::GenerateNonNestedInitializationCode(
+ io::Printer* printer) {
+ if (descriptor_->extension_scope() == NULL &&
+ HasDescriptorMethods(descriptor_->file())) {
+ // Only applies to non-nested, non-lite extensions.
+ printer->Print(
+ "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
+ "name", UnderscoresToCamelCase(descriptor_),
+ "index", SimpleItoa(descriptor_->index()));
+ }
+}
+
void ExtensionGenerator::GenerateRegistrationCode(io::Printer* printer) {
printer->Print(
"registry.add($scope$.$name$);\n",
diff --git a/src/google/protobuf/compiler/java/java_extension.h b/src/google/protobuf/compiler/java/java_extension.h
index 1e423048..009ed9ff 100644
--- a/src/google/protobuf/compiler/java/java_extension.h
+++ b/src/google/protobuf/compiler/java/java_extension.h
@@ -60,7 +60,7 @@ class ExtensionGenerator {
~ExtensionGenerator();
void Generate(io::Printer* printer);
- void GenerateInitializationCode(io::Printer* printer);
+ void GenerateNonNestedInitializationCode(io::Printer* printer);
void GenerateRegistrationCode(io::Printer* printer);
private:
diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc
index 978c8f33..c7d433c8 100644
--- a/src/google/protobuf/compiler/java/java_field.cc
+++ b/src/google/protobuf/compiler/java/java_field.cc
@@ -37,6 +37,7 @@
#include <google/protobuf/compiler/java/java_primitive_field.h>
#include <google/protobuf/compiler/java/java_enum_field.h>
#include <google/protobuf/compiler/java/java_message_field.h>
+#include <google/protobuf/compiler/java/java_string_field.h>
#include <google/protobuf/stubs/common.h>
namespace google {
@@ -63,33 +64,57 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
extension_generators_(
new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) {
- // Construct all the FieldGenerators.
+ // Construct all the FieldGenerators and assign them bit indices for their
+ // bit fields.
+ int messageBitIndex = 0;
+ int builderBitIndex = 0;
for (int i = 0; i < descriptor->field_count(); i++) {
- field_generators_[i].reset(MakeGenerator(descriptor->field(i)));
+ FieldGenerator* generator = MakeGenerator(descriptor->field(i),
+ messageBitIndex, builderBitIndex);
+ field_generators_[i].reset(generator);
+ messageBitIndex += generator->GetNumBitsForMessage();
+ builderBitIndex += generator->GetNumBitsForBuilder();
}
for (int i = 0; i < descriptor->extension_count(); i++) {
- extension_generators_[i].reset(MakeGenerator(descriptor->extension(i)));
+ FieldGenerator* generator = MakeGenerator(descriptor->extension(i),
+ messageBitIndex, builderBitIndex);
+ extension_generators_[i].reset(generator);
+ messageBitIndex += generator->GetNumBitsForMessage();
+ builderBitIndex += generator->GetNumBitsForBuilder();
}
}
-FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
+FieldGenerator* FieldGeneratorMap::MakeGenerator(
+ const FieldDescriptor* field, int messageBitIndex, int builderBitIndex) {
if (field->is_repeated()) {
switch (GetJavaType(field)) {
case JAVATYPE_MESSAGE:
- return new RepeatedMessageFieldGenerator(field);
+ return new RepeatedMessageFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
case JAVATYPE_ENUM:
- return new RepeatedEnumFieldGenerator(field);
+ return new RepeatedEnumFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
+ case JAVATYPE_STRING:
+ return new RepeatedStringFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
default:
- return new RepeatedPrimitiveFieldGenerator(field);
+ return new RepeatedPrimitiveFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
}
} else {
switch (GetJavaType(field)) {
case JAVATYPE_MESSAGE:
- return new MessageFieldGenerator(field);
+ return new MessageFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
case JAVATYPE_ENUM:
- return new EnumFieldGenerator(field);
+ return new EnumFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
+ case JAVATYPE_STRING:
+ return new StringFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
default:
- return new PrimitiveFieldGenerator(field);
+ return new PrimitiveFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
}
}
}
diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h
index f5bef7ab..6097f357 100644
--- a/src/google/protobuf/compiler/java/java_field.h
+++ b/src/google/protobuf/compiler/java/java_field.h
@@ -55,15 +55,24 @@ class FieldGenerator {
FieldGenerator() {}
virtual ~FieldGenerator();
+ virtual int GetNumBitsForMessage() const = 0;
+ virtual int GetNumBitsForBuilder() const = 0;
+ virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0;
virtual void GenerateMembers(io::Printer* printer) const = 0;
virtual void GenerateBuilderMembers(io::Printer* printer) const = 0;
virtual void GenerateInitializationCode(io::Printer* printer) const = 0;
+ virtual void GenerateBuilderClearCode(io::Printer* printer) const = 0;
virtual void GenerateMergingCode(io::Printer* printer) const = 0;
virtual void GenerateBuildingCode(io::Printer* printer) const = 0;
virtual void GenerateParsingCode(io::Printer* printer) const = 0;
virtual void GenerateParsingCodeFromPacked(io::Printer* printer) const;
virtual void GenerateSerializationCode(io::Printer* printer) const = 0;
virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
+ virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer)
+ const = 0;
+
+ virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
+ virtual void GenerateHashCode(io::Printer* printer) const = 0;
virtual string GetBoxedType() const = 0;
@@ -85,7 +94,8 @@ class FieldGeneratorMap {
scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
scoped_array<scoped_ptr<FieldGenerator> > extension_generators_;
- static FieldGenerator* MakeGenerator(const FieldDescriptor* field);
+ static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
+ int messageBitIndex, int builderBitIndex);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
};
diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc
index 7ea127c0..8968069f 100644
--- a/src/google/protobuf/compiler/java/java_file.cc
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -88,7 +88,8 @@ bool UsesExtensions(const Message& message) {
FileGenerator::FileGenerator(const FileDescriptor* file)
: file_(file),
java_package_(FileJavaPackage(file)),
- classname_(FileClassName(file)) {}
+ classname_(FileClassName(file)) {
+}
FileGenerator::~FileGenerator() {}
@@ -179,7 +180,9 @@ void FileGenerator::Generate(io::Printer* printer) {
EnumGenerator(file_->enum_type(i)).Generate(printer);
}
for (int i = 0; i < file_->message_type_count(); i++) {
- MessageGenerator(file_->message_type(i)).Generate(printer);
+ MessageGenerator messageGenerator(file_->message_type(i));
+ messageGenerator.GenerateInterface(printer);
+ messageGenerator.Generate(printer);
}
if (HasGenericServices(file_)) {
for (int i = 0; i < file_->service_count(); i++) {
@@ -215,24 +218,11 @@ void FileGenerator::Generate(io::Printer* printer) {
.GenerateStaticVariableInitializers(printer);
}
- for (int i = 0; i < file_->extension_count(); i++) {
- // TODO(kenton): Reuse ExtensionGenerator objects?
- ExtensionGenerator(file_->extension(i))
- .GenerateInitializationCode(printer);
- }
-
printer->Outdent();
printer->Print(
"}\n");
}
- // Dummy function we can use to force the static initialization block to
- // run. Needed by inner classes. Cannot be private due to
- // java_multiple_files option.
- printer->Print(
- "\n"
- "public static void internalForceInit() {}\n");
-
printer->Print(
"\n"
"// @@protoc_insertion_point(outer_class_scope)\n");
@@ -310,11 +300,10 @@ void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) {
MessageGenerator(file_->message_type(i))
.GenerateStaticVariableInitializers(printer);
}
-
for (int i = 0; i < file_->extension_count(); i++) {
// TODO(kenton): Reuse ExtensionGenerator objects?
ExtensionGenerator(file_->extension(i))
- .GenerateInitializationCode(printer);
+ .GenerateNonNestedInitializationCode(printer);
}
if (UsesExtensions(file_proto)) {
@@ -325,9 +314,11 @@ void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) {
" com.google.protobuf.ExtensionRegistry.newInstance();\n"
"registerAllExtensions(registry);\n");
for (int i = 0; i < file_->dependency_count(); i++) {
- printer->Print(
- "$dependency$.registerAllExtensions(registry);\n",
- "dependency", ClassName(file_->dependency(i)));
+ if (ShouldIncludeDependency(file_->dependency(i))) {
+ printer->Print(
+ "$dependency$.registerAllExtensions(registry);\n",
+ "dependency", ClassName(file_->dependency(i)));
+ }
}
printer->Print(
"return registry;\n");
@@ -372,13 +363,14 @@ template<typename GeneratorClass, typename DescriptorClass>
static void GenerateSibling(const string& package_dir,
const string& java_package,
const DescriptorClass* descriptor,
- OutputDirectory* output_directory,
- vector<string>* file_list) {
- string filename = package_dir + descriptor->name() + ".java";
+ GeneratorContext* context,
+ vector<string>* file_list,
+ const string& name_suffix,
+ void (GeneratorClass::*pfn)(io::Printer* printer)) {
+ string filename = package_dir + descriptor->name() + name_suffix + ".java";
file_list->push_back(filename);
- scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(filename));
+ scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
io::Printer printer(output.get(), '$');
printer.Print(
@@ -391,28 +383,36 @@ static void GenerateSibling(const string& package_dir,
"package", java_package);
}
- GeneratorClass(descriptor).Generate(&printer);
+ GeneratorClass generator(descriptor);
+ (generator.*pfn)(&printer);
}
void FileGenerator::GenerateSiblings(const string& package_dir,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
vector<string>* file_list) {
if (file_->options().java_multiple_files()) {
for (int i = 0; i < file_->enum_type_count(); i++) {
GenerateSibling<EnumGenerator>(package_dir, java_package_,
file_->enum_type(i),
- output_directory, file_list);
+ context, file_list, "",
+ &EnumGenerator::Generate);
}
for (int i = 0; i < file_->message_type_count(); i++) {
GenerateSibling<MessageGenerator>(package_dir, java_package_,
file_->message_type(i),
- output_directory, file_list);
+ context, file_list, "OrBuilder",
+ &MessageGenerator::GenerateInterface);
+ GenerateSibling<MessageGenerator>(package_dir, java_package_,
+ file_->message_type(i),
+ context, file_list, "",
+ &MessageGenerator::Generate);
}
if (HasGenericServices(file_)) {
for (int i = 0; i < file_->service_count(); i++) {
GenerateSibling<ServiceGenerator>(package_dir, java_package_,
file_->service(i),
- output_directory, file_list);
+ context, file_list, "",
+ &ServiceGenerator::Generate);
}
}
}
diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h
index 9e35d330..59911462 100644
--- a/src/google/protobuf/compiler/java/java_file.h
+++ b/src/google/protobuf/compiler/java/java_file.h
@@ -46,7 +46,7 @@ namespace protobuf {
class Printer; // printer.h
}
namespace compiler {
- class OutputDirectory; // code_generator.h
+ class GeneratorContext; // code_generator.h
}
}
@@ -70,12 +70,13 @@ class FileGenerator {
// files other than the outer file (i.e. one for each message, enum, and
// service type).
void GenerateSiblings(const string& package_dir,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
vector<string>* file_list);
const string& java_package() { return java_package_; }
const string& classname() { return classname_; }
+
private:
// Returns whether the dependency should be included in the output file.
// Always returns true for opensource, but used internally at Google to help
@@ -86,6 +87,7 @@ class FileGenerator {
string java_package_;
string classname_;
+
void GenerateEmbeddedDescriptor(io::Printer* printer);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc
index 745b55ae..e6c79abc 100644
--- a/src/google/protobuf/compiler/java/java_generator.cc
+++ b/src/google/protobuf/compiler/java/java_generator.cc
@@ -51,11 +51,8 @@ JavaGenerator::~JavaGenerator() {}
bool JavaGenerator::Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
- vector<pair<string, string> > options;
- ParseGeneratorParameter(parameter, &options);
-
// -----------------------------------------------------------------
// parse generator options
@@ -63,6 +60,10 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
// per line.
string output_list_file;
+
+ vector<pair<string, string> > options;
+ ParseGeneratorParameter(parameter, &options);
+
for (int i = 0; i < options.size(); i++) {
if (options[i].first == "output_list_file") {
output_list_file = options[i].second;
@@ -72,18 +73,23 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
}
}
-
// -----------------------------------------------------------------
+ if (file->options().optimize_for() == FileOptions::LITE_RUNTIME &&
+ file->options().java_generate_equals_and_hash()) {
+ *error = "The \"java_generate_equals_and_hash\" option is incompatible "
+ "with \"optimize_for = LITE_RUNTIME\". You must optimize for "
+ "SPEED or CODE_SIZE if you want to use this option.";
+ return false;
+ }
+
FileGenerator file_generator(file);
if (!file_generator.Validate(error)) {
return false;
}
- string package_dir =
- StringReplace(file_generator.java_package(), ".", "/", true);
- if (!package_dir.empty()) package_dir += "/";
+ string package_dir = JavaPackageToDir(file_generator.java_package());
vector<string> all_files;
@@ -94,19 +100,19 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
// Generate main java file.
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(java_filename));
+ context->Open(java_filename));
io::Printer printer(output.get(), '$');
file_generator.Generate(&printer);
// Generate sibling files.
- file_generator.GenerateSiblings(package_dir, output_directory, &all_files);
+ file_generator.GenerateSiblings(package_dir, context, &all_files);
// Generate output list if requested.
if (!output_list_file.empty()) {
// Generate output list. This is just a simple text file placed in a
// deterministic location which lists the .java files being generated.
scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
- output_directory->Open(output_list_file));
+ context->Open(output_list_file));
io::Printer srclist_printer(srclist_raw_output.get(), '$');
for (int i = 0; i < all_files.size(); i++) {
srclist_printer.Print("$filename$\n", "filename", all_files[i]);
diff --git a/src/google/protobuf/compiler/java/java_generator.h b/src/google/protobuf/compiler/java/java_generator.h
index c91c9053..888b8d85 100644
--- a/src/google/protobuf/compiler/java/java_generator.h
+++ b/src/google/protobuf/compiler/java/java_generator.h
@@ -57,7 +57,7 @@ class LIBPROTOC_EXPORT JavaGenerator : public CodeGenerator {
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const;
private:
diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc
index 7ed0c3cc..1b6f1653 100644
--- a/src/google/protobuf/compiler/java/java_helpers.cc
+++ b/src/google/protobuf/compiler/java/java_helpers.cc
@@ -134,16 +134,27 @@ string FileClassName(const FileDescriptor* file) {
}
string FileJavaPackage(const FileDescriptor* file) {
+ string result;
+
if (file->options().has_java_package()) {
- return file->options().java_package();
+ result = file->options().java_package();
} else {
- string result = kDefaultPackage;
+ result = kDefaultPackage;
if (!file->package().empty()) {
if (!result.empty()) result += '.';
result += file->package();
}
- return result;
}
+
+
+ return result;
+}
+
+string JavaPackageToDir(string package_name) {
+ string package_dir =
+ StringReplace(package_name, ".", "/", true);
+ if (!package_dir.empty()) package_dir += "/";
+ return package_dir;
}
string ToJavaName(const string& full_name, const FileDescriptor* file) {
@@ -335,6 +346,132 @@ string DefaultValue(const FieldDescriptor* field) {
return "";
}
+bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
+ // Switch on CppType since we need to know which default_value_* method
+ // of FieldDescriptor to call.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return field->default_value_int32() == 0;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return field->default_value_uint32() == 0;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return field->default_value_int64() == 0L;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return field->default_value_uint64() == 0L;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return field->default_value_double() == 0.0;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return field->default_value_float() == 0.0;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() == false;
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return false;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
+const char* bit_masks[] = {
+ "0x00000001",
+ "0x00000002",
+ "0x00000004",
+ "0x00000008",
+ "0x00000010",
+ "0x00000020",
+ "0x00000040",
+ "0x00000080",
+
+ "0x00000100",
+ "0x00000200",
+ "0x00000400",
+ "0x00000800",
+ "0x00001000",
+ "0x00002000",
+ "0x00004000",
+ "0x00008000",
+
+ "0x00010000",
+ "0x00020000",
+ "0x00040000",
+ "0x00080000",
+ "0x00100000",
+ "0x00200000",
+ "0x00400000",
+ "0x00800000",
+
+ "0x01000000",
+ "0x02000000",
+ "0x04000000",
+ "0x08000000",
+ "0x10000000",
+ "0x20000000",
+ "0x40000000",
+ "0x80000000",
+};
+
+string GetBitFieldName(int index) {
+ string varName = "bitField";
+ varName += SimpleItoa(index);
+ varName += "_";
+ return varName;
+}
+
+string GetBitFieldNameForBit(int bitIndex) {
+ return GetBitFieldName(bitIndex / 32);
+}
+
+string GenerateGetBit(int bitIndex) {
+ string varName = GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = "((" + varName + " & " + mask + ") == " + mask + ")";
+ return result;
+}
+
+string GenerateSetBit(int bitIndex) {
+ string varName = GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = varName + " |= " + mask;
+ return result;
+}
+
+string GenerateClearBit(int bitIndex) {
+ string varName = GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = varName + " = (" + varName + " & ~" + mask + ")";
+ return result;
+}
+
+string GenerateGetBitFromLocal(int bitIndex) {
+ string varName = "from_" + GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = "((" + varName + " & " + mask + ") == " + mask + ")";
+ return result;
+}
+
+string GenerateSetBitToLocal(int bitIndex) {
+ string varName = "to_" + GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = varName + " |= " + mask;
+ return result;
+}
+
} // 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 3c8974c9..4ae07f15 100644
--- a/src/google/protobuf/compiler/java/java_helpers.h
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -68,6 +68,9 @@ string FileClassName(const FileDescriptor* file);
// Returns the file's Java package name.
string FileJavaPackage(const FileDescriptor* file);
+// Returns output directory for the given package name.
+string JavaPackageToDir(string package_name);
+
// Converts the given fully-qualified name in the proto namespace to its
// fully-qualified name in the Java namespace, given that it is in the given
// file.
@@ -118,6 +121,7 @@ JavaType GetJavaType(const FieldDescriptor* field);
const char* BoxedPrimitiveTypeName(JavaType type);
string DefaultValue(const FieldDescriptor* field);
+bool IsDefaultValueJavaDefault(const FieldDescriptor* field);
// Does this message class keep track of unknown fields?
inline bool HasUnknownFields(const Descriptor* descriptor) {
@@ -132,6 +136,11 @@ inline bool HasGeneratedMethods(const Descriptor* descriptor) {
FileOptions::CODE_SIZE;
}
+// Does this message have specialized equals() and hashCode() methods?
+inline bool HasEqualsAndHashCode(const Descriptor* descriptor) {
+ return descriptor->file()->options().java_generate_equals_and_hash();
+}
+
// Does this message class have descriptor and reflection methods?
inline bool HasDescriptorMethods(const Descriptor* descriptor) {
return descriptor->file()->options().optimize_for() !=
@@ -146,6 +155,12 @@ inline bool HasDescriptorMethods(const FileDescriptor* descriptor) {
FileOptions::LITE_RUNTIME;
}
+inline bool HasNestedBuilders(const Descriptor* descriptor) {
+ // The proto-lite version doesn't support nested builders.
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
+}
+
// Should we generate generic services for this file?
inline bool HasGenericServices(const FileDescriptor *file) {
return file->service_count() > 0 &&
@@ -153,6 +168,43 @@ inline bool HasGenericServices(const FileDescriptor *file) {
file->options().java_generic_services();
}
+
+// Methods for shared bitfields.
+
+// Gets the name of the shared bitfield for the given index.
+string GetBitFieldName(int index);
+
+// Gets the name of the shared bitfield for the given bit index.
+// Effectively, GetBitFieldName(bitIndex / 32)
+string GetBitFieldNameForBit(int bitIndex);
+
+// Generates the java code for the expression that returns the boolean value
+// of the bit of the shared bitfields for the given bit index.
+// Example: "((bitField1_ & 0x04) == 0x04)"
+string GenerateGetBit(int bitIndex);
+
+// Generates the java code for the expression that sets the bit of the shared
+// bitfields for the given bit index.
+// Example: "bitField1_ = (bitField1_ | 0x04)"
+string GenerateSetBit(int bitIndex);
+
+// Generates the java code for the expression that clears the bit of the shared
+// bitfields for the given bit index.
+// Example: "bitField1_ = (bitField1_ & ~0x04)"
+string GenerateClearBit(int bitIndex);
+
+// Does the same as GenerateGetBit but operates on the bit field on a local
+// variable. This is used by the builder to copy the value in the builder to
+// the message.
+// Example: "((from_bitField1_ & 0x04) == 0x04)"
+string GenerateGetBitFromLocal(int bitIndex);
+
+// Does the same as GenerateSetBit but operates on the bit field on a local
+// variable. This is used by the builder to copy the value in the builder to
+// the message.
+// Example: "to_bitField1_ = (to_bitField1_ | 0x04)"
+string GenerateSetBitToLocal(int bitIndex);
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 8b91193f..47ee84cf 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -245,14 +245,54 @@ void MessageGenerator::GenerateStaticVariableInitializers(
MessageGenerator(descriptor_->nested_type(i))
.GenerateStaticVariableInitializers(printer);
}
+}
- for (int i = 0; i < descriptor_->extension_count(); i++) {
- // TODO(kenton): Reuse ExtensionGenerator objects?
- ExtensionGenerator(descriptor_->extension(i))
- .GenerateInitializationCode(printer);
+// ===================================================================
+
+void MessageGenerator::GenerateInterface(io::Printer* printer) {
+
+ if (descriptor_->extension_range_count() > 0) {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public interface $classname$OrBuilder extends\n"
+ " com.google.protobuf.GeneratedMessage.\n"
+ " ExtendableMessageOrBuilder<$classname$> {\n",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public interface $classname$OrBuilder extends \n"
+ " com.google.protobuf.GeneratedMessageLite.\n"
+ " ExtendableMessageOrBuilder<$classname$> {\n",
+ "classname", descriptor_->name());
+ }
+ } else {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public interface $classname$OrBuilder\n"
+ " extends com.google.protobuf.MessageOrBuilder {\n",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public interface $classname$OrBuilder\n"
+ " extends com.google.protobuf.MessageLiteOrBuilder {\n",
+ "classname", descriptor_->name());
+ }
}
+
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("\n");
+ PrintFieldComment(printer, descriptor_->field(i));
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInterfaceMembers(printer);
+ }
+ printer->Outdent();
+
+ printer->Print("}\n");
}
+// ===================================================================
+
void MessageGenerator::Generate(io::Printer* printer) {
bool is_own_file =
descriptor_->containing_type() == NULL &&
@@ -263,14 +303,14 @@ void MessageGenerator::Generate(io::Printer* printer) {
printer->Print(
"public $static$ final class $classname$ extends\n"
" com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
- " $classname$> {\n",
+ " $classname$> implements $classname$OrBuilder {\n",
"static", is_own_file ? "" : "static",
"classname", descriptor_->name());
} else {
printer->Print(
"public $static$ final class $classname$ extends\n"
" com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
- " $classname$> {\n",
+ " $classname$> implements $classname$OrBuilder {\n",
"static", is_own_file ? "" : "static",
"classname", descriptor_->name());
}
@@ -278,13 +318,15 @@ void MessageGenerator::Generate(io::Printer* printer) {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"public $static$ final class $classname$ extends\n"
- " com.google.protobuf.GeneratedMessage {\n",
+ " com.google.protobuf.GeneratedMessage\n"
+ " implements $classname$OrBuilder {\n",
"static", is_own_file ? "" : "static",
"classname", descriptor_->name());
} else {
printer->Print(
"public $static$ final class $classname$ extends\n"
- " com.google.protobuf.GeneratedMessageLite {\n",
+ " com.google.protobuf.GeneratedMessageLite\n"
+ " implements $classname$OrBuilder {\n",
"static", is_own_file ? "" : "static",
"classname", descriptor_->name());
}
@@ -292,8 +334,8 @@ void MessageGenerator::Generate(io::Printer* printer) {
printer->Indent();
printer->Print(
"// Use $classname$.newBuilder() to construct.\n"
- "private $classname$() {\n"
- " initFields();\n"
+ "private $classname$(Builder builder) {\n"
+ " super(builder);\n"
"}\n"
// Used when constructing the default instance, which cannot be initialized
// immediately because it may cyclically refer to other default instances.
@@ -310,33 +352,29 @@ void MessageGenerator::Generate(io::Printer* printer) {
"\n",
"classname", descriptor_->name());
- if (HasDescriptorMethods(descriptor_)) {
- printer->Print(
- "public static final com.google.protobuf.Descriptors.Descriptor\n"
- " getDescriptor() {\n"
- " return $fileclass$.internal_$identifier$_descriptor;\n"
- "}\n"
- "\n"
- "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
- " internalGetFieldAccessorTable() {\n"
- " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
- "}\n"
- "\n",
- "fileclass", ClassName(descriptor_->file()),
- "identifier", UniqueFileScopeIdentifier(descriptor_));
- }
+ GenerateDescriptorMethods(printer);
- // Nested types and extensions
+ // Nested types
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
EnumGenerator(descriptor_->enum_type(i)).Generate(printer);
}
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
- MessageGenerator(descriptor_->nested_type(i)).Generate(printer);
+ MessageGenerator messageGenerator(descriptor_->nested_type(i));
+ messageGenerator.GenerateInterface(printer);
+ messageGenerator.Generate(printer);
}
- for (int i = 0; i < descriptor_->extension_count(); i++) {
- ExtensionGenerator(descriptor_->extension(i)).Generate(printer);
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits += field_generators_.get(descriptor_->field(i))
+ .GetNumBitsForMessage();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
}
// Fields
@@ -361,35 +399,42 @@ void MessageGenerator::Generate(io::Printer* printer) {
printer->Print("}\n");
if (HasGeneratedMethods(descriptor_)) {
- GenerateIsInitialized(printer);
+ GenerateIsInitialized(printer, MEMOIZE);
GenerateMessageSerializationMethods(printer);
}
+ if (HasEqualsAndHashCode(descriptor_)) {
+ GenerateEqualsAndHashCode(printer);
+ }
+
GenerateParseFromMethods(printer);
GenerateBuilder(printer);
- // Force initialization of outer class. Otherwise, nested extensions may
- // not be initialized. Also carefully initialize the default instance in
- // such a way that it doesn't conflict with other initialization.
+ // Carefully initialize the default instance in such a way that it doesn't
+ // conflict with other initialization.
printer->Print(
"\n"
"static {\n"
" defaultInstance = new $classname$(true);\n"
- " $file$.internalForceInit();\n"
" defaultInstance.initFields();\n"
- "}\n",
- "file", ClassName(descriptor_->file()),
- "classname", descriptor_->name());
-
- printer->Print(
+ "}\n"
"\n"
"// @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "classname", descriptor_->name(),
"full_name", descriptor_->full_name());
+ // Extensions must be declared after the defaultInstance is initialized
+ // because the defaultInstance is used by the extension to lazily retrieve
+ // the outer class's FileDescriptor.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ ExtensionGenerator(descriptor_->extension(i)).Generate(printer);
+ }
+
printer->Outdent();
printer->Print("}\n\n");
}
+
// ===================================================================
void MessageGenerator::
@@ -502,6 +547,13 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
" return size;\n"
"}\n"
"\n");
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "protected Object writeReplace() throws java.io.ObjectStreamException {\n"
+ " return super.writeReplace();\n"
+ "}\n"
+ "\n");
}
void MessageGenerator::
@@ -605,42 +657,68 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) {
"\n",
"classname", ClassName(descriptor_));
+ if (HasNestedBuilders(descriptor_)) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "protected Builder newBuilderForType(\n"
+ " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
+ " Builder builder = new Builder(parent);\n"
+ " return builder;\n"
+ "}\n");
+ }
+
if (descriptor_->extension_range_count() > 0) {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"public static final class Builder extends\n"
" com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
- " $classname$, Builder> {\n",
+ " $classname$, Builder> implements $classname$OrBuilder {\n",
"classname", ClassName(descriptor_));
} else {
printer->Print(
"public static final class Builder extends\n"
" com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n"
- " $classname$, Builder> {\n",
+ " $classname$, Builder> implements $classname$OrBuilder {\n",
"classname", ClassName(descriptor_));
}
} else {
if (HasDescriptorMethods(descriptor_)) {
printer->Print(
"public static final class Builder extends\n"
- " com.google.protobuf.GeneratedMessage.Builder<Builder> {\n",
+ " com.google.protobuf.GeneratedMessage.Builder<Builder>\n"
+ " implements $classname$OrBuilder {\n",
"classname", ClassName(descriptor_));
} else {
printer->Print(
"public static final class Builder extends\n"
" com.google.protobuf.GeneratedMessageLite.Builder<\n"
- " $classname$, Builder> {\n",
+ " $classname$, Builder>\n"
+ " implements $classname$OrBuilder {\n",
"classname", ClassName(descriptor_));
}
}
printer->Indent();
+ GenerateDescriptorMethods(printer);
GenerateCommonBuilderMethods(printer);
if (HasGeneratedMethods(descriptor_)) {
+ GenerateIsInitialized(printer, DONT_MEMOIZE);
GenerateBuilderParsingMethods(printer);
}
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits += field_generators_.get(descriptor_->field(i))
+ .GetNumBitsForBuilder();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+
for (int i = 0; i < descriptor_->field_count(); i++) {
printer->Print("\n");
PrintFieldComment(printer, descriptor_->field(i));
@@ -657,36 +735,92 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) {
printer->Print("}\n");
}
+void MessageGenerator::GenerateDescriptorMethods(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public static final com.google.protobuf.Descriptors.Descriptor\n"
+ " getDescriptor() {\n"
+ " return $fileclass$.internal_$identifier$_descriptor;\n"
+ "}\n"
+ "\n"
+ "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ " internalGetFieldAccessorTable() {\n"
+ " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
+ "}\n"
+ "\n",
+ "fileclass", ClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_));
+ }
+}
+
// ===================================================================
void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
printer->Print(
- "private $classname$ result;\n"
- "\n"
"// Construct using $classname$.newBuilder()\n"
- "private Builder() {}\n"
- "\n"
- "private static Builder create() {\n"
- " Builder builder = new Builder();\n"
- " builder.result = new $classname$();\n"
- " return builder;\n"
+ "private Builder() {\n"
+ " maybeForceBuilderInitialization();\n"
"}\n"
- "\n"
- "protected $classname$ internalGetResult() {\n"
- " return result;\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "private Builder(BuilderParent parent) {\n"
+ " super(parent);\n"
+ " maybeForceBuilderInitialization();\n"
+ "}\n",
+ "classname", ClassName(descriptor_));
+ }
+
+
+ if (HasNestedBuilders(descriptor_)) {
+ printer->Print(
+ "private void maybeForceBuilderInitialization() {\n"
+ " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n");
+
+ printer->Indent();
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateFieldBuilderInitializationCode(printer);
+ }
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ "}\n");
+ } else {
+ printer->Print(
+ "private void maybeForceBuilderInitialization() {\n"
+ "}\n");
+ }
+
+ printer->Print(
+ "private static Builder create() {\n"
+ " return new Builder();\n"
"}\n"
"\n"
"public Builder clear() {\n"
- " if (result == null) {\n"
- " throw new IllegalStateException(\n"
- " \"Cannot call clear() after build().\");\n"
- " }\n"
- " result = new $classname$();\n"
+ " super.clear();\n",
+ "classname", ClassName(descriptor_));
+
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateBuilderClearCode(printer);
+ }
+
+ printer->Outdent();
+
+ printer->Print(
" return this;\n"
"}\n"
"\n"
"public Builder clone() {\n"
- " return create().mergeFrom(result);\n"
+ " return create().mergeFrom(buildPartial());\n"
"}\n"
"\n",
"classname", ClassName(descriptor_));
@@ -703,49 +837,78 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
"public $classname$ getDefaultInstanceForType() {\n"
" return $classname$.getDefaultInstance();\n"
"}\n"
- "\n"
- "public boolean isInitialized() {\n"
- " return result.isInitialized();\n"
- "}\n",
+ "\n",
"classname", ClassName(descriptor_));
// -----------------------------------------------------------------
printer->Print(
"public $classname$ build() {\n"
- // If result == null, we'll throw an appropriate exception later.
- " if (result != null && !isInitialized()) {\n"
+ " $classname$ result = buildPartial();\n"
+ " if (!result.isInitialized()) {\n"
" throw newUninitializedMessageException(result);\n"
" }\n"
- " return buildPartial();\n"
+ " return result;\n"
"}\n"
"\n"
"private $classname$ buildParsed()\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " if (!isInitialized()) {\n"
+ " $classname$ result = buildPartial();\n"
+ " if (!result.isInitialized()) {\n"
" throw newUninitializedMessageException(\n"
" result).asInvalidProtocolBufferException();\n"
" }\n"
- " return buildPartial();\n"
+ " return result;\n"
"}\n"
"\n"
"public $classname$ buildPartial() {\n"
- " if (result == null) {\n"
- " throw new IllegalStateException(\n"
- " \"build() has already been called on this Builder.\");\n"
- " }\n",
+ " $classname$ result = new $classname$(this);\n",
"classname", ClassName(descriptor_));
+
printer->Indent();
+ // Local vars for from and to bit fields to avoid accessing the builder and
+ // message over and over for these fields. Seems to provide a slight
+ // perforamance improvement in micro benchmark and this is also what proto1
+ // code does.
+ int totalBuilderBits = 0;
+ int totalMessageBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldGenerator& field = field_generators_.get(descriptor_->field(i));
+ totalBuilderBits += field.GetNumBitsForBuilder();
+ totalMessageBits += field.GetNumBitsForMessage();
+ }
+ int totalBuilderInts = (totalBuilderBits + 31) / 32;
+ int totalMessageInts = (totalMessageBits + 31) / 32;
+ for (int i = 0; i < totalBuilderInts; i++) {
+ printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+ for (int i = 0; i < totalMessageInts; i++) {
+ printer->Print("int to_$bit_field_name$ = 0;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+
+ // Output generation code for each field.
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
}
+ // Copy the bit field results to the generated message
+ for (int i = 0; i < totalMessageInts; i++) {
+ printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+
printer->Outdent();
+
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ " onBuilt();\n");
+ }
+
printer->Print(
- " $classname$ returnMe = result;\n"
- " result = null;\n"
- " return returnMe;\n"
+ " return result;\n"
"}\n"
"\n",
"classname", ClassName(descriptor_));
@@ -834,25 +997,31 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
printer->Print(
"case 0:\n" // zero signals EOF / limit reached
" this.setUnknownFields(unknownFields.build());\n"
+ " $on_changed$\n"
" return this;\n"
"default: {\n"
" if (!parseUnknownField(input, unknownFields,\n"
" extensionRegistry, tag)) {\n"
" this.setUnknownFields(unknownFields.build());\n"
+ " $on_changed$\n"
" return this;\n" // it's an endgroup tag
" }\n"
" break;\n"
- "}\n");
+ "}\n",
+ "on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : "");
} else {
printer->Print(
"case 0:\n" // zero signals EOF / limit reached
+ " $on_changed$\n"
" return this;\n"
"default: {\n"
" if (!parseUnknownField(input, extensionRegistry, tag)) {\n"
+ " $on_changed$\n"
" return this;\n" // it's an endgroup tag
" }\n"
" break;\n"
- "}\n");
+ "}\n",
+ "on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : "");
}
for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -898,16 +1067,33 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
" }\n" // switch (tag)
" }\n" // while (true)
"}\n"
+
"\n");
}
// ===================================================================
-void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
+void MessageGenerator::GenerateIsInitialized(
+ io::Printer* printer, UseMemoization useMemoization) {
+ bool memoization = useMemoization == MEMOIZE;
+ if (memoization) {
+ // Memoizes whether the protocol buffer is fully initialized (has all
+ // required fields). -1 means not yet computed. 0 means false and 1 means
+ // true.
+ printer->Print(
+ "private byte memoizedIsInitialized = -1;\n");
+ }
printer->Print(
"public final boolean isInitialized() {\n");
printer->Indent();
+ if (memoization) {
+ printer->Print(
+ "byte isInitialized = memoizedIsInitialized;\n"
+ "if (isInitialized != -1) return isInitialized == 1;\n"
+ "\n");
+ }
+
// Check that all required fields in this message are set.
// TODO(kenton): We can optimize this when we switch to putting all the
// "has" fields into a single bitfield.
@@ -916,8 +1102,12 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
if (field->is_required()) {
printer->Print(
- "if (!has$name$) return false;\n",
- "name", UnderscoresToCapitalizedCamelCase(field));
+ "if (!has$name$()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ "}\n",
+ "name", UnderscoresToCapitalizedCamelCase(field),
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
}
}
@@ -929,25 +1119,37 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
switch (field->label()) {
case FieldDescriptor::LABEL_REQUIRED:
printer->Print(
- "if (!get$name$().isInitialized()) return false;\n",
+ "if (!get$name$().isInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ "}\n",
"type", ClassName(field->message_type()),
- "name", UnderscoresToCapitalizedCamelCase(field));
+ "name", UnderscoresToCapitalizedCamelCase(field),
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
break;
case FieldDescriptor::LABEL_OPTIONAL:
printer->Print(
"if (has$name$()) {\n"
- " if (!get$name$().isInitialized()) return false;\n"
+ " if (!get$name$().isInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ " }\n"
"}\n",
"type", ClassName(field->message_type()),
- "name", UnderscoresToCapitalizedCamelCase(field));
+ "name", UnderscoresToCapitalizedCamelCase(field),
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print(
- "for ($type$ element : get$name$List()) {\n"
- " if (!element.isInitialized()) return false;\n"
+ "for (int i = 0; i < get$name$Count(); i++) {\n"
+ " if (!get$name$(i).isInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ " }\n"
"}\n",
"type", ClassName(field->message_type()),
- "name", UnderscoresToCapitalizedCamelCase(field));
+ "name", UnderscoresToCapitalizedCamelCase(field),
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
break;
}
}
@@ -955,10 +1157,20 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
printer->Print(
- "if (!extensionsAreInitialized()) return false;\n");
+ "if (!extensionsAreInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ "}\n",
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
}
printer->Outdent();
+
+ if (memoization) {
+ printer->Print(
+ " memoizedIsInitialized = 1;\n");
+ }
+
printer->Print(
" return true;\n"
"}\n"
@@ -967,6 +1179,94 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
// ===================================================================
+void MessageGenerator::GenerateEqualsAndHashCode(io::Printer* printer) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "public boolean equals(final Object obj) {\n");
+ printer->Indent();
+ printer->Print(
+ "if (obj == this) {\n"
+ " return true;\n"
+ "}\n"
+ "if (!(obj instanceof $classname$)) {\n"
+ " return super.equals(obj);\n"
+ "}\n"
+ "$classname$ other = ($classname$) obj;\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+
+ printer->Print("boolean result = true;\n");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (!field->is_repeated()) {
+ printer->Print(
+ "result = result && (has$name$() == other.has$name$());\n"
+ "if (has$name$()) {\n",
+ "name", UnderscoresToCapitalizedCamelCase(field));
+ printer->Indent();
+ }
+ field_generators_.get(field).GenerateEqualsCode(printer);
+ if (!field->is_repeated()) {
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+ }
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "result = result &&\n"
+ " getUnknownFields().equals(other.getUnknownFields());\n");
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "result = result &&\n"
+ " getExtensionFields().equals(other.getExtensionFields());\n");
+ }
+ }
+ printer->Print(
+ "return result;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "public int hashCode() {\n");
+ printer->Indent();
+ printer->Print(
+ "int hash = 41;\n"
+ "hash = (19 * hash) + getDescriptorForType().hashCode();\n");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (!field->is_repeated()) {
+ printer->Print(
+ "if (has$name$()) {\n",
+ "name", UnderscoresToCapitalizedCamelCase(field));
+ printer->Indent();
+ }
+ field_generators_.get(field).GenerateHashCode(printer);
+ if (!field->is_repeated()) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ }
+ if (HasDescriptorMethods(descriptor_)) {
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "hash = hashFields(hash, getExtensionFields());\n");
+ }
+ }
+ printer->Print(
+ "hash = (29 * hash) + getUnknownFields().hashCode();\n"
+ "return hash;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+}
+
+// ===================================================================
+
void MessageGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) {
for (int i = 0; i < descriptor_->extension_count(); i++) {
ExtensionGenerator(descriptor_->extension(i))
diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h
index 50ffae08..4c6fbbe5 100644
--- a/src/google/protobuf/compiler/java/java_message.h
+++ b/src/google/protobuf/compiler/java/java_message.h
@@ -67,11 +67,19 @@ class MessageGenerator {
// Generate the class itself.
void Generate(io::Printer* printer);
+ // Generates the base interface that both the class and its builder implement
+ void GenerateInterface(io::Printer* printer);
+
// Generate code to register all contained extensions with an
// ExtensionRegistry.
void GenerateExtensionRegistrationCode(io::Printer* printer);
private:
+ enum UseMemoization {
+ MEMOIZE,
+ DONT_MEMOIZE
+ };
+
void GenerateMessageSerializationMethods(io::Printer* printer);
void GenerateParseFromMethods(io::Printer* printer);
void GenerateSerializeOneField(io::Printer* printer,
@@ -81,8 +89,11 @@ class MessageGenerator {
void GenerateBuilder(io::Printer* printer);
void GenerateCommonBuilderMethods(io::Printer* printer);
+ void GenerateDescriptorMethods(io::Printer* printer);
void GenerateBuilderParsingMethods(io::Printer* printer);
- void GenerateIsInitialized(io::Printer* printer);
+ void GenerateIsInitialized(io::Printer* printer,
+ UseMemoization useMemoization);
+ void GenerateEqualsAndHashCode(io::Printer* printer);
const Descriptor* descriptor_;
FieldGeneratorMap field_generators_;
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc
index 71edc024..251945af 100644
--- a/src/google/protobuf/compiler/java/java_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -51,16 +51,43 @@ namespace {
// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
// repeat code between this and the other field types.
void SetMessageVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
map<string, string>* variables) {
(*variables)["name"] =
UnderscoresToCamelCase(descriptor);
(*variables)["capitalized_name"] =
UnderscoresToCapitalizedCamelCase(descriptor);
+ (*variables)["constant_name"] = FieldConstantName(descriptor);
(*variables)["number"] = SimpleItoa(descriptor->number());
(*variables)["type"] = ClassName(descriptor->message_type());
(*variables)["group_or_message"] =
(GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ?
"Group" : "Message";
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? "@java.lang.Deprecated " : "";
+ (*variables)["on_changed"] =
+ HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex);
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
}
} // namespace
@@ -68,68 +95,244 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
// ===================================================================
MessageFieldGenerator::
-MessageFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetMessageVariables(descriptor, &variables_);
+MessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
}
MessageFieldGenerator::~MessageFieldGenerator() {}
+int MessageFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int MessageFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void MessageFieldGenerator::
+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.
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n"
+ "$deprecation$$type$ get$capitalized_name$();\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
+ }
+}
+
void MessageFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private boolean has$capitalized_name$;\n"
"private $type$ $name$_;\n"
- "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
- "public $type$ get$capitalized_name$() { return $name$_; }\n");
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+ " return $name$_;\n"
+ "}\n");
+ }
+}
+
+void MessageFieldGenerator::PrintNestedBuilderCondition(
+ io::Printer* printer,
+ const char* regular_case,
+ const char* nested_builder_case) const {
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_, "if ($name$Builder_ == null) {\n");
+ printer->Indent();
+ printer->Print(variables_, regular_case);
+ printer->Outdent();
+ printer->Print("} else {\n");
+ printer->Indent();
+ printer->Print(variables_, nested_builder_case);
+ printer->Outdent();
+ printer->Print("}\n");
+ } else {
+ printer->Print(variables_, regular_case);
+ }
+}
+
+void MessageFieldGenerator::PrintNestedBuilderFunction(
+ io::Printer* printer,
+ const char* method_prototype,
+ const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const {
+ printer->Print(variables_, method_prototype);
+ printer->Print(" {\n");
+ printer->Indent();
+ PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
+ if (trailing_code != NULL) {
+ printer->Print(variables_, trailing_code);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
}
void MessageFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+
printer->Print(variables_,
- "public boolean has$capitalized_name$() {\n"
- " return result.has$capitalized_name$();\n"
- "}\n"
- "public $type$ get$capitalized_name$() {\n"
- " return result.get$capitalized_name$();\n"
- "}\n"
- "public Builder set$capitalized_name$($type$ value) {\n"
- " if (value == null) {\n"
- " throw new NullPointerException();\n"
- " }\n"
- " result.has$capitalized_name$ = true;\n"
- " result.$name$_ = value;\n"
- " return this;\n"
- "}\n"
- "public Builder set$capitalized_name$($type$.Builder builderForValue) {\n"
- " result.has$capitalized_name$ = true;\n"
- " result.$name$_ = builderForValue.build();\n"
- " return this;\n"
+ // Used when the builder is null.
+ "private $type$ $name$_ = $type$.getDefaultInstance();\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields are
+ // ignored.
+ "private com.google.protobuf.SingleFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
+ "\n");
+ }
+
+ // The comments above the methods below are based on a hypothetical
+ // field of type "Field" called "Field".
+
+ // boolean hasField()
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+
+ // Field getField()
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public $type$ get$capitalized_name$()",
+
+ "return $name$_;\n",
+
+ "return $name$Builder_.getMessage();\n",
+
+ NULL);
+
+ // Field.Builder setField(Field value)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
"}\n"
- "public Builder merge$capitalized_name$($type$ value) {\n"
- " if (result.has$capitalized_name$() &&\n"
- " result.$name$_ != $type$.getDefaultInstance()) {\n"
- " result.$name$_ =\n"
- " $type$.newBuilder(result.$name$_).mergeFrom(value).buildPartial();\n"
- " } else {\n"
- " result.$name$_ = value;\n"
- " }\n"
- " result.has$capitalized_name$ = true;\n"
- " return this;\n"
+ "$name$_ = value;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(value);\n",
+
+ "$set_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ // Field.Builder setField(Field.Builder builderForValue)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " $type$.Builder builderForValue)",
+
+ "$name$_ = builderForValue.build();\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(builderForValue.build());\n",
+
+ "$set_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ // Field.Builder mergeField(Field value)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder merge$capitalized_name$($type$ value)",
+
+ "if ($get_has_field_bit_builder$ &&\n"
+ " $name$_ != $type$.getDefaultInstance()) {\n"
+ " $name$_ =\n"
+ " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
+ "} else {\n"
+ " $name$_ = value;\n"
"}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.has$capitalized_name$ = false;\n"
- " result.$name$_ = $type$.getDefaultInstance();\n"
- " return this;\n"
- "}\n");
+ "$on_changed$\n",
+
+ "$name$Builder_.mergeFrom(value);\n",
+
+ "$set_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ // Field.Builder clearField()
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder clear$capitalized_name$()",
+
+ "$name$_ = $type$.getDefaultInstance();\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.clear();\n",
+
+ "$clear_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "$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"
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+ " if ($name$Builder_ != null) {\n"
+ " return $name$Builder_.getMessageOrBuilder();\n"
+ " } else {\n"
+ " return $name$_;\n"
+ " }\n"
+ "}\n"
+ "private com.google.protobuf.SingleFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> \n"
+ " get$capitalized_name$FieldBuilder() {\n"
+ " if ($name$Builder_ == null) {\n"
+ " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " $name$_,\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $name$_ = null;\n"
+ " }\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ }
}
void MessageFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "get$capitalized_name$FieldBuilder();\n");
+}
+
+
+void MessageFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n");
}
void MessageFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ PrintNestedBuilderCondition(printer,
+ "$name$_ = $type$.getDefaultInstance();\n",
+
+ "$name$Builder_.clear();\n");
+ printer->Print(variables_, "$clear_has_field_bit_builder$;\n");
+}
+
+void MessageFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
printer->Print(variables_,
"if (other.has$capitalized_name$()) {\n"
@@ -139,7 +342,16 @@ GenerateMergingCode(io::Printer* printer) const {
void MessageFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
- // Nothing to do for singular fields.
+
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+
+ PrintNestedBuilderCondition(printer,
+ "result.$name$_ = $name$_;\n",
+
+ "result.$name$_ = $name$Builder_.build();\n");
}
void MessageFieldGenerator::
@@ -165,20 +377,34 @@ GenerateParsingCode(io::Printer* printer) const {
void MessageFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
- " output.write$group_or_message$($number$, get$capitalized_name$());\n"
+ "if ($get_has_field_bit_message$) {\n"
+ " output.write$group_or_message$($number$, $name$_);\n"
"}\n");
}
void MessageFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
+ "if ($get_has_field_bit_message$) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
+ " .compute$group_or_message$Size($number$, $name$_);\n"
"}\n");
}
+void MessageFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$());\n");
+}
+
+void MessageFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n"
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+}
+
string MessageFieldGenerator::GetBoxedType() const {
return ClassName(descriptor_->message_type());
}
@@ -186,109 +412,416 @@ string MessageFieldGenerator::GetBoxedType() const {
// ===================================================================
RepeatedMessageFieldGenerator::
-RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetMessageVariables(descriptor, &variables_);
+RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
}
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+int RepeatedMessageFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedMessageFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ // TODO(jonp): In the future, consider having methods 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.
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$type$> \n"
+ " get$capitalized_name$List();\n"
+ "$deprecation$$type$ get$capitalized_name$(int index);\n"
+ "$deprecation$int get$capitalized_name$Count();\n");
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
+ " get$capitalized_name$OrBuilderList();\n"
+ "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index);\n");
+ }
+}
+
void RepeatedMessageFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private java.util.List<$type$> $name$_ =\n"
- " java.util.Collections.emptyList();\n"
- "public java.util.List<$type$> get$capitalized_name$List() {\n"
+ "private java.util.List<$type$> $name$_;\n"
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
"}\n"
- "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
- "public $type$ get$capitalized_name$(int index) {\n"
+ "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+ " get$capitalized_name$OrBuilderList() {\n"
+ " return $name$_;\n"
+ "}\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n"
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index) {\n"
" return $name$_.get(index);\n"
"}\n");
+
+}
+
+void RepeatedMessageFieldGenerator::PrintNestedBuilderCondition(
+ io::Printer* printer,
+ const char* regular_case,
+ const char* nested_builder_case) const {
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_, "if ($name$Builder_ == null) {\n");
+ printer->Indent();
+ printer->Print(variables_, regular_case);
+ printer->Outdent();
+ printer->Print("} else {\n");
+ printer->Indent();
+ printer->Print(variables_, nested_builder_case);
+ printer->Outdent();
+ printer->Print("}\n");
+ } else {
+ printer->Print(variables_, regular_case);
+ }
+}
+
+void RepeatedMessageFieldGenerator::PrintNestedBuilderFunction(
+ io::Printer* printer,
+ const char* method_prototype,
+ const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const {
+ printer->Print(variables_, method_prototype);
+ printer->Print(" {\n");
+ printer->Indent();
+ PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
+ if (trailing_code != NULL) {
+ printer->Print(variables_, trailing_code);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
}
void RepeatedMessageFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+
printer->Print(variables_,
- // Note: We return an unmodifiable list because otherwise the caller
- // 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.
- "public java.util.List<$type$> get$capitalized_name$List() {\n"
- " return java.util.Collections.unmodifiableList(result.$name$_);\n"
- "}\n"
- "public int get$capitalized_name$Count() {\n"
- " return result.get$capitalized_name$Count();\n"
- "}\n"
- "public $type$ get$capitalized_name$(int index) {\n"
- " return result.get$capitalized_name$(index);\n"
- "}\n"
- "public Builder set$capitalized_name$(int index, $type$ value) {\n"
- " if (value == null) {\n"
- " throw new NullPointerException();\n"
- " }\n"
- " result.$name$_.set(index, value);\n"
- " return this;\n"
- "}\n"
- "public Builder set$capitalized_name$(int index, "
- "$type$.Builder builderForValue) {\n"
- " result.$name$_.set(index, builderForValue.build());\n"
- " return this;\n"
+ // Used when the builder is null.
+ // One field is the list and the other field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ "private java.util.List<$type$> $name$_ =\n"
+ " java.util.Collections.emptyList();\n"
+
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
"}\n"
- "public Builder add$capitalized_name$($type$ value) {\n"
- " if (value == null) {\n"
- " throw new NullPointerException();\n"
- " }\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
- " }\n"
- " result.$name$_.add(value);\n"
- " return this;\n"
+ "\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields are
+ // ignored.
+ "private com.google.protobuf.RepeatedFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
+ "\n");
+ }
+
+ // The comments above the methods below are based on a hypothetical
+ // repeated field of type "Field" called "RepeatedField".
+
+ // List<Field> getRepeatedFieldList()
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List()",
+
+ "return java.util.Collections.unmodifiableList($name$_);\n",
+ "return $name$Builder_.getMessageList();\n",
+
+ NULL);
+
+ // int getRepeatedFieldCount()
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public int get$capitalized_name$Count()",
+
+ "return $name$_.size();\n",
+ "return $name$Builder_.getCount();\n",
+
+ NULL);
+
+ // Field getRepeatedField(int index)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public $type$ get$capitalized_name$(int index)",
+
+ "return $name$_.get(index);\n",
+
+ "return $name$Builder_.getMessage(index);\n",
+
+ NULL);
+
+ // Builder setRepeatedField(int index, Field value)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$ value)",
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
"}\n"
- "public Builder add$capitalized_name$($type$.Builder builderForValue) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
- " }\n"
- " result.$name$_.add(builderForValue.build());\n"
- " return this;\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.set(index, value);\n"
+ "$on_changed$\n",
+ "$name$Builder_.setMessage(index, value);\n",
+ "return this;\n");
+
+ // Builder setRepeatedField(int index, Field.Builder builderForValue)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.set(index, builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(index, builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(Field value)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
"}\n"
- "public Builder addAll$capitalized_name$(\n"
- " java.lang.Iterable<? extends $type$> values) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
- " }\n"
- " super.addAll(values, result.$name$_);\n"
- " return this;\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(value);\n"
+
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(value);\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(int index, Field value)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " int index, $type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
"}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.$name$_ = java.util.Collections.emptyList();\n"
- " return this;\n"
- "}\n");
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(index, value);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(index, value);\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(Field.Builder builderForValue)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(int index, Field.Builder builderForValue)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " int index, $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(index, builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(index, builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addAllRepeatedField(Iterable<Field> values)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
+ " java.lang.Iterable<? extends $type$> values)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "super.addAll(values, $name$_);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addAllMessages(values);\n",
+
+ "return this;\n");
+
+ // Builder clearAllRepeatedField()
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder clear$capitalized_name$()",
+
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.clear();\n",
+
+ "return this;\n");
+
+ // Builder removeRepeatedField(int index)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder remove$capitalized_name$(int index)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.remove(index);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.remove(index);\n",
+
+ "return this;\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n"
+ " int index) {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
+ "}\n"
+
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index) {\n"
+ " if ($name$Builder_ == null) {\n"
+ " return $name$_.get(index);"
+ " } else {\n"
+ " return $name$Builder_.getMessageOrBuilder(index);\n"
+ " }\n"
+ "}\n"
+
+ "$deprecation$public java.util.List<? extends $type$OrBuilder> \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"
+
+ "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n"
+ " return get$capitalized_name$FieldBuilder().addBuilder(\n"
+ " $type$.getDefaultInstance());\n"
+ "}\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"
+ "$deprecation$public java.util.List<$type$.Builder> \n"
+ " get$capitalized_name$BuilderList() {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilderList();\n"
+ "}\n"
+ "private com.google.protobuf.RepeatedFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> \n"
+ " get$capitalized_name$FieldBuilder() {\n"
+ " if ($name$Builder_ == null) {\n"
+ " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " $name$_,\n"
+ " $get_mutable_bit_builder$,\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $name$_ = null;\n"
+ " }\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "get$capitalized_name$FieldBuilder();\n");
}
void RepeatedMessageFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- // Initialized inline.
+ printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ PrintNestedBuilderCondition(printer,
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n",
+
+ "$name$Builder_.clear();\n");
}
void RepeatedMessageFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
- printer->Print(variables_,
+ // The code below does two optimizations (non-nested builder case):
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
+ PrintNestedBuilderCondition(printer,
"if (!other.$name$_.isEmpty()) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$type$>();\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n",
+
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$Builder_.isEmpty()) {\n"
+ " $name$Builder_.dispose();\n"
+ " $name$Builder_ = null;\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $name$Builder_ = \n"
+ " com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?\n"
+ " get$capitalized_name$FieldBuilder() : null;\n"
+ " } else {\n"
+ " $name$Builder_.addAllMessages(other.$name$_);\n"
" }\n"
- " result.$name$_.addAll(other.$name$_);\n"
"}\n");
}
void RepeatedMessageFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
- printer->Print(variables_,
- "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
- " result.$name$_ =\n"
- " java.util.Collections.unmodifiableList(result.$name$_);\n"
- "}\n");
+ // The code below (non-nested builder case) ensures that the result has an
+ // immutable list. If our list is immutable, we can just reuse it. If not,
+ // we make it immutable.
+ PrintNestedBuilderCondition(printer,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n",
+
+ "result.$name$_ = $name$Builder_.build();\n");
}
void RepeatedMessageFieldGenerator::
@@ -311,17 +844,33 @@ GenerateParsingCode(io::Printer* printer) const {
void RepeatedMessageFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.write$group_or_message$($number$, element);\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$group_or_message$($number$, $name$_.get(i));\n"
"}\n");
}
void RepeatedMessageFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .compute$group_or_message$Size($number$, element);\n"
+ " .compute$group_or_message$Size($number$, $name$_.get(i));\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
"}\n");
}
diff --git a/src/google/protobuf/compiler/java/java_message_field.h b/src/google/protobuf/compiler/java/java_message_field.h
index 66bdd884..2efbcd97 100644
--- a/src/google/protobuf/compiler/java/java_message_field.h
+++ b/src/google/protobuf/compiler/java/java_message_field.h
@@ -46,50 +46,84 @@ namespace java {
class MessageFieldGenerator : public FieldGenerator {
public:
- explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
+ explicit MessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
~MessageFieldGenerator();
// implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
private:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
+
+ void PrintNestedBuilderCondition(io::Printer* printer,
+ const char* regular_case, const char* nested_builder_case) const;
+ void PrintNestedBuilderFunction(io::Printer* printer,
+ const char* method_prototype, const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const;
};
class RepeatedMessageFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
+ explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
~RepeatedMessageFieldGenerator();
// implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
private:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
+
+ void PrintNestedBuilderCondition(io::Printer* printer,
+ const char* regular_case, const char* nested_builder_case) const;
+ void PrintNestedBuilderFunction(io::Printer* printer,
+ const char* method_prototype, const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const;
};
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/src/google/protobuf/compiler/java/java_plugin_unittest.cc
index cfe01885..ccc94c9d 100644
--- a/src/google/protobuf/compiler/java/java_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/java/java_plugin_unittest.cc
@@ -56,21 +56,22 @@ class TestGenerator : public CodeGenerator {
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
- TryInsert("Test.java", "outer_class_scope", output_directory);
- TryInsert("Test.java", "class_scope:foo.Bar", output_directory);
- TryInsert("Test.java", "class_scope:foo.Bar.Baz", output_directory);
- TryInsert("Test.java", "builder_scope:foo.Bar", output_directory);
- TryInsert("Test.java", "builder_scope:foo.Bar.Baz", output_directory);
- TryInsert("Test.java", "enum_scope:foo.Qux", output_directory);
+ string filename = "Test.java";
+ TryInsert(filename, "outer_class_scope", context);
+ TryInsert(filename, "class_scope:foo.Bar", context);
+ TryInsert(filename, "class_scope:foo.Bar.Baz", context);
+ TryInsert(filename, "builder_scope:foo.Bar", context);
+ TryInsert(filename, "builder_scope:foo.Bar.Baz", context);
+ TryInsert(filename, "enum_scope:foo.Qux", context);
return true;
}
void TryInsert(const string& filename, const string& insertion_point,
- OutputDirectory* output_directory) const {
+ GeneratorContext* context) const {
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->OpenForInsert(filename, insertion_point));
+ context->OpenForInsert(filename, insertion_point));
io::Printer printer(output.get(), '$');
printer.Print("// inserted $name$\n", "name", insertion_point);
}
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index f6179bfa..addb8819 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -154,15 +154,24 @@ int FixedSize(FieldDescriptor::Type type) {
}
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
map<string, string>* variables) {
(*variables)["name"] =
UnderscoresToCamelCase(descriptor);
(*variables)["capitalized_name"] =
UnderscoresToCapitalizedCamelCase(descriptor);
+ (*variables)["constant_name"] = FieldConstantName(descriptor);
(*variables)["number"] = SimpleItoa(descriptor->number());
(*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
(*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
+ (*variables)["field_type"] = (*variables)["type"];
+ (*variables)["field_list_type"] = "java.util.List<" +
+ (*variables)["boxed_type"] + ">";
+ (*variables)["empty_list"] = "java.util.Collections.emptyList();";
(*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ?
+ "" : ("= " + DefaultValue(descriptor));
(*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
(*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
(*variables)["tag_size"] = SimpleItoa(
@@ -175,67 +184,135 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
} else {
(*variables)["null_check"] = "";
}
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? "@java.lang.Deprecated " : "";
int fixed_size = FixedSize(GetType(descriptor));
if (fixed_size != -1) {
(*variables)["fixed_size"] = SimpleItoa(fixed_size);
}
+ (*variables)["on_changed"] =
+ HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex);
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
}
+
} // namespace
// ===================================================================
PrimitiveFieldGenerator::
-PrimitiveFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetPrimitiveVariables(descriptor, &variables_);
+PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
}
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+int PrimitiveFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int PrimitiveFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void PrimitiveFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n"
+ "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
void PrimitiveFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private boolean has$capitalized_name$;\n"
- "private $type$ $name$_ = $default$;\n"
- "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
- "public $type$ get$capitalized_name$() { return $name$_; }\n");
+ "private $field_type$ $name$_;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
}
void PrimitiveFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
- "public boolean has$capitalized_name$() {\n"
- " return result.has$capitalized_name$();\n"
- "}\n"
- "public $type$ get$capitalized_name$() {\n"
- " return result.get$capitalized_name$();\n"
- "}\n"
- "public Builder set$capitalized_name$($type$ value) {\n"
+ "private $field_type$ $name$_ $default_init$;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
"$null_check$"
- " result.has$capitalized_name$ = true;\n"
- " result.$name$_ = value;\n"
+ " $set_has_field_bit_builder$;\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
" return this;\n"
"}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.has$capitalized_name$ = false;\n");
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_builder$;\n");
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
// it multiple times. Instead, get the default out of the default instance.
printer->Print(variables_,
- " result.$name$_ = getDefaultInstance().get$capitalized_name$();\n");
+ " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
} else {
printer->Print(variables_,
- " result.$name$_ = $default$;\n");
+ " $name$_ = $default$;\n");
}
printer->Print(variables_,
+ " $on_changed$\n"
" return this;\n"
"}\n");
}
void PrimitiveFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void PrimitiveFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- // Initialized inline.
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$;\n");
}
void PrimitiveFieldGenerator::
@@ -248,32 +325,121 @@ GenerateMergingCode(io::Printer* printer) const {
void PrimitiveFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
- // Nothing to do here for primitive types.
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
}
void PrimitiveFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
- "set$capitalized_name$(input.read$capitalized_type$());\n");
+ "$set_has_field_bit_builder$;\n"
+ "$name$_ = input.read$capitalized_type$();\n");
}
void PrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
- " output.write$capitalized_type$($number$, get$capitalized_name$());\n"
+ "if ($get_has_field_bit_message$) {\n"
+ " output.write$capitalized_type$($number$, $name$_);\n"
"}\n");
}
void PrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (has$capitalized_name$()) {\n"
+ "if ($get_has_field_bit_message$) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .compute$capitalized_type$Size($number$, get$capitalized_name$());\n"
+ " .compute$capitalized_type$Size($number$, $name$_);\n"
"}\n");
}
+void PrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ switch (GetJavaType(descriptor_)) {
+ case JAVATYPE_INT:
+ case JAVATYPE_LONG:
+ case JAVATYPE_BOOLEAN:
+ printer->Print(variables_,
+ "result = result && (get$capitalized_name$()\n"
+ " == other.get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_FLOAT:
+ printer->Print(variables_,
+ "result = result && (Float.floatToIntBits(get$capitalized_name$())"
+ " == Float.floatToIntBits(other.get$capitalized_name$()));\n");
+ break;
+
+ case JAVATYPE_DOUBLE:
+ printer->Print(variables_,
+ "result = result && (Double.doubleToLongBits(get$capitalized_name$())"
+ " == Double.doubleToLongBits(other.get$capitalized_name$()));\n");
+ break;
+
+ case JAVATYPE_STRING:
+ case JAVATYPE_BYTES:
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_ENUM:
+ case JAVATYPE_MESSAGE:
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+}
+
+void PrimitiveFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n");
+ switch (GetJavaType(descriptor_)) {
+ case JAVATYPE_INT:
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$();\n");
+ break;
+
+ case JAVATYPE_LONG:
+ printer->Print(variables_,
+ "hash = (53 * hash) + hashLong(get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_BOOLEAN:
+ printer->Print(variables_,
+ "hash = (53 * hash) + hashBoolean(get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_FLOAT:
+ printer->Print(variables_,
+ "hash = (53 * hash) + Float.floatToIntBits(\n"
+ " get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_DOUBLE:
+ printer->Print(variables_,
+ "hash = (53 * hash) + hashLong(\n"
+ " Double.doubleToLongBits(get$capitalized_name$()));\n");
+ break;
+
+ case JAVATYPE_STRING:
+ case JAVATYPE_BYTES:
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+ break;
+
+ case JAVATYPE_ENUM:
+ case JAVATYPE_MESSAGE:
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+}
+
string PrimitiveFieldGenerator::GetBoxedType() const {
return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
}
@@ -281,23 +447,46 @@ string PrimitiveFieldGenerator::GetBoxedType() const {
// ===================================================================
RepeatedPrimitiveFieldGenerator::
-RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor)
- : descriptor_(descriptor) {
- SetPrimitiveVariables(descriptor, &variables_);
+RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
}
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+int RepeatedPrimitiveFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedPrimitiveFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n"
+ "$deprecation$int get$capitalized_name$Count();\n"
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+}
+
+
void RepeatedPrimitiveFieldGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private java.util.List<$boxed_type$> $name$_ =\n"
- " java.util.Collections.emptyList();\n"
- "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n"
+ "private $field_list_type$ $name$_;\n"
+ "$deprecation$public java.util.List<$boxed_type$>\n"
+ " get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
"}\n"
- "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
- "public $type$ get$capitalized_name$(int index) {\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
" return $name$_.get(index);\n"
"}\n");
@@ -310,76 +499,125 @@ GenerateMembers(io::Printer* printer) const {
void RepeatedPrimitiveFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
+ // One field is the list and the bit field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ printer->Print(variables_,
+ "private $field_list_type$ $name$_ = $empty_list$;\n");
+
printer->Print(variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<$boxed_type$>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n");
+
// Note: We return an unmodifiable list because otherwise the caller
// 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.
- "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n"
- " return java.util.Collections.unmodifiableList(result.$name$_);\n"
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<$boxed_type$>\n"
+ " get$capitalized_name$List() {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
"}\n"
- "public int get$capitalized_name$Count() {\n"
- " return result.get$capitalized_name$Count();\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
"}\n"
- "public $type$ get$capitalized_name$(int index) {\n"
- " return result.get$capitalized_name$(index);\n"
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
"}\n"
- "public Builder set$capitalized_name$(int index, $type$ value) {\n"
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$ value) {\n"
"$null_check$"
- " result.$name$_.set(index, value);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
" return this;\n"
"}\n"
- "public Builder add$capitalized_name$($type$ value) {\n"
+ "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
"$null_check$"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
- " }\n"
- " result.$name$_.add(value);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
" return this;\n"
"}\n"
- "public Builder addAll$capitalized_name$(\n"
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
" java.lang.Iterable<? extends $boxed_type$> values) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
- " }\n"
- " super.addAll(values, result.$name$_);\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " super.addAll(values, $name$_);\n"
+ " $on_changed$\n"
" return this;\n"
"}\n"
- "public Builder clear$capitalized_name$() {\n"
- " result.$name$_ = java.util.Collections.emptyList();\n"
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $name$_ = $empty_list$;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $on_changed$\n"
" return this;\n"
"}\n");
}
void RepeatedPrimitiveFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void RepeatedPrimitiveFieldGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- // Initialized inline.
+ printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $empty_list$;\n"
+ "$clear_mutable_bit_builder$;\n");
}
void RepeatedPrimitiveFieldGenerator::
GenerateMergingCode(io::Printer* printer) const {
+ // The code below does two optimizations:
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
printer->Print(variables_,
"if (!other.$name$_.isEmpty()) {\n"
- " if (result.$name$_.isEmpty()) {\n"
- " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
" }\n"
- " result.$name$_.addAll(other.$name$_);\n"
+ " $on_changed$\n"
"}\n");
}
void RepeatedPrimitiveFieldGenerator::
GenerateBuildingCode(io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
printer->Print(variables_,
- "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n"
- " result.$name$_ =\n"
- " java.util.Collections.unmodifiableList(result.$name$_);\n"
- "}\n");
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
}
void RepeatedPrimitiveFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
- "add$capitalized_name$(input.read$capitalized_type$());\n");
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(input.read$capitalized_type$());\n");
}
void RepeatedPrimitiveFieldGenerator::
@@ -401,13 +639,13 @@ GenerateSerializationCode(io::Printer* printer) const {
" output.writeRawVarint32($tag$);\n"
" output.writeRawVarint32($name$MemoizedSerializedSize);\n"
"}\n"
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.write$capitalized_type$NoTag(element);\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$capitalized_type$NoTag($name$_.get(i));\n"
"}\n");
} else {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
- " output.write$capitalized_type$($number$, element);\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$capitalized_type$($number$, $name$_.get(i));\n"
"}\n");
}
}
@@ -421,9 +659,9 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
if (FixedSize(GetType(descriptor_)) == -1) {
printer->Print(variables_,
- "for ($type$ element : get$capitalized_name$List()) {\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
" dataSize += com.google.protobuf.CodedOutputStream\n"
- " .compute$capitalized_type$SizeNoTag(element);\n"
+ " .compute$capitalized_type$SizeNoTag($name$_.get(i));\n"
"}\n");
} else {
printer->Print(variables_,
@@ -455,6 +693,22 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print("}\n");
}
+void RepeatedPrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+ "}\n");
+}
+
string RepeatedPrimitiveFieldGenerator::GetBoxedType() const {
return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
}
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.h b/src/google/protobuf/compiler/java/java_primitive_field.h
index 4e482a05..7900fac5 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.h
+++ b/src/google/protobuf/compiler/java/java_primitive_field.h
@@ -46,49 +46,69 @@ namespace java {
class PrimitiveFieldGenerator : public FieldGenerator {
public:
- explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+ explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
~PrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
private:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
};
class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+ explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
~RepeatedPrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingCodeFromPacked(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
string GetBoxedType() const;
private:
const FieldDescriptor* descriptor_;
map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
};
diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc
index 5545bf7f..1ae4f461 100644
--- a/src/google/protobuf/compiler/java/java_service.cc
+++ b/src/google/protobuf/compiler/java/java_service.cc
@@ -118,7 +118,7 @@ void ServiceGenerator::GenerateNewReflectiveServiceMethod(
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor* method = descriptor_->method(i);
- printer->Print("@Override\n");
+ printer->Print("@java.lang.Override\n");
GenerateMethodSignature(printer, method, IS_CONCRETE);
printer->Print(
" {\n"
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
new file mode 100644
index 00000000..a93ff434
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -0,0 +1,605 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Author: jonp@google.com (Jon Perlow)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_string_field.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ map<string, string>* variables) {
+ (*variables)["name"] =
+ UnderscoresToCamelCase(descriptor);
+ (*variables)["capitalized_name"] =
+ UnderscoresToCapitalizedCamelCase(descriptor);
+ (*variables)["constant_name"] = FieldConstantName(descriptor);
+ (*variables)["number"] = SimpleItoa(descriptor->number());
+ (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY";
+
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["default_init"] = ("= " + DefaultValue(descriptor));
+ (*variables)["capitalized_type"] = "String";
+ (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
+ (*variables)["tag_size"] = SimpleItoa(
+ WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ (*variables)["null_check"] =
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n";
+
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? "@java.lang.Deprecated " : "";
+ (*variables)["on_changed"] =
+ HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex);
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+} // namespace
+
+// ===================================================================
+
+StringFieldGenerator::
+StringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
+}
+
+StringFieldGenerator::~StringFieldGenerator() {}
+
+int StringFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int StringFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+// A note about how strings are handled. This code used to just store a String
+// in the Message. This had two issues:
+//
+// 1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded
+// strings, but rather fields that were raw bytes incorrectly marked
+// as strings in the proto file. This is common because in the proto1
+// syntax, string was the way to indicate bytes and C++ engineers can
+// easily make this mistake without affecting the C++ API. By converting to
+// strings immediately, some java code might corrupt these byte arrays as
+// it passes through a java server even if the field was never accessed by
+// application code.
+//
+// 2. There's a performance hit to converting between bytes and strings and
+// it many cases, the field is never even read by the application code. This
+// avoids unnecessary conversions in the common use cases.
+//
+// So now, the field for String is maintained as an Object reference which can
+// either store a String or a ByteString. The code uses an instanceof check
+// to see which one it has and converts to the other one if needed. It remembers
+// the last value requested (in a thread safe manner) as this is most likely
+// the one needed next. The thread safety is such that if two threads both
+// convert the field because the changes made by each thread were not visible to
+// the other, they may cause a conversion to happen more times than would
+// otherwise be necessary. This was deemed better than adding synchronization
+// overhead. It will not cause any corruption issues or affect the behavior of
+// the API. The instanceof check is also highly optimized in the JVM and we
+// decided it was better to reduce the memory overhead by not having two
+// separate fields but rather use dynamic type checking.
+//
+// For single fields, the logic for this is done inside the generated code. For
+// repeated fields, the logic is done in LazyStringArrayList and
+// UnmodifiableLazyStringList.
+void StringFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n"
+ "$deprecation$String get$capitalized_name$();\n");
+}
+
+void StringFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private Object $name$_;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public String get$capitalized_name$() {\n"
+ " Object ref = $name$_;\n"
+ " if (ref instanceof String) {\n"
+ " return (String) ref;\n"
+ " } else {\n"
+ " com.google.protobuf.ByteString bs = \n"
+ " (com.google.protobuf.ByteString) ref;\n"
+ " String s = bs.toStringUtf8();\n"
+ " if (com.google.protobuf.Internal.isValidUtf8(bs)) {\n"
+ " $name$_ = s;\n"
+ " }\n"
+ " return s;\n"
+ " }\n"
+ "}\n"
+ "private com.google.protobuf.ByteString get$capitalized_name$Bytes() {\n"
+ " Object ref = $name$_;\n"
+ " if (ref instanceof String) {\n"
+ " com.google.protobuf.ByteString b = \n"
+ " com.google.protobuf.ByteString.copyFromUtf8((String) ref);\n"
+ " $name$_ = b;\n"
+ " return b;\n"
+ " } else {\n"
+ " return (com.google.protobuf.ByteString) ref;\n"
+ " }\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private Object $name$_ $default_init$;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public String get$capitalized_name$() {\n"
+ " Object ref = $name$_;\n"
+ " if (!(ref instanceof String)) {\n"
+ " String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();\n"
+ " $name$_ = s;\n"
+ " return s;\n"
+ " } else {\n"
+ " return (String) ref;\n"
+ " }\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$(String value) {\n"
+ "$null_check$"
+ " $set_has_field_bit_builder$;\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_builder$;\n");
+ // 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_,
+ " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
+ printer->Print(variables_,
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "void set$capitalized_name$(com.google.protobuf.ByteString value) {\n"
+ " $set_has_field_bit_builder$;\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void StringFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void StringFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$;\n");
+}
+
+void StringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (other.has$capitalized_name$()) {\n"
+ " set$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void StringFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$set_has_field_bit_builder$;\n"
+ "$name$_ = input.readBytes();\n");
+}
+
+void StringFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$());\n");
+}
+
+void StringFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n");
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+}
+
+string StringFieldGenerator::GetBoxedType() const {
+ return "String";
+}
+
+
+// ===================================================================
+
+RepeatedStringFieldGenerator::
+RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
+}
+
+RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
+
+int RepeatedStringFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedStringFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedStringFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$java.util.List<String> get$capitalized_name$List();\n"
+ "$deprecation$int get$capitalized_name$Count();\n"
+ "$deprecation$String get$capitalized_name$(int index);\n");
+}
+
+
+void RepeatedStringFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private com.google.protobuf.LazyStringList $name$_;\n"
+ "$deprecation$public java.util.List<String>\n"
+ " get$capitalized_name$List() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public String get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+
+ if (descriptor_->options().packed() &&
+ HasGeneratedMethods(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "private int $name$MemoizedSerializedSize = -1;\n");
+ }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ // One field is the list and the bit field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ printer->Print(variables_,
+ "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n");
+
+ printer->Print(variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n");
+
+ // Note: We return an unmodifiable list because otherwise the caller
+ // 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.
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<String>\n"
+ " get$capitalized_name$List() {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public String get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n"
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, String value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder add$capitalized_name$(String value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
+ " java.lang.Iterable<String> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " super.addAll(values, $name$_);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\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->Print(variables_,
+ "void add$capitalized_name$(com.google.protobuf.ByteString value) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void RepeatedStringFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $empty_list$;\n"
+ "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ // The code below does two optimizations:
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
+ printer->Print(variables_,
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
+
+ printer->Print(variables_,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = new com.google.protobuf.UnmodifiableLazyStringList(\n"
+ " $name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(input.readBytes());\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateParsingCodeFromPacked(io::Printer* printer) const {
+ printer->Print(variables_,
+ "int length = input.readRawVarint32();\n"
+ "int limit = input.pushLimit(length);\n"
+ "while (input.getBytesUntilLimit() > 0) {\n"
+ " add$capitalized_name$(input.read$capitalized_type$());\n"
+ "}\n"
+ "input.popLimit(limit);\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (get$capitalized_name$List().size() > 0) {\n"
+ " output.writeRawVarint32($tag$);\n"
+ " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+ "}\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$capitalized_type$NoTag($name$_.get(i));\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeBytes($number$, $name$_.getByteString(i));\n"
+ "}\n");
+ }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int dataSize = 0;\n");
+ printer->Indent();
+
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " dataSize += com.google.protobuf.CodedOutputStream\n"
+ " .computeBytesSizeNoTag($name$_.getByteString(i));\n"
+ "}\n");
+
+ printer->Print(
+ "size += dataSize;\n");
+
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (!get$capitalized_name$List().isEmpty()) {\n"
+ " size += $tag_size$;\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeInt32SizeNoTag(dataSize);\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "size += $tag_size$ * get$capitalized_name$List().size();\n");
+ }
+
+ // cache the data size for packed fields.
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "$name$MemoizedSerializedSize = dataSize;\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+ "}\n");
+}
+
+string RepeatedStringFieldGenerator::GetBoxedType() const {
+ return "String";
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_string_field.h b/src/google/protobuf/compiler/java/java_string_field.h
new file mode 100644
index 00000000..8cb41469
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_string_field.h
@@ -0,0 +1,120 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Author: jonp@google.com (Jon Perlow)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class StringFieldGenerator : public FieldGenerator {
+ public:
+ explicit StringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
+ ~StringFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator);
+};
+
+class RepeatedStringFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
+ ~RepeatedStringFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateParsingCodeFromPacked(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc
index 83d5a4e4..5b76af25 100644
--- a/src/google/protobuf/compiler/mock_code_generator.cc
+++ b/src/google/protobuf/compiler/mock_code_generator.cc
@@ -45,6 +45,16 @@ 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 vector<const FileDescriptor*> all_files) {
+ vector<string> names;
+ for (int i = 0; i < all_files.size(); i++) {
+ names.push_back(all_files[i]->name());
+ }
+ return JoinStrings(names, ",");
+}
+
static const char* kFirstInsertionPointName = "first_mock_insertion_point";
static const char* kSecondInsertionPointName = "second_mock_insertion_point";
static const char* kFirstInsertionPoint =
@@ -63,6 +73,7 @@ void MockCodeGenerator::ExpectGenerated(
const string& insertions,
const string& file,
const string& first_message_name,
+ const string& first_parsed_file_name,
const string& output_directory) {
string content;
ASSERT_TRUE(File::ReadFileToString(
@@ -84,7 +95,8 @@ void MockCodeGenerator::ExpectGenerated(
}
ASSERT_EQ(lines.size(), 3 + insertion_list.size() * 2);
- EXPECT_EQ(GetOutputFileContent(name, parameter, file, first_message_name),
+ EXPECT_EQ(GetOutputFileContent(name, parameter, file,
+ first_parsed_file_name, first_message_name),
lines[0]);
EXPECT_EQ(kFirstInsertionPoint, lines[1 + insertion_list.size()]);
@@ -92,12 +104,12 @@ void MockCodeGenerator::ExpectGenerated(
for (int i = 0; i < insertion_list.size(); i++) {
EXPECT_EQ(GetOutputFileContent(insertion_list[i], "first_insert",
- file, first_message_name),
+ file, file, first_message_name),
lines[1 + i]);
// Second insertion point is indented, so the inserted text should
// automatically be indented too.
EXPECT_EQ(" " + GetOutputFileContent(insertion_list[i], "second_insert",
- file, first_message_name),
+ file, file, first_message_name),
lines[2 + insertion_list.size() + i]);
}
}
@@ -105,7 +117,7 @@ void MockCodeGenerator::ExpectGenerated(
bool MockCodeGenerator::Generate(
const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
for (int i = 0; i < file->message_type_count(); i++) {
if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) {
@@ -134,11 +146,12 @@ bool MockCodeGenerator::Generate(
for (int i = 0; i < insert_into.size(); i++) {
{
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->OpenForInsert(
+ context->OpenForInsert(
GetOutputFileName(insert_into[i], file),
kFirstInsertionPointName));
io::Printer printer(output.get(), '$');
- printer.PrintRaw(GetOutputFileContent(name_, "first_insert", file));
+ printer.PrintRaw(GetOutputFileContent(name_, "first_insert",
+ file, context));
if (printer.failed()) {
*error = "MockCodeGenerator detected write error.";
return false;
@@ -147,11 +160,12 @@ bool MockCodeGenerator::Generate(
{
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->OpenForInsert(
+ context->OpenForInsert(
GetOutputFileName(insert_into[i], file),
kSecondInsertionPointName));
io::Printer printer(output.get(), '$');
- printer.PrintRaw(GetOutputFileContent(name_, "second_insert", file));
+ printer.PrintRaw(GetOutputFileContent(name_, "second_insert",
+ file, context));
if (printer.failed()) {
*error = "MockCodeGenerator detected write error.";
return false;
@@ -160,10 +174,11 @@ bool MockCodeGenerator::Generate(
}
} else {
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(GetOutputFileName(name_, file)));
+ context->Open(GetOutputFileName(name_, file)));
io::Printer printer(output.get(), '$');
- printer.PrintRaw(GetOutputFileContent(name_, parameter, file));
+ printer.PrintRaw(GetOutputFileContent(name_, parameter,
+ file, context));
printer.PrintRaw(kFirstInsertionPoint);
printer.PrintRaw(kSecondInsertionPoint);
@@ -186,11 +201,16 @@ string MockCodeGenerator::GetOutputFileName(const string& generator_name,
return file + ".MockCodeGenerator." + generator_name;
}
-string MockCodeGenerator::GetOutputFileContent(const string& generator_name,
- const string& parameter,
- const FileDescriptor* file) {
+string MockCodeGenerator::GetOutputFileContent(
+ const string& generator_name,
+ const string& parameter,
+ const FileDescriptor* file,
+ GeneratorContext *context) {
+ vector<const FileDescriptor*> all_files;
+ context->ListParsedFiles(&all_files);
return GetOutputFileContent(
generator_name, parameter, file->name(),
+ CommaSeparatedList(all_files),
file->message_type_count() > 0 ?
file->message_type(0)->name() : "(none)");
}
@@ -199,9 +219,11 @@ string MockCodeGenerator::GetOutputFileContent(
const string& generator_name,
const string& parameter,
const string& file,
+ const string& parsed_file_list,
const string& first_message_name) {
- return strings::Substitute("$0: $1, $2, $3\n",
- generator_name, parameter, file, first_message_name);
+ return strings::Substitute("$0: $1, $2, $3, $4\n",
+ generator_name, parameter, file,
+ first_message_name, parsed_file_list);
}
} // namespace compiler
diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h
index 01d69dd2..5c7942bd 100644
--- a/src/google/protobuf/compiler/mock_code_generator.h
+++ b/src/google/protobuf/compiler/mock_code_generator.h
@@ -69,11 +69,14 @@ class MockCodeGenerator : public CodeGenerator {
//
// |insertions| is a comma-separated list of names of MockCodeGenerators which
// should have inserted lines into this file.
+ // |parsed_file_list| is a comma-separated list of names of the files
+ // that are being compiled together in this run.
static void ExpectGenerated(const string& name,
const string& parameter,
const string& insertions,
const string& file,
const string& first_message_name,
+ const string& parsed_file_list,
const string& output_directory);
// Get the name of the file which would be written by the given generator.
@@ -86,7 +89,7 @@ class MockCodeGenerator : public CodeGenerator {
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const;
private:
@@ -94,10 +97,12 @@ class MockCodeGenerator : public CodeGenerator {
static string GetOutputFileContent(const string& generator_name,
const string& parameter,
- const FileDescriptor* file);
+ const FileDescriptor* file,
+ GeneratorContext *context);
static string GetOutputFileContent(const string& generator_name,
const string& parameter,
const string& file,
+ const string& parsed_file_list,
const string& first_message_name);
};
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index 9fcb1314..34317b1f 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -250,20 +250,69 @@ void Parser::AddError(const string& error) {
AddError(input_->current().line, input_->current().column, error);
}
-void Parser::RecordLocation(
- const Message* descriptor,
- DescriptorPool::ErrorCollector::ErrorLocation location,
- int line, int column) {
- if (source_location_table_ != NULL) {
- source_location_table_->Add(descriptor, location, line, column);
+// -------------------------------------------------------------------
+
+Parser::LocationRecorder::LocationRecorder(Parser* parser)
+ : parser_(parser),
+ location_(parser_->source_code_info_->add_location()) {
+ location_->add_span(parser_->input_->current().line);
+ location_->add_span(parser_->input_->current().column);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) {
+ Init(parent);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+ int path1) {
+ Init(parent);
+ AddPath(path1);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+ int path1, int path2) {
+ Init(parent);
+ AddPath(path1);
+ AddPath(path2);
+}
+
+void Parser::LocationRecorder::Init(const LocationRecorder& parent) {
+ parser_ = parent.parser_;
+ location_ = parser_->source_code_info_->add_location();
+ location_->mutable_path()->CopyFrom(parent.location_->path());
+
+ location_->add_span(parser_->input_->current().line);
+ location_->add_span(parser_->input_->current().column);
+}
+
+Parser::LocationRecorder::~LocationRecorder() {
+ if (location_->span_size() <= 2) {
+ EndAt(parser_->input_->previous());
}
}
-void Parser::RecordLocation(
- const Message* descriptor,
+void Parser::LocationRecorder::AddPath(int path_component) {
+ location_->add_path(path_component);
+}
+
+void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) {
+ location_->set_span(0, token.line);
+ location_->set_span(1, token.column);
+}
+
+void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) {
+ if (token.line != location_->span(0)) {
+ location_->add_span(token.line);
+ }
+ location_->add_span(token.end_column);
+}
+
+void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location) {
- RecordLocation(descriptor, location,
- input_->current().line, input_->current().column);
+ if (parser_->source_location_table_ != NULL) {
+ parser_->source_location_table_->Add(
+ descriptor, location, location_->span(0), location_->span(1));
+ }
}
// -------------------------------------------------------------------
@@ -308,38 +357,51 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
had_errors_ = false;
syntax_identifier_.clear();
+ // Note that |file| could be NULL at this point if
+ // stop_after_syntax_identifier_ is true. So, we conservatively allocate
+ // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto
+ // later on.
+ SourceCodeInfo source_code_info;
+ source_code_info_ = &source_code_info;
+
if (LookingAtType(io::Tokenizer::TYPE_START)) {
// Advance to first token.
input_->Next();
}
- if (require_syntax_identifier_ || LookingAt("syntax")) {
- if (!ParseSyntaxIdentifier()) {
- // Don't attempt to parse the file if we didn't recognize the syntax
- // identifier.
- return false;
+ {
+ LocationRecorder root_location(this);
+
+ if (require_syntax_identifier_ || LookingAt("syntax")) {
+ if (!ParseSyntaxIdentifier()) {
+ // Don't attempt to parse the file if we didn't recognize the syntax
+ // identifier.
+ return false;
+ }
+ } else if (!stop_after_syntax_identifier_) {
+ syntax_identifier_ = "proto2";
}
- } else if (!stop_after_syntax_identifier_) {
- syntax_identifier_ = "proto2";
- }
- if (stop_after_syntax_identifier_) return !had_errors_;
+ if (stop_after_syntax_identifier_) return !had_errors_;
- // Repeatedly parse statements until we reach the end of the file.
- while (!AtEnd()) {
- if (!ParseTopLevelStatement(file)) {
- // This statement failed to parse. Skip it, but keep looping to parse
- // other statements.
- SkipStatement();
+ // Repeatedly parse statements until we reach the end of the file.
+ while (!AtEnd()) {
+ if (!ParseTopLevelStatement(file, root_location)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
- if (LookingAt("}")) {
- AddError("Unmatched \"}\".");
- input_->Next();
+ if (LookingAt("}")) {
+ AddError("Unmatched \"}\".");
+ input_->Next();
+ }
}
}
}
input_ = NULL;
+ source_code_info_ = NULL;
+ source_code_info.Swap(file->mutable_source_code_info());
return !had_errors_;
}
@@ -363,25 +425,40 @@ bool Parser::ParseSyntaxIdentifier() {
return true;
}
-bool Parser::ParseTopLevelStatement(FileDescriptorProto* file) {
+bool Parser::ParseTopLevelStatement(FileDescriptorProto* file,
+ const LocationRecorder& root_location) {
if (TryConsume(";")) {
// empty statement; ignore
return true;
} else if (LookingAt("message")) {
- return ParseMessageDefinition(file->add_message_type());
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size());
+ return ParseMessageDefinition(file->add_message_type(), location);
} else if (LookingAt("enum")) {
- return ParseEnumDefinition(file->add_enum_type());
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size());
+ return ParseEnumDefinition(file->add_enum_type(), location);
} else if (LookingAt("service")) {
- return ParseServiceDefinition(file->add_service());
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kServiceFieldNumber, file->service_size());
+ return ParseServiceDefinition(file->add_service(), location);
} else if (LookingAt("extend")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kExtensionFieldNumber);
return ParseExtend(file->mutable_extension(),
- file->mutable_message_type());
+ file->mutable_message_type(),
+ root_location,
+ FileDescriptorProto::kMessageTypeFieldNumber,
+ location);
} else if (LookingAt("import")) {
- return ParseImport(file->add_dependency());
+ int index = file->dependency_size();
+ return ParseImport(file->add_dependency(), root_location, index);
} else if (LookingAt("package")) {
- return ParsePackage(file);
+ return ParsePackage(file, root_location);
} else if (LookingAt("option")) {
- return ParseOption(file->mutable_options());
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(file->mutable_options(), location);
} else {
AddError("Expected top-level statement (e.g. \"message\").");
return false;
@@ -391,15 +468,22 @@ bool Parser::ParseTopLevelStatement(FileDescriptorProto* file) {
// -------------------------------------------------------------------
// Messages
-bool Parser::ParseMessageDefinition(DescriptorProto* message) {
+bool Parser::ParseMessageDefinition(DescriptorProto* message,
+ const LocationRecorder& message_location) {
DO(Consume("message"));
- RecordLocation(message, DescriptorPool::ErrorCollector::NAME);
- DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
- DO(ParseMessageBlock(message));
+ {
+ LocationRecorder location(message_location,
+ DescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ message, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
+ }
+ DO(ParseMessageBlock(message, message_location));
return true;
}
-bool Parser::ParseMessageBlock(DescriptorProto* message) {
+bool Parser::ParseMessageBlock(DescriptorProto* message,
+ const LocationRecorder& message_location) {
DO(Consume("{"));
while (!TryConsume("}")) {
@@ -408,7 +492,7 @@ bool Parser::ParseMessageBlock(DescriptorProto* message) {
return false;
}
- if (!ParseMessageStatement(message)) {
+ if (!ParseMessageStatement(message, message_location)) {
// This statement failed to parse. Skip it, but keep looping to parse
// other statements.
SkipStatement();
@@ -418,66 +502,133 @@ bool Parser::ParseMessageBlock(DescriptorProto* message) {
return true;
}
-bool Parser::ParseMessageStatement(DescriptorProto* message) {
+bool Parser::ParseMessageStatement(DescriptorProto* message,
+ const LocationRecorder& message_location) {
if (TryConsume(";")) {
// empty statement; ignore
return true;
} else if (LookingAt("message")) {
- return ParseMessageDefinition(message->add_nested_type());
+ LocationRecorder location(message_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ message->nested_type_size());
+ return ParseMessageDefinition(message->add_nested_type(), location);
} else if (LookingAt("enum")) {
- return ParseEnumDefinition(message->add_enum_type());
+ LocationRecorder location(message_location,
+ DescriptorProto::kEnumTypeFieldNumber,
+ message->enum_type_size());
+ return ParseEnumDefinition(message->add_enum_type(), location);
} else if (LookingAt("extensions")) {
- return ParseExtensions(message);
+ LocationRecorder location(message_location,
+ DescriptorProto::kExtensionRangeFieldNumber);
+ return ParseExtensions(message, location);
} else if (LookingAt("extend")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kExtensionFieldNumber);
return ParseExtend(message->mutable_extension(),
- message->mutable_nested_type());
+ message->mutable_nested_type(),
+ message_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ location);
} else if (LookingAt("option")) {
- return ParseOption(message->mutable_options());
+ LocationRecorder location(message_location,
+ DescriptorProto::kOptionsFieldNumber);
+ return ParseOption(message->mutable_options(), location);
} else {
+ LocationRecorder location(message_location,
+ DescriptorProto::kFieldFieldNumber,
+ message->field_size());
return ParseMessageField(message->add_field(),
- message->mutable_nested_type());
+ message->mutable_nested_type(),
+ message_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ location);
}
}
bool Parser::ParseMessageField(FieldDescriptorProto* field,
- RepeatedPtrField<DescriptorProto>* messages) {
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location) {
// Parse label and type.
- FieldDescriptorProto::Label label;
- DO(ParseLabel(&label));
- field->set_label(label);
-
- RecordLocation(field, DescriptorPool::ErrorCollector::TYPE);
- FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
- string type_name;
- DO(ParseType(&type, &type_name));
- if (type_name.empty()) {
- field->set_type(type);
- } else {
- field->set_type_name(type_name);
+ io::Tokenizer::Token label_token = input_->current();
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kLabelFieldNumber);
+ FieldDescriptorProto::Label label;
+ DO(ParseLabel(&label));
+ field->set_label(label);
+ }
+
+ {
+ LocationRecorder location(field_location); // add path later
+ location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE);
+
+ FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
+ string type_name;
+ DO(ParseType(&type, &type_name));
+ if (type_name.empty()) {
+ location.AddPath(FieldDescriptorProto::kTypeFieldNumber);
+ field->set_type(type);
+ } else {
+ location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
+ field->set_type_name(type_name);
+ }
}
// Parse name and '='.
- RecordLocation(field, DescriptorPool::ErrorCollector::NAME);
io::Tokenizer::Token name_token = input_->current();
- DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
+ }
DO(Consume("=", "Missing field number."));
// Parse field number.
- RecordLocation(field, DescriptorPool::ErrorCollector::NUMBER);
- int number;
- DO(ConsumeInteger(&number, "Expected field number."));
- field->set_number(number);
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kNumberFieldNumber);
+ location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::NUMBER);
+ int number;
+ DO(ConsumeInteger(&number, "Expected field number."));
+ field->set_number(number);
+ }
// Parse options.
- DO(ParseFieldOptions(field));
+ DO(ParseFieldOptions(field, field_location));
// Deal with groups.
- if (type_name.empty() && type == FieldDescriptorProto::TYPE_GROUP) {
+ if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) {
+ // Awkward: Since a group declares both a message type and a field, we
+ // have to create overlapping locations.
+ LocationRecorder group_location(parent_location);
+ group_location.StartAt(label_token);
+ group_location.AddPath(location_field_number_for_nested_type);
+ group_location.AddPath(messages->size());
+
DescriptorProto* group = messages->Add();
group->set_name(field->name());
+
// Record name location to match the field name's location.
- RecordLocation(group, DescriptorPool::ErrorCollector::NAME,
- name_token.line, name_token.column);
+ {
+ LocationRecorder location(group_location,
+ DescriptorProto::kNameFieldNumber);
+ location.StartAt(name_token);
+ location.EndAt(name_token);
+ location.RecordLegacyLocation(
+ group, DescriptorPool::ErrorCollector::NAME);
+ }
+
+ // The field's type_name also comes from the name. Confusing!
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kTypeNameFieldNumber);
+ location.StartAt(name_token);
+ location.EndAt(name_token);
+ }
// As a hack for backwards-compatibility, we force the group name to start
// with a capital letter and lower-case the field name. New code should
@@ -490,7 +641,7 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field,
field->set_type_name(group->name());
if (LookingAt("{")) {
- DO(ParseMessageBlock(group));
+ DO(ParseMessageBlock(group, group_location));
} else {
AddError("Missing group body.");
return false;
@@ -502,15 +653,23 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field,
return true;
}
-bool Parser::ParseFieldOptions(FieldDescriptorProto* field) {
- if (!TryConsume("[")) return true;
+bool Parser::ParseFieldOptions(FieldDescriptorProto* field,
+ const LocationRecorder& field_location) {
+ if (!LookingAt("[")) return true;
+
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kOptionsFieldNumber);
+
+ DO(Consume("["));
// Parse field options.
do {
if (LookingAt("default")) {
- DO(ParseDefaultAssignment(field));
+ // We intentionally pass field_location rather than location here, since
+ // the default value is not actually an option.
+ DO(ParseDefaultAssignment(field, field_location));
} else {
- DO(ParseOptionAssignment(field->mutable_options()));
+ DO(ParseOptionAssignment(field->mutable_options(), location));
}
} while (TryConsume(","));
@@ -518,7 +677,8 @@ bool Parser::ParseFieldOptions(FieldDescriptorProto* field) {
return true;
}
-bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
+bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field,
+ const LocationRecorder& field_location) {
if (field->has_default_value()) {
AddError("Already set option \"default\".");
field->clear_default_value();
@@ -527,7 +687,10 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
DO(Consume("default"));
DO(Consume("="));
- RecordLocation(field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kDefaultValueFieldNumber);
+ location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
string* default_value = field->mutable_default_value();
if (!field->has_type()) {
@@ -634,26 +797,35 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) {
return true;
}
-bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option) {
+bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
+ const LocationRecorder& part_location) {
UninterpretedOption::NamePart* name = uninterpreted_option->add_name();
string identifier; // We parse identifiers into this string.
if (LookingAt("(")) { // This is an extension.
DO(Consume("("));
- // An extension name consists of dot-separated identifiers, and may begin
- // with a dot.
- if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
- DO(ConsumeIdentifier(&identifier, "Expected identifier."));
- name->mutable_name_part()->append(identifier);
- }
- while (LookingAt(".")) {
- DO(Consume("."));
- name->mutable_name_part()->append(".");
- DO(ConsumeIdentifier(&identifier, "Expected identifier."));
- name->mutable_name_part()->append(identifier);
+
+ {
+ LocationRecorder location(
+ part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
+ // An extension name consists of dot-separated identifiers, and may begin
+ // with a dot.
+ if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ name->mutable_name_part()->append(identifier);
+ }
+ while (LookingAt(".")) {
+ DO(Consume("."));
+ name->mutable_name_part()->append(".");
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ name->mutable_name_part()->append(identifier);
+ }
}
+
DO(Consume(")"));
name->set_is_extension(true);
} else { // This is a regular field.
+ LocationRecorder location(
+ part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
DO(ConsumeIdentifier(&identifier, "Expected identifier."));
name->mutable_name_part()->append(identifier);
name->set_is_extension(false);
@@ -661,34 +833,75 @@ bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option) {
return true;
}
+bool Parser::ParseUninterpretedBlock(string* value) {
+ // Note that enclosing braces are not added to *value.
+ DO(Consume("{"));
+ int brace_depth = 1;
+ while (!AtEnd()) {
+ if (LookingAt("{")) {
+ brace_depth++;
+ } else if (LookingAt("}")) {
+ brace_depth--;
+ if (brace_depth == 0) {
+ input_->Next();
+ return true;
+ }
+ }
+ // TODO(sanjay): Interpret line/column numbers to preserve formatting
+ if (!value->empty()) value->push_back(' ');
+ value->append(input_->current().text);
+ input_->Next();
+ }
+ AddError("Unexpected end of stream while parsing aggregate value.");
+ return false;
+}
+
// We don't interpret the option here. Instead we store it in an
// UninterpretedOption, to be interpreted later.
-bool Parser::ParseOptionAssignment(Message* options) {
+bool Parser::ParseOptionAssignment(Message* options,
+ const LocationRecorder& options_location) {
// Create an entry in the uninterpreted_option field.
const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->
FindFieldByName("uninterpreted_option");
GOOGLE_CHECK(uninterpreted_option_field != NULL)
<< "No field named \"uninterpreted_option\" in the Options proto.";
+ const Reflection* reflection = options->GetReflection();
+
+ LocationRecorder location(
+ options_location, uninterpreted_option_field->number(),
+ reflection->FieldSize(*options, uninterpreted_option_field));
+
UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>(
options->GetReflection()->AddMessage(options,
uninterpreted_option_field));
// Parse dot-separated name.
- RecordLocation(uninterpreted_option,
- DescriptorPool::ErrorCollector::OPTION_NAME);
-
- DO(ParseOptionNamePart(uninterpreted_option));
+ {
+ LocationRecorder name_location(location,
+ UninterpretedOption::kNameFieldNumber);
+ name_location.RecordLegacyLocation(
+ uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME);
+
+ {
+ LocationRecorder part_location(name_location,
+ uninterpreted_option->name_size());
+ DO(ParseOptionNamePart(uninterpreted_option, part_location));
+ }
- while (LookingAt(".")) {
- DO(Consume("."));
- DO(ParseOptionNamePart(uninterpreted_option));
+ while (LookingAt(".")) {
+ DO(Consume("."));
+ LocationRecorder part_location(name_location,
+ uninterpreted_option->name_size());
+ DO(ParseOptionNamePart(uninterpreted_option, part_location));
+ }
}
DO(Consume("="));
- RecordLocation(uninterpreted_option,
- DescriptorPool::ErrorCollector::OPTION_VALUE);
+ LocationRecorder value_location(location);
+ value_location.RecordLegacyLocation(
+ uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE);
// All values are a single token, except for negative numbers, which consist
// of a single '-' symbol, followed by a positive number.
@@ -704,6 +917,7 @@ bool Parser::ParseOptionAssignment(Message* options) {
return false;
case io::Tokenizer::TYPE_IDENTIFIER: {
+ value_location.AddPath(UninterpretedOption::kIdentifierValueFieldNumber);
if (is_negative) {
AddError("Invalid '-' symbol before identifier.");
return false;
@@ -720,15 +934,19 @@ bool Parser::ParseOptionAssignment(Message* options) {
is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max;
DO(ConsumeInteger64(max_value, &value, "Expected integer."));
if (is_negative) {
- uninterpreted_option->set_negative_int_value(
- -static_cast<int64>(value));
+ value_location.AddPath(
+ UninterpretedOption::kNegativeIntValueFieldNumber);
+ uninterpreted_option->set_negative_int_value(-static_cast<int64>(value));
} else {
+ value_location.AddPath(
+ UninterpretedOption::kPositiveIntValueFieldNumber);
uninterpreted_option->set_positive_int_value(value);
}
break;
}
case io::Tokenizer::TYPE_FLOAT: {
+ value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber);
double value;
DO(ConsumeNumber(&value, "Expected number."));
uninterpreted_option->set_double_value(is_negative ? -value : value);
@@ -736,6 +954,7 @@ bool Parser::ParseOptionAssignment(Message* options) {
}
case io::Tokenizer::TYPE_STRING: {
+ value_location.AddPath(UninterpretedOption::kStringValueFieldNumber);
if (is_negative) {
AddError("Invalid '-' symbol before string.");
return false;
@@ -747,31 +966,57 @@ bool Parser::ParseOptionAssignment(Message* options) {
}
case io::Tokenizer::TYPE_SYMBOL:
- AddError("Expected option value.");
- return false;
+ if (LookingAt("{")) {
+ value_location.AddPath(UninterpretedOption::kAggregateValueFieldNumber);
+ DO(ParseUninterpretedBlock(
+ uninterpreted_option->mutable_aggregate_value()));
+ } else {
+ AddError("Expected option value.");
+ return false;
+ }
+ break;
}
return true;
}
-bool Parser::ParseExtensions(DescriptorProto* message) {
+bool Parser::ParseExtensions(DescriptorProto* message,
+ const LocationRecorder& extensions_location) {
// Parse the declaration.
DO(Consume("extensions"));
do {
+ // Note that kExtensionRangeFieldNumber was already pushed by the parent.
+ LocationRecorder location(extensions_location,
+ message->extension_range_size());
+
DescriptorProto::ExtensionRange* range = message->add_extension_range();
- RecordLocation(range, DescriptorPool::ErrorCollector::NUMBER);
+ location.RecordLegacyLocation(
+ range, DescriptorPool::ErrorCollector::NUMBER);
int start, end;
- DO(ConsumeInteger(&start, "Expected field number range."));
+ io::Tokenizer::Token start_token;
+
+ {
+ LocationRecorder start_location(
+ location, DescriptorProto::ExtensionRange::kStartFieldNumber);
+ start_token = input_->current();
+ DO(ConsumeInteger(&start, "Expected field number range."));
+ }
if (TryConsume("to")) {
+ LocationRecorder end_location(
+ location, DescriptorProto::ExtensionRange::kEndFieldNumber);
if (TryConsume("max")) {
end = FieldDescriptor::kMaxNumber;
} else {
DO(ConsumeInteger(&end, "Expected integer."));
}
} else {
+ LocationRecorder end_location(
+ location, DescriptorProto::ExtensionRange::kEndFieldNumber);
+ end_location.StartAt(start_token);
+ end_location.EndAt(start_token);
end = start;
}
@@ -788,16 +1033,17 @@ bool Parser::ParseExtensions(DescriptorProto* message) {
}
bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
- RepeatedPtrField<DescriptorProto>* messages) {
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& extend_location) {
DO(Consume("extend"));
- // We expect to see at least one extension field defined in the extend block.
- // We need to create it now so we can record the extendee's location.
- FieldDescriptorProto* first_field = extensions->Add();
-
// Parse the extendee type.
- RecordLocation(first_field, DescriptorPool::ErrorCollector::EXTENDEE);
- DO(ParseUserDefinedType(first_field->mutable_extendee()));
+ io::Tokenizer::Token extendee_start = input_->current();
+ string extendee;
+ DO(ParseUserDefinedType(&extendee));
+ io::Tokenizer::Token extendee_end = input_->previous();
// Parse the block.
DO(Consume("{"));
@@ -810,16 +1056,29 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
return false;
}
- FieldDescriptorProto* field;
- if (is_first) {
- field = first_field;
- is_first = false;
- } else {
- field = extensions->Add();
- field->set_extendee(first_field->extendee());
+ // Note that kExtensionFieldNumber was already pushed by the parent.
+ LocationRecorder location(extend_location, extensions->size());
+
+ FieldDescriptorProto* field = extensions->Add();
+
+ {
+ LocationRecorder extendee_location(
+ location, FieldDescriptorProto::kExtendeeFieldNumber);
+ extendee_location.StartAt(extendee_start);
+ extendee_location.EndAt(extendee_end);
+
+ if (is_first) {
+ extendee_location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::EXTENDEE);
+ is_first = false;
+ }
}
- if (!ParseMessageField(field, messages)) {
+ field->set_extendee(extendee);
+
+ if (!ParseMessageField(field, messages, parent_location,
+ location_field_number_for_nested_type,
+ location)) {
// This statement failed to parse. Skip it, but keep looping to parse
// other statements.
SkipStatement();
@@ -832,15 +1091,24 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
// -------------------------------------------------------------------
// Enums
-bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type) {
+bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location) {
DO(Consume("enum"));
- RecordLocation(enum_type, DescriptorPool::ErrorCollector::NAME);
- DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
- DO(ParseEnumBlock(enum_type));
+
+ {
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ enum_type, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
+ }
+
+ DO(ParseEnumBlock(enum_type, enum_location));
return true;
}
-bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) {
+bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location) {
DO(Consume("{"));
while (!TryConsume("}")) {
@@ -849,7 +1117,7 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) {
return false;
}
- if (!ParseEnumStatement(enum_type)) {
+ if (!ParseEnumStatement(enum_type, enum_location)) {
// This statement failed to parse. Skip it, but keep looping to parse
// other statements.
SkipStatement();
@@ -859,41 +1127,69 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) {
return true;
}
-bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type) {
+bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location) {
if (TryConsume(";")) {
// empty statement; ignore
return true;
} else if (LookingAt("option")) {
- return ParseOption(enum_type->mutable_options());
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(enum_type->mutable_options(), location);
} else {
- return ParseEnumConstant(enum_type->add_value());
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kValueFieldNumber, enum_type->value_size());
+ return ParseEnumConstant(enum_type->add_value(), location);
}
}
-bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value) {
- RecordLocation(enum_value, DescriptorPool::ErrorCollector::NAME);
- DO(ConsumeIdentifier(enum_value->mutable_name(),
- "Expected enum constant name."));
+bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value,
+ const LocationRecorder& enum_value_location) {
+ // Parse name.
+ {
+ LocationRecorder location(enum_value_location,
+ EnumValueDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ enum_value, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(enum_value->mutable_name(),
+ "Expected enum constant name."));
+ }
+
DO(Consume("=", "Missing numeric value for enum constant."));
- bool is_negative = TryConsume("-");
- int number;
- DO(ConsumeInteger(&number, "Expected integer."));
- if (is_negative) number *= -1;
- enum_value->set_number(number);
+ // Parse value.
+ {
+ LocationRecorder location(
+ enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber);
+ location.RecordLegacyLocation(
+ enum_value, DescriptorPool::ErrorCollector::NUMBER);
+
+ bool is_negative = TryConsume("-");
+ int number;
+ DO(ConsumeInteger(&number, "Expected integer."));
+ if (is_negative) number *= -1;
+ enum_value->set_number(number);
+ }
- DO(ParseEnumConstantOptions(enum_value));
+ DO(ParseEnumConstantOptions(enum_value, enum_value_location));
DO(Consume(";"));
return true;
}
-bool Parser::ParseEnumConstantOptions(EnumValueDescriptorProto* value) {
- if (!TryConsume("[")) return true;
+bool Parser::ParseEnumConstantOptions(
+ EnumValueDescriptorProto* value,
+ const LocationRecorder& enum_value_location) {
+ if (!LookingAt("[")) return true;
+
+ LocationRecorder location(
+ enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber);
+
+ DO(Consume("["));
do {
- DO(ParseOptionAssignment(value->mutable_options()));
+ DO(ParseOptionAssignment(value->mutable_options(), location));
} while (TryConsume(","));
DO(Consume("]"));
@@ -903,15 +1199,24 @@ bool Parser::ParseEnumConstantOptions(EnumValueDescriptorProto* value) {
// -------------------------------------------------------------------
// Services
-bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service) {
+bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location) {
DO(Consume("service"));
- RecordLocation(service, DescriptorPool::ErrorCollector::NAME);
- DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
- DO(ParseServiceBlock(service));
+
+ {
+ LocationRecorder location(service_location,
+ ServiceDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ service, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
+ }
+
+ DO(ParseServiceBlock(service, service_location));
return true;
}
-bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) {
+bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location) {
DO(Consume("{"));
while (!TryConsume("}")) {
@@ -920,7 +1225,7 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) {
return false;
}
- if (!ParseServiceStatement(service)) {
+ if (!ParseServiceStatement(service, service_location)) {
// This statement failed to parse. Skip it, but keep looping to parse
// other statements.
SkipStatement();
@@ -930,33 +1235,55 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) {
return true;
}
-bool Parser::ParseServiceStatement(ServiceDescriptorProto* service) {
+bool Parser::ParseServiceStatement(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location) {
if (TryConsume(";")) {
// empty statement; ignore
return true;
} else if (LookingAt("option")) {
- return ParseOption(service->mutable_options());
+ LocationRecorder location(
+ service_location, ServiceDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(service->mutable_options(), location);
} else {
- return ParseServiceMethod(service->add_method());
+ LocationRecorder location(service_location,
+ ServiceDescriptorProto::kMethodFieldNumber, service->method_size());
+ return ParseServiceMethod(service->add_method(), location);
}
}
-bool Parser::ParseServiceMethod(MethodDescriptorProto* method) {
+bool Parser::ParseServiceMethod(MethodDescriptorProto* method,
+ const LocationRecorder& method_location) {
DO(Consume("rpc"));
- RecordLocation(method, DescriptorPool::ErrorCollector::NAME);
- DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
+
+ {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ method, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
+ }
// Parse input type.
DO(Consume("("));
- RecordLocation(method, DescriptorPool::ErrorCollector::INPUT_TYPE);
- DO(ParseUserDefinedType(method->mutable_input_type()));
+ {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kInputTypeFieldNumber);
+ location.RecordLegacyLocation(
+ method, DescriptorPool::ErrorCollector::INPUT_TYPE);
+ DO(ParseUserDefinedType(method->mutable_input_type()));
+ }
DO(Consume(")"));
// Parse output type.
DO(Consume("returns"));
DO(Consume("("));
- RecordLocation(method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
- DO(ParseUserDefinedType(method->mutable_output_type()));
+ {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kOutputTypeFieldNumber);
+ location.RecordLegacyLocation(
+ method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
+ DO(ParseUserDefinedType(method->mutable_output_type()));
+ }
DO(Consume(")"));
if (TryConsume("{")) {
@@ -970,7 +1297,9 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method) {
if (TryConsume(";")) {
// empty statement; ignore
} else {
- if (!ParseOption(method->mutable_options())) {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kOptionsFieldNumber);
+ if (!ParseOption(method->mutable_options(), location)) {
// This statement failed to parse. Skip it, but keep looping to
// parse other statements.
SkipStatement();
@@ -1054,7 +1383,8 @@ bool Parser::ParseUserDefinedType(string* type_name) {
// ===================================================================
-bool Parser::ParsePackage(FileDescriptorProto* file) {
+bool Parser::ParsePackage(FileDescriptorProto* file,
+ const LocationRecorder& root_location) {
if (file->has_package()) {
AddError("Multiple package definitions.");
// Don't append the new package to the old one. Just replace it. Not
@@ -1064,31 +1394,43 @@ bool Parser::ParsePackage(FileDescriptorProto* file) {
DO(Consume("package"));
- RecordLocation(file, DescriptorPool::ErrorCollector::NAME);
+ {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kPackageFieldNumber);
+ location.RecordLegacyLocation(file, DescriptorPool::ErrorCollector::NAME);
- while (true) {
- string identifier;
- DO(ConsumeIdentifier(&identifier, "Expected identifier."));
- file->mutable_package()->append(identifier);
- if (!TryConsume(".")) break;
- file->mutable_package()->append(".");
+ while (true) {
+ string identifier;
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ file->mutable_package()->append(identifier);
+ if (!TryConsume(".")) break;
+ file->mutable_package()->append(".");
+ }
}
DO(Consume(";"));
return true;
}
-bool Parser::ParseImport(string* import_filename) {
+bool Parser::ParseImport(string* import_filename,
+ const LocationRecorder& root_location,
+ int index) {
DO(Consume("import"));
- DO(ConsumeString(import_filename,
- "Expected a string naming the file to import."));
+ {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kDependencyFieldNumber,
+ index);
+ DO(ConsumeString(import_filename,
+ "Expected a string naming the file to import."));
+ }
DO(Consume(";"));
return true;
}
-bool Parser::ParseOption(Message* options) {
+bool Parser::ParseOption(Message* options,
+ const LocationRecorder& options_location) {
DO(Consume("option"));
- DO(ParseOptionAssignment(options));
+ DO(ParseOptionAssignment(options, options_location));
DO(Consume(";"));
return true;
}
diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h
index 72c96d04..4cc90a29 100644
--- a/src/google/protobuf/compiler/parser.h
+++ b/src/google/protobuf/compiler/parser.h
@@ -74,6 +74,9 @@ class LIBPROTOBUF_EXPORT Parser {
// Optional fetaures:
+ // DEPRECATED: New code should use the SourceCodeInfo embedded in the
+ // FileDescriptorProto.
+ //
// Requests that locations of certain definitions be recorded to the given
// SourceLocationTable while parsing. This can be used to look up exact line
// and column numbers for errors reported by DescriptorPool during validation.
@@ -82,7 +85,7 @@ class LIBPROTOBUF_EXPORT Parser {
source_location_table_ = location_table;
}
- // Requsets that errors be recorded to the given ErrorCollector while
+ // Requests that errors be recorded to the given ErrorCollector while
// parsing. Set to NULL (the default) to discard error messages.
void RecordErrorsTo(io::ErrorCollector* error_collector) {
error_collector_ = error_collector;
@@ -180,16 +183,56 @@ class LIBPROTOBUF_EXPORT Parser {
// of the current token.
void AddError(const string& error);
- // Record the given line and column and associate it with this descriptor
- // in the SourceLocationTable.
- void RecordLocation(const Message* descriptor,
- DescriptorPool::ErrorCollector::ErrorLocation location,
- int line, int column);
-
- // Record the current line and column and associate it with this descriptor
- // in the SourceLocationTable.
- void RecordLocation(const Message* descriptor,
- DescriptorPool::ErrorCollector::ErrorLocation location);
+ // Records a location in the SourceCodeInfo.location table (see
+ // descriptor.proto). We use RAII to ensure that the start and end locations
+ // are recorded -- the constructor records the start location and the
+ // destructor records the end location. Since the parser is
+ // recursive-descent, this works out beautifully.
+ class LIBPROTOBUF_EXPORT LocationRecorder {
+ public:
+ // Construct the file's "root" location.
+ LocationRecorder(Parser* parser);
+
+ // Construct a location that represents a declaration nested within the
+ // given parent. E.g. a field's location is nested within the location
+ // for a message type. The parent's path will be copied, so you should
+ // call AddPath() only to add the path components leading from the parent
+ // to the child (as opposed to leading from the root to the child).
+ LocationRecorder(const LocationRecorder& parent);
+
+ // Convenience constructors that call AddPath() one or two times.
+ LocationRecorder(const LocationRecorder& parent, int path1);
+ LocationRecorder(const LocationRecorder& parent, int path1, int path2);
+
+ ~LocationRecorder();
+
+ // Add a path component. See SourceCodeInfo.Location.path in
+ // descriptor.proto.
+ void AddPath(int path_component);
+
+ // By default the location is considered to start at the current token at
+ // the time the LocationRecorder is created. StartAt() sets the start
+ // location to the given token instead.
+ void StartAt(const io::Tokenizer::Token& token);
+
+ // By default the location is considered to end at the previous token at
+ // the time the LocationRecorder is destroyed. EndAt() sets the end
+ // location to the given token instead.
+ void EndAt(const io::Tokenizer::Token& token);
+
+ // Records the start point of this location to the SourceLocationTable that
+ // was passed to RecordSourceLocationsTo(), if any. SourceLocationTable
+ // is an older way of keeping track of source locations which is still
+ // used in some places.
+ void RecordLegacyLocation(const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location);
+
+ private:
+ Parser* parser_;
+ SourceCodeInfo::Location* location_;
+
+ void Init(const LocationRecorder& parent);
+ };
// =================================================================
// Parsers for various language constructs
@@ -210,50 +253,81 @@ class LIBPROTOBUF_EXPORT Parser {
// makes logic much simpler for the caller.
// Parse a top-level message, enum, service, etc.
- bool ParseTopLevelStatement(FileDescriptorProto* file);
+ bool ParseTopLevelStatement(FileDescriptorProto* file,
+ const LocationRecorder& root_location);
// Parse various language high-level language construrcts.
- bool ParseMessageDefinition(DescriptorProto* message);
- bool ParseEnumDefinition(EnumDescriptorProto* enum_type);
- bool ParseServiceDefinition(ServiceDescriptorProto* service);
- bool ParsePackage(FileDescriptorProto* file);
- bool ParseImport(string* import_filename);
- bool ParseOption(Message* options);
+ bool ParseMessageDefinition(DescriptorProto* message,
+ const LocationRecorder& message_location);
+ bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location);
+ bool ParseServiceDefinition(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location);
+ bool ParsePackage(FileDescriptorProto* file,
+ const LocationRecorder& root_location);
+ bool ParseImport(string* import_filename,
+ const LocationRecorder& root_location,
+ int index);
+ bool ParseOption(Message* options,
+ const LocationRecorder& options_location);
// These methods parse the contents of a message, enum, or service type and
// add them to the given object. They consume the entire block including
// the beginning and ending brace.
- bool ParseMessageBlock(DescriptorProto* message);
- bool ParseEnumBlock(EnumDescriptorProto* enum_type);
- bool ParseServiceBlock(ServiceDescriptorProto* service);
+ bool ParseMessageBlock(DescriptorProto* message,
+ const LocationRecorder& message_location);
+ bool ParseEnumBlock(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location);
+ bool ParseServiceBlock(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location);
// Parse one statement within a message, enum, or service block, inclunding
// final semicolon.
- bool ParseMessageStatement(DescriptorProto* message);
- bool ParseEnumStatement(EnumDescriptorProto* message);
- bool ParseServiceStatement(ServiceDescriptorProto* message);
+ bool ParseMessageStatement(DescriptorProto* message,
+ const LocationRecorder& message_location);
+ bool ParseEnumStatement(EnumDescriptorProto* message,
+ const LocationRecorder& enum_location);
+ bool ParseServiceStatement(ServiceDescriptorProto* message,
+ const LocationRecorder& service_location);
// Parse a field of a message. If the field is a group, its type will be
// added to "messages".
+ //
+ // parent_location and location_field_number_for_nested_type are needed when
+ // parsing groups -- we need to generate a nested message type within the
+ // parent and record its location accordingly. Since the parent could be
+ // either a FileDescriptorProto or a DescriptorProto, we must pass in the
+ // correct field number to use.
bool ParseMessageField(FieldDescriptorProto* field,
- RepeatedPtrField<DescriptorProto>* messages);
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location);
// Parse an "extensions" declaration.
- bool ParseExtensions(DescriptorProto* message);
+ bool ParseExtensions(DescriptorProto* message,
+ const LocationRecorder& extensions_location);
- // Parse an "extend" declaration.
+ // Parse an "extend" declaration. (See also comments for
+ // ParseMessageField().)
bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
- RepeatedPtrField<DescriptorProto>* messages);
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& extend_location);
// Parse a single enum value within an enum block.
- bool ParseEnumConstant(EnumValueDescriptorProto* enum_value);
+ bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
+ const LocationRecorder& enum_value_location);
// Parse enum constant options, i.e. the list in square brackets at the end
// of the enum constant value definition.
- bool ParseEnumConstantOptions(EnumValueDescriptorProto* value);
+ bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
+ const LocationRecorder& enum_value_location);
// Parse a single method within a service definition.
- bool ParseServiceMethod(MethodDescriptorProto* method);
+ bool ParseServiceMethod(MethodDescriptorProto* method,
+ const LocationRecorder& method_location);
// Parse "required", "optional", or "repeated" and fill in "label"
// with the value.
@@ -269,28 +343,45 @@ class LIBPROTOBUF_EXPORT Parser {
// Parses field options, i.e. the stuff in square brackets at the end
// of a field definition. Also parses default value.
- bool ParseFieldOptions(FieldDescriptorProto* field);
+ bool ParseFieldOptions(FieldDescriptorProto* field,
+ const LocationRecorder& field_location);
// Parse the "default" option. This needs special handling because its
// type is the field's type.
- bool ParseDefaultAssignment(FieldDescriptorProto* field);
+ bool ParseDefaultAssignment(FieldDescriptorProto* field,
+ const LocationRecorder& field_location);
// Parse a single option name/value pair, e.g. "ctype = CORD". The name
// identifies a field of the given Message, and the value of that field
// is set to the parsed value.
- bool ParseOptionAssignment(Message* options);
+ bool ParseOptionAssignment(Message* options,
+ const LocationRecorder& options_location);
// Parses a single part of a multipart option name. A multipart name consists
// of names separated by dots. Each name is either an identifier or a series
// of identifiers separated by dots and enclosed in parentheses. E.g.,
// "foo.(bar.baz).qux".
- bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option);
+ bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
+ const LocationRecorder& part_location);
+
+ // Parses a string surrounded by balanced braces. Strips off the outer
+ // braces and stores the enclosed string in *value.
+ // E.g.,
+ // { foo } *value gets 'foo'
+ // { foo { bar: box } } *value gets 'foo { bar: box }'
+ // {} *value gets ''
+ //
+ // REQUIRES: LookingAt("{")
+ // When finished successfully, we are looking at the first token past
+ // the ending brace.
+ bool ParseUninterpretedBlock(string* value);
// =================================================================
io::Tokenizer* input_;
io::ErrorCollector* error_collector_;
- SourceLocationTable* source_location_table_;
+ SourceCodeInfo* source_code_info_;
+ SourceLocationTable* source_location_table_; // legacy
bool had_errors_;
bool require_syntax_identifier_;
bool stop_after_syntax_identifier_;
@@ -302,6 +393,11 @@ class LIBPROTOBUF_EXPORT Parser {
// A table mapping (descriptor, ErrorLocation) pairs -- as reported by
// DescriptorPool when validating descriptors -- to line and column numbers
// within the original source code.
+//
+// This is semi-obsolete: FileDescriptorProto.source_code_info now contains
+// far more complete information about source locations. However, as of this
+// writing you still need to use SourceLocationTable when integrating with
+// DescriptorPool.
class LIBPROTOBUF_EXPORT SourceLocationTable {
public:
SourceLocationTable();
diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc
index e2262b8b..156c0dc3 100644
--- a/src/google/protobuf/compiler/parser_unittest.cc
+++ b/src/google/protobuf/compiler/parser_unittest.cc
@@ -34,6 +34,7 @@
#include <vector>
#include <algorithm>
+#include <map>
#include <google/protobuf/compiler/parser.h>
@@ -45,6 +46,7 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/map-util.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -118,6 +120,9 @@ class ParserTest : public testing::Test {
EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
ASSERT_EQ("", error_collector_.text_);
+ // We don't cover SourceCodeInfo in these tests.
+ actual.clear_source_code_info();
+
// Parse the ASCII representation in order to canonicalize it. We could
// just compare directly to actual.DebugString(), but that would require
// that the caller precisely match the formatting that DebugString()
@@ -930,6 +935,12 @@ TEST_F(ParseErrorTest, MultipleParseErrors) {
"3:25: Expected \";\".\n");
}
+TEST_F(ParseErrorTest, EofInAggregateValue) {
+ ExpectHasErrors(
+ "option (fileopt) = { i:100\n",
+ "1:0: Unexpected end of stream while parsing aggregate value.\n");
+}
+
// -------------------------------------------------------------------
// Enum errors
@@ -1248,6 +1259,861 @@ TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) {
}
// ===================================================================
+// SourceCodeInfo tests.
+
+// Follows a path -- as defined by SourceCodeInfo.Location.path -- from a
+// message to a particular sub-field.
+// * If the target is itself a message, sets *output_message to point at it,
+// *output_field to NULL, and *output_index to -1.
+// * Otherwise, if the target is an element of a repeated field, sets
+// *output_message to the containing message, *output_field to the descriptor
+// of the field, and *output_index to the index of the element.
+// * Otherwise, the target is a field (possibly a repeated field, but not any
+// one element). Sets *output_message to the containing message,
+// *output_field to the descriptor of the field, and *output_index to -1.
+// Returns true if the path was valid, false otherwise. A gTest failure is
+// recorded before returning false.
+bool FollowPath(const Message& root,
+ const int* path_begin, const int* path_end,
+ const Message** output_message,
+ const FieldDescriptor** output_field,
+ int* output_index) {
+ if (path_begin == path_end) {
+ // Path refers to this whole message.
+ *output_message = &root;
+ *output_field = NULL;
+ *output_index = -1;
+ return true;
+ }
+
+ const Descriptor* descriptor = root.GetDescriptor();
+ const Reflection* reflection = root.GetReflection();
+
+ const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin);
+
+ if (field == NULL) {
+ ADD_FAILURE() << descriptor->name() << " has no field number: "
+ << *path_begin;
+ return false;
+ }
+
+ ++path_begin;
+
+ if (field->is_repeated()) {
+ if (path_begin == path_end) {
+ // Path refers to the whole repeated field.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = -1;
+ return true;
+ }
+
+ int index = *path_begin++;
+ int size = reflection->FieldSize(root, field);
+
+ if (index >= size) {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " has size " << size << ", but path contained index: "
+ << index;
+ return false;
+ }
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Descend into child message.
+ const Message& child = reflection->GetRepeatedMessage(root, field, index);
+ return FollowPath(child, path_begin, path_end,
+ output_message, output_field, output_index);
+ } else if (path_begin == path_end) {
+ // Path refers to this element.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = index;
+ return true;
+ } else {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " is not a message; cannot descend into it.";
+ return false;
+ }
+ } else {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ const Message& child = reflection->GetMessage(root, field);
+ return FollowPath(child, path_begin, path_end,
+ output_message, output_field, output_index);
+ } else if (path_begin == path_end) {
+ // Path refers to this field.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = -1;
+ return true;
+ } else {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " is not a message; cannot descend into it.";
+ return false;
+ }
+ }
+}
+
+// Split some text on line breaks. The line breaks are retained in the output,
+// so each line (except the last) ends with a '\n', and the lines can be
+// concatenated to produce the original text.
+//
+// I couldn't find the proper string utility function for this. Our
+// split-on-delimiter functions don't include the delimiter in the output.
+void SplitLines(const string& text, vector<string>* lines) {
+ string::size_type pos = 0;
+
+ while (pos != string::npos) {
+ string::size_type last_pos = pos;
+ pos = text.find_first_of('\n', pos);
+ if (pos != string::npos) ++pos;
+ lines->push_back(text.substr(last_pos, pos - last_pos));
+ }
+}
+
+// Look for the given tags in the given text and construct a span (as defined
+// by SourceCodeInfo.Location.span) from them. E.g. for text like:
+// /*a*/message /*b*/Foo/*c*/ {}/*d*/
+// There are four tags: "a", "b", "c", and "d". The constructed span starts
+// immediately after the start tag's trailing '/' and ends immediately before
+// the end tags leading '/'.
+void MakeExpectedSpan(const vector<string>& lines,
+ const string& start_tag, const string& end_tag,
+ RepeatedField<int>* output) {
+ string start_comment = "/*" + start_tag + "*/";
+ string end_comment = "/*" + end_tag + "*/";
+
+ int start_line = -1;
+ int start_column = -1;
+ for (int i = 0; i < lines.size(); i++) {
+ string::size_type pos = lines[i].find(start_comment);
+ if (pos != string::npos) {
+ start_line = i;
+ start_column = pos + start_comment.size();
+ break;
+ }
+ }
+ ASSERT_NE(start_line, -1)
+ << "Tag \"" << start_comment << "\" not found in text.";
+
+ int end_line = -1;
+ int end_column = -1;
+ for (int i = start_line; i < lines.size(); i++) {
+ string::size_type pos = lines[i].find(end_comment);
+ if (pos != string::npos) {
+ end_line = i;
+ end_column = pos;
+ break;
+ }
+ }
+ ASSERT_NE(end_line, -1)
+ << "Tag \"" << end_comment << "\" not found in text.";
+
+ output->Add(start_line);
+ output->Add(start_column);
+ if (end_line != start_line) output->Add(end_line);
+ output->Add(end_column);
+}
+
+// Check if two spans are equal.
+bool CompareSpans(const RepeatedField<int>& span1,
+ const RepeatedField<int>& span2) {
+ if (span1.size() != span2.size()) return false;
+ for (int i = 0; i < span1.size(); i++) {
+ if (span1.Get(i) != span2.Get(i)) return false;
+ }
+ return true;
+}
+
+// Test fixture for source info tests, which check that source locations are
+// recorded correctly in FileDescriptorProto.source_code_info.location.
+class SourceInfoTest : public ParserTest {
+ protected:
+ // The parsed file (initialized by Parse()).
+ FileDescriptorProto file_;
+
+ // Parse the given text as a .proto file and populate the spans_ map with
+ // all the source location spans in its SourceCodeInfo table.
+ bool Parse(const char* text) {
+ SetupParser(text);
+ SplitLines(text, &lines_);
+ if (!parser_->Parse(input_.get(), &file_)) {
+ return false;
+ }
+
+ const SourceCodeInfo& source_info = file_.source_code_info();
+ for (int i = 0; i < source_info.location_size(); i++) {
+ const SourceCodeInfo::Location& location = source_info.location(i);
+ const Message* descriptor_proto = NULL;
+ const FieldDescriptor* field = NULL;
+ int index = 0;
+ if (!FollowPath(file_, location.path().begin(), location.path().end(),
+ &descriptor_proto, &field, &index)) {
+ return false;
+ }
+
+ spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index),
+ &location));
+ }
+
+ return true;
+ }
+
+ virtual void TearDown() {
+ EXPECT_TRUE(spans_.empty())
+ << "Forgot to call HasSpan() for:\n"
+ << spans_.begin()->second->DebugString();
+ }
+
+ // -----------------------------------------------------------------
+ // HasSpan() checks that the span of source code delimited by the given
+ // tags (comments) correspond via the SourceCodeInfo table to the given
+ // part of the FileDescriptorProto. (If unclear, look at the actual tests;
+ // it should quickly become obvious.)
+
+ bool HasSpan(const char* start_tag, const char* end_tag,
+ const Message& descriptor_proto) {
+ return HasSpan(start_tag, end_tag, descriptor_proto, NULL, -1);
+ }
+
+ bool HasSpan(const char* start_tag, const char* end_tag,
+ const Message& descriptor_proto, const string& field_name) {
+ return HasSpan(start_tag, end_tag, descriptor_proto, field_name, -1);
+ }
+
+ bool HasSpan(const char* start_tag, const char* end_tag,
+ const Message& descriptor_proto, const string& field_name,
+ int index) {
+ const FieldDescriptor* field =
+ descriptor_proto.GetDescriptor()->FindFieldByName(field_name);
+ if (field == NULL) {
+ ADD_FAILURE() << descriptor_proto.GetDescriptor()->name()
+ << " has no such field: " << field_name;
+ return false;
+ }
+
+ return HasSpan(start_tag, end_tag, descriptor_proto, field, index);
+ }
+
+ bool HasSpan(const Message& descriptor_proto) {
+ return HasSpan(NULL, NULL, descriptor_proto, NULL, -1);
+ }
+
+ bool HasSpan(const Message& descriptor_proto, const string& field_name) {
+ return HasSpan(NULL, NULL, descriptor_proto, field_name, -1);
+ }
+
+ bool HasSpan(const Message& descriptor_proto, const string& field_name,
+ int index) {
+ return HasSpan(NULL, NULL, descriptor_proto, field_name, index);
+ }
+
+ bool HasSpan(const char* start_tag, const char* end_tag,
+ const Message& descriptor_proto, const FieldDescriptor* field,
+ int index) {
+ pair<SpanMap::iterator, SpanMap::iterator> range =
+ spans_.equal_range(SpanKey(descriptor_proto, field, index));
+
+ if (start_tag == NULL) {
+ if (range.first == range.second) {
+ return false;
+ } else {
+ spans_.erase(range.first);
+ return true;
+ }
+ } else {
+ RepeatedField<int> expected_span;
+ MakeExpectedSpan(lines_, start_tag, end_tag, &expected_span);
+
+ for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) {
+ if (CompareSpans(expected_span, iter->second->span())) {
+ spans_.erase(iter);
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ private:
+ struct SpanKey {
+ const Message* descriptor_proto;
+ const FieldDescriptor* field;
+ int index;
+
+ inline SpanKey() {}
+ inline SpanKey(const Message& descriptor_proto,
+ const FieldDescriptor* field,
+ int index)
+ : descriptor_proto(&descriptor_proto), field(field), index(index) {}
+
+ inline bool operator<(const SpanKey& other) const {
+ if (descriptor_proto < other.descriptor_proto) return true;
+ if (descriptor_proto > other.descriptor_proto) return false;
+ if (field < other.field) return true;
+ if (field > other.field) return false;
+ return index < other.index;
+ }
+ };
+
+ typedef multimap<SpanKey, const SourceCodeInfo::Location*> SpanMap;
+ SpanMap spans_;
+ vector<string> lines_;
+};
+
+TEST_F(SourceInfoTest, BasicFileDecls) {
+ EXPECT_TRUE(Parse(
+ "/*a*/syntax = \"proto2\";\n"
+ "package /*b*/foo.bar/*c*/;\n"
+ "import /*d*/\"baz.proto\"/*e*/;\n"
+ "import /*f*/\"qux.proto\"/*g*/;/*h*/\n"
+ "// comment ignored\n"));
+
+ EXPECT_TRUE(HasSpan("a", "h", file_));
+ EXPECT_TRUE(HasSpan("b", "c", file_, "package"));
+ EXPECT_TRUE(HasSpan("d", "e", file_, "dependency", 0));
+ EXPECT_TRUE(HasSpan("f", "g", file_, "dependency", 1));
+}
+
+TEST_F(SourceInfoTest, Messages) {
+ EXPECT_TRUE(Parse(
+ "/*a*/message /*b*/Foo/*c*/ {}/*d*/\n"
+ "/*e*/message /*f*/Bar/*g*/ {}/*h*/\n"));
+
+ EXPECT_TRUE(HasSpan("a", "d", file_.message_type(0)));
+ EXPECT_TRUE(HasSpan("b", "c", file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan("e", "h", file_.message_type(1)));
+ EXPECT_TRUE(HasSpan("f", "g", file_.message_type(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, Fields) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " /*a*/optional/*b*/ /*c*/int32/*d*/ /*e*/bar/*f*/ = /*g*/1/*h*/;/*i*/\n"
+ " /*j*/repeated/*k*/ /*l*/X.Y/*m*/ /*n*/baz/*o*/ = /*p*/2/*q*/;/*r*/\n"
+ "}\n"));
+
+ const FieldDescriptorProto& field1 = file_.message_type(0).field(0);
+ const FieldDescriptorProto& field2 = file_.message_type(0).field(1);
+
+ EXPECT_TRUE(HasSpan("a", "i", field1));
+ EXPECT_TRUE(HasSpan("a", "b", field1, "label"));
+ EXPECT_TRUE(HasSpan("c", "d", field1, "type"));
+ EXPECT_TRUE(HasSpan("e", "f", field1, "name"));
+ EXPECT_TRUE(HasSpan("g", "h", field1, "number"));
+
+ EXPECT_TRUE(HasSpan("j", "r", field2));
+ EXPECT_TRUE(HasSpan("j", "k", field2, "label"));
+ EXPECT_TRUE(HasSpan("l", "m", field2, "type_name"));
+ EXPECT_TRUE(HasSpan("n", "o", field2, "name"));
+ EXPECT_TRUE(HasSpan("p", "q", field2, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Extensions) {
+ EXPECT_TRUE(Parse(
+ "/*a*/extend /*b*/Foo/*c*/ {\n"
+ " /*d*/optional/*e*/ int32 bar = 1;/*f*/\n"
+ " /*g*/repeated/*h*/ X.Y baz = 2;/*i*/\n"
+ "}/*j*/\n"
+ "/*k*/extend /*l*/Bar/*m*/ {\n"
+ " /*n*/optional int32 qux = 1;/*o*/\n"
+ "}/*p*/\n"));
+
+ const FieldDescriptorProto& field1 = file_.extension(0);
+ const FieldDescriptorProto& field2 = file_.extension(1);
+ const FieldDescriptorProto& field3 = file_.extension(2);
+
+ EXPECT_TRUE(HasSpan("a", "j", file_, "extension"));
+ EXPECT_TRUE(HasSpan("k", "p", file_, "extension"));
+
+ EXPECT_TRUE(HasSpan("d", "f", field1));
+ EXPECT_TRUE(HasSpan("d", "e", field1, "label"));
+ EXPECT_TRUE(HasSpan("b", "c", field1, "extendee"));
+
+ EXPECT_TRUE(HasSpan("g", "i", field2));
+ EXPECT_TRUE(HasSpan("g", "h", field2, "label"));
+ EXPECT_TRUE(HasSpan("b", "c", field2, "extendee"));
+
+ EXPECT_TRUE(HasSpan("n", "o", field3));
+ EXPECT_TRUE(HasSpan("l", "m", field3, "extendee"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(field1, "type"));
+ EXPECT_TRUE(HasSpan(field1, "name"));
+ EXPECT_TRUE(HasSpan(field1, "number"));
+ EXPECT_TRUE(HasSpan(field2, "type_name"));
+ EXPECT_TRUE(HasSpan(field2, "name"));
+ EXPECT_TRUE(HasSpan(field2, "number"));
+ EXPECT_TRUE(HasSpan(field3, "label"));
+ EXPECT_TRUE(HasSpan(field3, "type"));
+ EXPECT_TRUE(HasSpan(field3, "name"));
+ EXPECT_TRUE(HasSpan(field3, "number"));
+}
+
+TEST_F(SourceInfoTest, NestedExtensions) {
+ EXPECT_TRUE(Parse(
+ "message Message {\n"
+ " /*a*/extend /*b*/Foo/*c*/ {\n"
+ " /*d*/optional/*e*/ int32 bar = 1;/*f*/\n"
+ " /*g*/repeated/*h*/ X.Y baz = 2;/*i*/\n"
+ " }/*j*/\n"
+ " /*k*/extend /*l*/Bar/*m*/ {\n"
+ " /*n*/optional int32 qux = 1;/*o*/\n"
+ " }/*p*/\n"
+ "}\n"));
+
+ const FieldDescriptorProto& field1 = file_.message_type(0).extension(0);
+ const FieldDescriptorProto& field2 = file_.message_type(0).extension(1);
+ const FieldDescriptorProto& field3 = file_.message_type(0).extension(2);
+
+ EXPECT_TRUE(HasSpan("a", "j", file_.message_type(0), "extension"));
+ EXPECT_TRUE(HasSpan("k", "p", file_.message_type(0), "extension"));
+
+ EXPECT_TRUE(HasSpan("d", "f", field1));
+ EXPECT_TRUE(HasSpan("d", "e", field1, "label"));
+ EXPECT_TRUE(HasSpan("b", "c", field1, "extendee"));
+
+ EXPECT_TRUE(HasSpan("g", "i", field2));
+ EXPECT_TRUE(HasSpan("g", "h", field2, "label"));
+ EXPECT_TRUE(HasSpan("b", "c", field2, "extendee"));
+
+ EXPECT_TRUE(HasSpan("n", "o", field3));
+ EXPECT_TRUE(HasSpan("l", "m", field3, "extendee"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(field1, "type"));
+ EXPECT_TRUE(HasSpan(field1, "name"));
+ EXPECT_TRUE(HasSpan(field1, "number"));
+ EXPECT_TRUE(HasSpan(field2, "type_name"));
+ EXPECT_TRUE(HasSpan(field2, "name"));
+ EXPECT_TRUE(HasSpan(field2, "number"));
+ EXPECT_TRUE(HasSpan(field3, "label"));
+ EXPECT_TRUE(HasSpan(field3, "type"));
+ EXPECT_TRUE(HasSpan(field3, "name"));
+ EXPECT_TRUE(HasSpan(field3, "number"));
+}
+
+TEST_F(SourceInfoTest, ExtensionRanges) {
+ EXPECT_TRUE(Parse(
+ "message Message {\n"
+ " /*a*/extensions /*b*/1/*c*/ to /*d*/4/*e*/, /*f*/6/*g*/;/*h*/\n"
+ " /*i*/extensions /*j*/8/*k*/ to /*l*/max/*m*/;/*n*/\n"
+ "}\n"));
+
+ const DescriptorProto::ExtensionRange& range1 =
+ file_.message_type(0).extension_range(0);
+ const DescriptorProto::ExtensionRange& range2 =
+ file_.message_type(0).extension_range(1);
+ const DescriptorProto::ExtensionRange& range3 =
+ file_.message_type(0).extension_range(2);
+
+ EXPECT_TRUE(HasSpan("a", "h", file_.message_type(0), "extension_range"));
+ EXPECT_TRUE(HasSpan("i", "n", file_.message_type(0), "extension_range"));
+
+ EXPECT_TRUE(HasSpan("b", "e", range1));
+ EXPECT_TRUE(HasSpan("b", "c", range1, "start"));
+ EXPECT_TRUE(HasSpan("d", "e", range1, "end"));
+
+ EXPECT_TRUE(HasSpan("f", "g", range2));
+ EXPECT_TRUE(HasSpan("f", "g", range2, "start"));
+ EXPECT_TRUE(HasSpan("f", "g", range2, "end"));
+
+ EXPECT_TRUE(HasSpan("j", "m", range3));
+ EXPECT_TRUE(HasSpan("j", "k", range3, "start"));
+ EXPECT_TRUE(HasSpan("l", "m", range3, "end"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, NestedMessages) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " /*a*/message /*b*/Bar/*c*/ {\n"
+ " /*d*/message /*e*/Baz/*f*/ {}/*g*/\n"
+ " }/*h*/\n"
+ " /*i*/message /*j*/Qux/*k*/ {}/*l*/\n"
+ "}\n"));
+
+ const DescriptorProto& bar = file_.message_type(0).nested_type(0);
+ const DescriptorProto& baz = bar.nested_type(0);
+ const DescriptorProto& qux = file_.message_type(0).nested_type(1);
+
+ EXPECT_TRUE(HasSpan("a", "h", bar));
+ EXPECT_TRUE(HasSpan("b", "c", bar, "name"));
+ EXPECT_TRUE(HasSpan("d", "g", baz));
+ EXPECT_TRUE(HasSpan("e", "f", baz, "name"));
+ EXPECT_TRUE(HasSpan("i", "l", qux));
+ EXPECT_TRUE(HasSpan("j", "k", qux, "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Groups) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " message Bar {}\n"
+ " /*a*/optional/*b*/ /*c*/group/*d*/ /*e*/Baz/*f*/ = /*g*/1/*h*/ {\n"
+ " /*i*/message Qux {}/*j*/\n"
+ " }/*k*/\n"
+ "}\n"));
+
+ const DescriptorProto& bar = file_.message_type(0).nested_type(0);
+ const DescriptorProto& baz = file_.message_type(0).nested_type(1);
+ const DescriptorProto& qux = baz.nested_type(0);
+ const FieldDescriptorProto& field = file_.message_type(0).field(0);
+
+ EXPECT_TRUE(HasSpan("a", "k", field));
+ EXPECT_TRUE(HasSpan("a", "b", field, "label"));
+ EXPECT_TRUE(HasSpan("c", "d", field, "type"));
+ EXPECT_TRUE(HasSpan("e", "f", field, "name"));
+ EXPECT_TRUE(HasSpan("e", "f", field, "type_name"));
+ EXPECT_TRUE(HasSpan("g", "h", field, "number"));
+
+ EXPECT_TRUE(HasSpan("a", "k", baz));
+ EXPECT_TRUE(HasSpan("e", "f", baz, "name"));
+ EXPECT_TRUE(HasSpan("i", "j", qux));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(bar));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(qux, "name"));
+}
+
+TEST_F(SourceInfoTest, Enums) {
+ EXPECT_TRUE(Parse(
+ "/*a*/enum /*b*/Foo/*c*/ {}/*d*/\n"
+ "/*e*/enum /*f*/Bar/*g*/ {}/*h*/\n"));
+
+ EXPECT_TRUE(HasSpan("a", "d", file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan("b", "c", file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan("e", "h", file_.enum_type(1)));
+ EXPECT_TRUE(HasSpan("f", "g", file_.enum_type(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, EnumValues) {
+ EXPECT_TRUE(Parse(
+ "enum Foo {\n"
+ " /*a*/BAR/*b*/ = /*c*/1/*d*/;/*e*/\n"
+ " /*f*/BAZ/*g*/ = /*h*/2/*i*/;/*j*/\n"
+ "}"));
+
+ const EnumValueDescriptorProto& bar = file_.enum_type(0).value(0);
+ const EnumValueDescriptorProto& baz = file_.enum_type(0).value(1);
+
+ EXPECT_TRUE(HasSpan("a", "e", bar));
+ EXPECT_TRUE(HasSpan("a", "b", bar, "name"));
+ EXPECT_TRUE(HasSpan("c", "d", bar, "number"));
+ EXPECT_TRUE(HasSpan("f", "j", baz));
+ EXPECT_TRUE(HasSpan("f", "g", baz, "name"));
+ EXPECT_TRUE(HasSpan("h", "i", baz, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, NestedEnums) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " /*a*/enum /*b*/Bar/*c*/ {}/*d*/\n"
+ " /*e*/enum /*f*/Baz/*g*/ {}/*h*/\n"
+ "}\n"));
+
+ const EnumDescriptorProto& bar = file_.message_type(0).enum_type(0);
+ const EnumDescriptorProto& baz = file_.message_type(0).enum_type(1);
+
+ EXPECT_TRUE(HasSpan("a", "d", bar));
+ EXPECT_TRUE(HasSpan("b", "c", bar, "name"));
+ EXPECT_TRUE(HasSpan("e", "h", baz));
+ EXPECT_TRUE(HasSpan("f", "g", baz, "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Services) {
+ EXPECT_TRUE(Parse(
+ "/*a*/service /*b*/Foo/*c*/ {}/*d*/\n"
+ "/*e*/service /*f*/Bar/*g*/ {}/*h*/\n"));
+
+ EXPECT_TRUE(HasSpan("a", "d", file_.service(0)));
+ EXPECT_TRUE(HasSpan("b", "c", file_.service(0), "name"));
+ EXPECT_TRUE(HasSpan("e", "h", file_.service(1)));
+ EXPECT_TRUE(HasSpan("f", "g", file_.service(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, Methods) {
+ EXPECT_TRUE(Parse(
+ "service Foo {\n"
+ " /*a*/rpc /*b*/Bar/*c*/(/*d*/X/*e*/) returns(/*f*/Y/*g*/);/*h*/"
+ " /*i*/rpc /*j*/Baz/*k*/(/*l*/Z/*m*/) returns(/*n*/W/*o*/);/*p*/"
+ "}"));
+
+ const MethodDescriptorProto& bar = file_.service(0).method(0);
+ const MethodDescriptorProto& baz = file_.service(0).method(1);
+
+ EXPECT_TRUE(HasSpan("a", "h", bar));
+ EXPECT_TRUE(HasSpan("b", "c", bar, "name"));
+ EXPECT_TRUE(HasSpan("d", "e", bar, "input_type"));
+ EXPECT_TRUE(HasSpan("f", "g", bar, "output_type"));
+
+ EXPECT_TRUE(HasSpan("i", "p", baz));
+ EXPECT_TRUE(HasSpan("j", "k", baz, "name"));
+ EXPECT_TRUE(HasSpan("l", "m", baz, "input_type"));
+ EXPECT_TRUE(HasSpan("n", "o", baz, "output_type"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.service(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Options) {
+ EXPECT_TRUE(Parse(
+ "/*a*/option /*b*/foo/*c*/./*d*/(/*e*/bar.baz/*f*/)/*g*/ = "
+ "/*h*/123/*i*/;/*j*/\n"
+ "/*k*/option qux = /*l*/-123/*m*/;/*n*/\n"
+ "/*o*/option corge = /*p*/abc/*q*/;/*r*/\n"
+ "/*s*/option grault = /*t*/'blah'/*u*/;/*v*/\n"
+ "/*w*/option garply = /*x*/{ yadda yadda }/*y*/;/*z*/\n"
+ "/*0*/option waldo = /*1*/123.0/*2*/;/*3*/\n"
+ ));
+
+ const UninterpretedOption& option1 = file_.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = file_.options().uninterpreted_option(1);
+ const UninterpretedOption& option3 = file_.options().uninterpreted_option(2);
+ const UninterpretedOption& option4 = file_.options().uninterpreted_option(3);
+ const UninterpretedOption& option5 = file_.options().uninterpreted_option(4);
+ const UninterpretedOption& option6 = file_.options().uninterpreted_option(5);
+
+ EXPECT_TRUE(HasSpan("a", "j", file_.options()));
+ EXPECT_TRUE(HasSpan("b", "i", option1));
+ EXPECT_TRUE(HasSpan("b", "g", option1, "name"));
+ EXPECT_TRUE(HasSpan("b", "c", option1.name(0)));
+ EXPECT_TRUE(HasSpan("b", "c", option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan("d", "g", option1.name(1)));
+ EXPECT_TRUE(HasSpan("e", "f", option1.name(1), "name_part"));
+ EXPECT_TRUE(HasSpan("h", "i", option1, "positive_int_value"));
+
+ EXPECT_TRUE(HasSpan("k", "n", file_.options()));
+ EXPECT_TRUE(HasSpan("l", "m", option2, "negative_int_value"));
+
+ EXPECT_TRUE(HasSpan("o", "r", file_.options()));
+ EXPECT_TRUE(HasSpan("p", "q", option3, "identifier_value"));
+
+ EXPECT_TRUE(HasSpan("s", "v", file_.options()));
+ EXPECT_TRUE(HasSpan("t", "u", option4, "string_value"));
+
+ EXPECT_TRUE(HasSpan("w", "z", file_.options()));
+ EXPECT_TRUE(HasSpan("x", "y", option5, "aggregate_value"));
+
+ EXPECT_TRUE(HasSpan("0", "3", file_.options()));
+ EXPECT_TRUE(HasSpan("1", "2", option6, "double_value"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(option2));
+ EXPECT_TRUE(HasSpan(option3));
+ EXPECT_TRUE(HasSpan(option4));
+ EXPECT_TRUE(HasSpan(option5));
+ EXPECT_TRUE(HasSpan(option6));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option3, "name"));
+ EXPECT_TRUE(HasSpan(option4, "name"));
+ EXPECT_TRUE(HasSpan(option5, "name"));
+ EXPECT_TRUE(HasSpan(option6, "name"));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option3.name(0)));
+ EXPECT_TRUE(HasSpan(option4.name(0)));
+ EXPECT_TRUE(HasSpan(option5.name(0)));
+ EXPECT_TRUE(HasSpan(option6.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option3.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option4.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option5.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option6.name(0), "name_part"));
+}
+
+TEST_F(SourceInfoTest, ScopedOptions) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " /*a*/option mopt = 1;/*b*/\n"
+ "}\n"
+ "enum Bar {\n"
+ " /*c*/option eopt = 1;/*d*/\n"
+ "}\n"
+ "service Baz {\n"
+ " /*e*/option sopt = 1;/*f*/\n"
+ " rpc M(X) returns(Y) {\n"
+ " /*g*/option mopt = 1;/*h*/\n"
+ " }\n"
+ "}\n"));
+
+ EXPECT_TRUE(HasSpan("a", "b", file_.message_type(0).options()));
+ EXPECT_TRUE(HasSpan("c", "d", file_.enum_type(0).options()));
+ EXPECT_TRUE(HasSpan("e", "f", file_.service(0).options()));
+ EXPECT_TRUE(HasSpan("g", "h", file_.service(0).method(0).options()));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.service(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "input_type"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "output_type"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+}
+
+TEST_F(SourceInfoTest, FieldOptions) {
+ // The actual "name = value" pairs are parsed by the same code as for
+ // top-level options so we won't re-test that -- just make sure that the
+ // syntax used for field options is understood.
+ EXPECT_TRUE(Parse(
+ "message Foo {"
+ " optional int32 bar = 1 "
+ "/*a*/[default=/*b*/123/*c*/,/*d*/opt1=123/*e*/,"
+ "/*f*/opt2='hi'/*g*/]/*h*/;"
+ "}\n"
+ ));
+
+ const FieldDescriptorProto& field = file_.message_type(0).field(0);
+ const UninterpretedOption& option1 = field.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = field.options().uninterpreted_option(1);
+
+ EXPECT_TRUE(HasSpan("a", "h", field.options()));
+ EXPECT_TRUE(HasSpan("b", "c", field, "default_value"));
+ EXPECT_TRUE(HasSpan("d", "e", option1));
+ EXPECT_TRUE(HasSpan("f", "g", option2));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(field));
+ EXPECT_TRUE(HasSpan(field, "label"));
+ EXPECT_TRUE(HasSpan(field, "type"));
+ EXPECT_TRUE(HasSpan(field, "name"));
+ EXPECT_TRUE(HasSpan(field, "number"));
+ EXPECT_TRUE(HasSpan(option1, "name"));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option1.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
+ EXPECT_TRUE(HasSpan(option2, "string_value"));
+}
+
+TEST_F(SourceInfoTest, EnumValueOptions) {
+ // The actual "name = value" pairs are parsed by the same code as for
+ // top-level options so we won't re-test that -- just make sure that the
+ // syntax used for enum options is understood.
+ EXPECT_TRUE(Parse(
+ "enum Foo {"
+ " BAR = 1 /*a*/[/*b*/opt1=123/*c*/,/*d*/opt2='hi'/*e*/]/*f*/;"
+ "}\n"
+ ));
+
+ const EnumValueDescriptorProto& value = file_.enum_type(0).value(0);
+ const UninterpretedOption& option1 = value.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = value.options().uninterpreted_option(1);
+
+ EXPECT_TRUE(HasSpan("a", "f", value.options()));
+ EXPECT_TRUE(HasSpan("b", "c", option1));
+ EXPECT_TRUE(HasSpan("d", "e", option2));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan(value));
+ EXPECT_TRUE(HasSpan(value, "name"));
+ EXPECT_TRUE(HasSpan(value, "number"));
+ EXPECT_TRUE(HasSpan(option1, "name"));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option1.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
+ EXPECT_TRUE(HasSpan(option2, "string_value"));
+}
+
+// ===================================================================
} // anonymous namespace
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc
index a4aedafb..727f9421 100644
--- a/src/google/protobuf/compiler/plugin.cc
+++ b/src/google/protobuf/compiler/plugin.cc
@@ -59,13 +59,15 @@ namespace google {
namespace protobuf {
namespace compiler {
-class GeneratorResponseOutputDirectory : public OutputDirectory {
+class GeneratorResponseContext : public GeneratorContext {
public:
- GeneratorResponseOutputDirectory(CodeGeneratorResponse* response)
- : response_(response) {}
- virtual ~GeneratorResponseOutputDirectory() {}
+ GeneratorResponseContext(CodeGeneratorResponse* response,
+ const vector<const FileDescriptor*>& parsed_files)
+ : response_(response),
+ parsed_files_(parsed_files) {}
+ virtual ~GeneratorResponseContext() {}
- // implements OutputDirectory --------------------------------------
+ // implements GeneratorContext --------------------------------------
virtual io::ZeroCopyOutputStream* Open(const string& filename) {
CodeGeneratorResponse::File* file = response_->add_file();
@@ -81,8 +83,13 @@ class GeneratorResponseOutputDirectory : public OutputDirectory {
return new io::StringOutputStream(file->mutable_content());
}
+ void ListParsedFiles(vector<const FileDescriptor*>* output) {
+ *output = parsed_files_;
+ }
+
private:
CodeGeneratorResponse* response_;
+ const vector<const FileDescriptor*>& parsed_files_;
};
int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
@@ -112,22 +119,26 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
}
}
- CodeGeneratorResponse response;
- GeneratorResponseOutputDirectory output_directory(&response);
-
+ vector<const FileDescriptor*> parsed_files;
for (int i = 0; i < request.file_to_generate_size(); i++) {
- const FileDescriptor* file =
- pool.FindFileByName(request.file_to_generate(i));
- if (file == NULL) {
+ parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i)));
+ if (parsed_files.back() == NULL) {
cerr << argv[0] << ": protoc asked plugin to generate a file but "
"did not provide a descriptor for the file: "
<< request.file_to_generate(i) << endl;
return 1;
}
+ }
+
+ CodeGeneratorResponse response;
+ GeneratorResponseContext context(&response, parsed_files);
+
+ for (int i = 0; i < parsed_files.size(); i++) {
+ const FileDescriptor* file = parsed_files[i];
string error;
bool succeeded = generator->Generate(
- file, request.parameter(), &output_directory, &error);
+ file, request.parameter(), &context, &error);
if (!succeeded && error.empty()) {
error = "Code generator returned false but provided no error "
diff --git a/src/google/protobuf/compiler/plugin.h b/src/google/protobuf/compiler/plugin.h
index 7c403332..64dfb1d2 100644
--- a/src/google/protobuf/compiler/plugin.h
+++ b/src/google/protobuf/compiler/plugin.h
@@ -64,7 +64,7 @@ namespace compiler {
class CodeGenerator; // code_generator.h
// Implements main() for a protoc plugin exposing the given code generator.
-LIBPROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator);
+int PluginMain(int argc, char* argv[], const CodeGenerator* generator);
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 13d35c68..ad4b4deb 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -158,7 +158,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto
// ===================================================================
-const ::std::string CodeGeneratorRequest::_default_parameter_;
#ifndef _MSC_VER
const int CodeGeneratorRequest::kFileToGenerateFieldNumber;
const int CodeGeneratorRequest::kParameterFieldNumber;
@@ -181,7 +180,7 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from)
void CodeGeneratorRequest::SharedCtor() {
_cached_size_ = 0;
- parameter_ = const_cast< ::std::string*>(&_default_parameter_);
+ parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -190,7 +189,7 @@ CodeGeneratorRequest::~CodeGeneratorRequest() {
}
void CodeGeneratorRequest::SharedDtor() {
- if (parameter_ != &_default_parameter_) {
+ if (parameter_ != &::google::protobuf::internal::kEmptyString) {
delete parameter_;
}
if (this != default_instance_) {
@@ -219,8 +218,8 @@ CodeGeneratorRequest* CodeGeneratorRequest::New() const {
void CodeGeneratorRequest::Clear() {
if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
- if (_has_bit(1)) {
- if (parameter_ != &_default_parameter_) {
+ if (has_parameter()) {
+ if (parameter_ != &::google::protobuf::internal::kEmptyString) {
parameter_->clear();
}
}
@@ -315,7 +314,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes(
}
// optional string parameter = 2;
- if (_has_bit(1)) {
+ if (has_parameter()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->parameter().data(), this->parameter().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -347,7 +346,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes(
}
// optional string parameter = 2;
- if (_has_bit(1)) {
+ if (has_parameter()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->parameter().data(), this->parameter().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -425,7 +424,7 @@ void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
file_to_generate_.MergeFrom(from.file_to_generate_);
proto_file_.MergeFrom(from.proto_file_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
- if (from._has_bit(1)) {
+ if (from.has_parameter()) {
set_parameter(from.parameter());
}
}
@@ -474,9 +473,6 @@ void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) {
// ===================================================================
-const ::std::string CodeGeneratorResponse_File::_default_name_;
-const ::std::string CodeGeneratorResponse_File::_default_insertion_point_;
-const ::std::string CodeGeneratorResponse_File::_default_content_;
#ifndef _MSC_VER
const int CodeGeneratorResponse_File::kNameFieldNumber;
const int CodeGeneratorResponse_File::kInsertionPointFieldNumber;
@@ -499,9 +495,9 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon
void CodeGeneratorResponse_File::SharedCtor() {
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
- insertion_point_ = const_cast< ::std::string*>(&_default_insertion_point_);
- content_ = const_cast< ::std::string*>(&_default_content_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ content_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -510,13 +506,13 @@ CodeGeneratorResponse_File::~CodeGeneratorResponse_File() {
}
void CodeGeneratorResponse_File::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
delete name_;
}
- if (insertion_point_ != &_default_insertion_point_) {
+ if (insertion_point_ != &::google::protobuf::internal::kEmptyString) {
delete insertion_point_;
}
- if (content_ != &_default_content_) {
+ if (content_ != &::google::protobuf::internal::kEmptyString) {
delete content_;
}
if (this != default_instance_) {
@@ -545,18 +541,18 @@ CodeGeneratorResponse_File* CodeGeneratorResponse_File::New() const {
void CodeGeneratorResponse_File::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
}
- if (_has_bit(1)) {
- if (insertion_point_ != &_default_insertion_point_) {
+ if (has_insertion_point()) {
+ if (insertion_point_ != &::google::protobuf::internal::kEmptyString) {
insertion_point_->clear();
}
}
- if (_has_bit(2)) {
- if (content_ != &_default_content_) {
+ if (has_content()) {
+ if (content_ != &::google::protobuf::internal::kEmptyString) {
content_->clear();
}
}
@@ -640,7 +636,7 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream(
void CodeGeneratorResponse_File::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -649,7 +645,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes(
}
// optional string insertion_point = 2;
- if (_has_bit(1)) {
+ if (has_insertion_point()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->insertion_point().data(), this->insertion_point().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -658,7 +654,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes(
}
// optional string content = 15;
- if (_has_bit(2)) {
+ if (has_content()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->content().data(), this->content().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -675,7 +671,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes(
::google::protobuf::uint8* CodeGeneratorResponse_File::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -685,7 +681,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes(
}
// optional string insertion_point = 2;
- if (_has_bit(1)) {
+ if (has_insertion_point()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->insertion_point().data(), this->insertion_point().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -695,7 +691,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes(
}
// optional string content = 15;
- if (_has_bit(2)) {
+ if (has_content()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->content().data(), this->content().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -763,13 +759,13 @@ void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& fr
void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(1)) {
+ if (from.has_insertion_point()) {
set_insertion_point(from.insertion_point());
}
- if (from._has_bit(2)) {
+ if (from.has_content()) {
set_content(from.content());
}
}
@@ -815,7 +811,6 @@ void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) {
// -------------------------------------------------------------------
-const ::std::string CodeGeneratorResponse::_default_error_;
#ifndef _MSC_VER
const int CodeGeneratorResponse::kErrorFieldNumber;
const int CodeGeneratorResponse::kFileFieldNumber;
@@ -837,7 +832,7 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from)
void CodeGeneratorResponse::SharedCtor() {
_cached_size_ = 0;
- error_ = const_cast< ::std::string*>(&_default_error_);
+ error_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -846,7 +841,7 @@ CodeGeneratorResponse::~CodeGeneratorResponse() {
}
void CodeGeneratorResponse::SharedDtor() {
- if (error_ != &_default_error_) {
+ if (error_ != &::google::protobuf::internal::kEmptyString) {
delete error_;
}
if (this != default_instance_) {
@@ -875,8 +870,8 @@ CodeGeneratorResponse* CodeGeneratorResponse::New() const {
void CodeGeneratorResponse::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (error_ != &_default_error_) {
+ if (has_error()) {
+ if (error_ != &::google::protobuf::internal::kEmptyString) {
error_->clear();
}
}
@@ -942,7 +937,7 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream(
void CodeGeneratorResponse::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional string error = 1;
- if (_has_bit(0)) {
+ if (has_error()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->error().data(), this->error().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -965,7 +960,7 @@ void CodeGeneratorResponse::SerializeWithCachedSizes(
::google::protobuf::uint8* CodeGeneratorResponse::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional string error = 1;
- if (_has_bit(0)) {
+ if (has_error()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->error().data(), this->error().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -1035,7 +1030,7 @@ void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
GOOGLE_CHECK_NE(&from, this);
file_.MergeFrom(from.file_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_error()) {
set_error(from.error());
}
}
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index bd6bf63c..c307bfd4 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -120,6 +120,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
inline void set_parameter(const char* value);
inline void set_parameter(const char* value, size_t size);
inline ::std::string* mutable_parameter();
+ inline ::std::string* release_parameter();
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
inline int proto_file_size() const;
@@ -135,29 +136,21 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
private:
+ inline void set_has_parameter();
+ inline void clear_has_parameter();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_;
::std::string* parameter_;
- static const ::std::string _default_parameter_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_;
- friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
void InitAsDefaultInstance();
static CodeGeneratorRequest* default_instance_;
@@ -227,6 +220,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
// optional string insertion_point = 2;
inline bool has_insertion_point() const;
@@ -237,6 +231,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline void set_insertion_point(const char* value);
inline void set_insertion_point(const char* value, size_t size);
inline ::std::string* mutable_insertion_point();
+ inline ::std::string* release_insertion_point();
// optional string content = 15;
inline bool has_content() const;
@@ -247,34 +242,29 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
inline void set_content(const char* value);
inline void set_content(const char* value, size_t size);
inline ::std::string* mutable_content();
+ inline ::std::string* release_content();
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_insertion_point();
+ inline void clear_has_insertion_point();
+ inline void set_has_content();
+ inline void clear_has_content();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* name_;
- static const ::std::string _default_name_;
::std::string* insertion_point_;
- static const ::std::string _default_insertion_point_;
::std::string* content_;
- static const ::std::string _default_content_;
- friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
void InitAsDefaultInstance();
static CodeGeneratorResponse_File* default_instance_;
@@ -346,6 +336,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
inline void set_error(const char* value);
inline void set_error(const char* value, size_t size);
inline ::std::string* mutable_error();
+ inline ::std::string* release_error();
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
inline int file_size() const;
@@ -361,28 +352,20 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
private:
+ inline void set_has_error();
+ inline void clear_has_error();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* error_;
- static const ::std::string _default_error_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_;
- friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
void InitAsDefaultInstance();
static CodeGeneratorResponse* default_instance_;
@@ -440,45 +423,61 @@ CodeGeneratorRequest::mutable_file_to_generate() {
// optional string parameter = 2;
inline bool CodeGeneratorRequest::has_parameter() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void CodeGeneratorRequest::set_has_parameter() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void CodeGeneratorRequest::clear_has_parameter() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void CodeGeneratorRequest::clear_parameter() {
- if (parameter_ != &_default_parameter_) {
+ if (parameter_ != &::google::protobuf::internal::kEmptyString) {
parameter_->clear();
}
- _clear_bit(1);
+ clear_has_parameter();
}
inline const ::std::string& CodeGeneratorRequest::parameter() const {
return *parameter_;
}
inline void CodeGeneratorRequest::set_parameter(const ::std::string& value) {
- _set_bit(1);
- if (parameter_ == &_default_parameter_) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::kEmptyString) {
parameter_ = new ::std::string;
}
parameter_->assign(value);
}
inline void CodeGeneratorRequest::set_parameter(const char* value) {
- _set_bit(1);
- if (parameter_ == &_default_parameter_) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::kEmptyString) {
parameter_ = new ::std::string;
}
parameter_->assign(value);
}
inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) {
- _set_bit(1);
- if (parameter_ == &_default_parameter_) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::kEmptyString) {
parameter_ = new ::std::string;
}
parameter_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* CodeGeneratorRequest::mutable_parameter() {
- _set_bit(1);
- if (parameter_ == &_default_parameter_) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::kEmptyString) {
parameter_ = new ::std::string;
}
return parameter_;
}
+inline ::std::string* CodeGeneratorRequest::release_parameter() {
+ clear_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = parameter_;
+ parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
inline int CodeGeneratorRequest::proto_file_size() const {
@@ -511,129 +510,177 @@ CodeGeneratorRequest::mutable_proto_file() {
// optional string name = 1;
inline bool CodeGeneratorResponse_File::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void CodeGeneratorResponse_File::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void CodeGeneratorResponse_File::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& CodeGeneratorResponse_File::name() const {
return *name_;
}
inline void CodeGeneratorResponse_File::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void CodeGeneratorResponse_File::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* CodeGeneratorResponse_File::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
return name_;
}
+inline ::std::string* CodeGeneratorResponse_File::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional string insertion_point = 2;
inline bool CodeGeneratorResponse_File::has_insertion_point() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_insertion_point() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void CodeGeneratorResponse_File::clear_has_insertion_point() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void CodeGeneratorResponse_File::clear_insertion_point() {
- if (insertion_point_ != &_default_insertion_point_) {
+ if (insertion_point_ != &::google::protobuf::internal::kEmptyString) {
insertion_point_->clear();
}
- _clear_bit(1);
+ clear_has_insertion_point();
}
inline const ::std::string& CodeGeneratorResponse_File::insertion_point() const {
return *insertion_point_;
}
inline void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) {
- _set_bit(1);
- if (insertion_point_ == &_default_insertion_point_) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::kEmptyString) {
insertion_point_ = new ::std::string;
}
insertion_point_->assign(value);
}
inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) {
- _set_bit(1);
- if (insertion_point_ == &_default_insertion_point_) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::kEmptyString) {
insertion_point_ = new ::std::string;
}
insertion_point_->assign(value);
}
inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) {
- _set_bit(1);
- if (insertion_point_ == &_default_insertion_point_) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::kEmptyString) {
insertion_point_ = new ::std::string;
}
insertion_point_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
- _set_bit(1);
- if (insertion_point_ == &_default_insertion_point_) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::kEmptyString) {
insertion_point_ = new ::std::string;
}
return insertion_point_;
}
+inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() {
+ clear_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = insertion_point_;
+ insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional string content = 15;
inline bool CodeGeneratorResponse_File::has_content() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_content() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void CodeGeneratorResponse_File::clear_has_content() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void CodeGeneratorResponse_File::clear_content() {
- if (content_ != &_default_content_) {
+ if (content_ != &::google::protobuf::internal::kEmptyString) {
content_->clear();
}
- _clear_bit(2);
+ clear_has_content();
}
inline const ::std::string& CodeGeneratorResponse_File::content() const {
return *content_;
}
inline void CodeGeneratorResponse_File::set_content(const ::std::string& value) {
- _set_bit(2);
- if (content_ == &_default_content_) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::kEmptyString) {
content_ = new ::std::string;
}
content_->assign(value);
}
inline void CodeGeneratorResponse_File::set_content(const char* value) {
- _set_bit(2);
- if (content_ == &_default_content_) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::kEmptyString) {
content_ = new ::std::string;
}
content_->assign(value);
}
inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) {
- _set_bit(2);
- if (content_ == &_default_content_) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::kEmptyString) {
content_ = new ::std::string;
}
content_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* CodeGeneratorResponse_File::mutable_content() {
- _set_bit(2);
- if (content_ == &_default_content_) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::kEmptyString) {
content_ = new ::std::string;
}
return content_;
}
+inline ::std::string* CodeGeneratorResponse_File::release_content() {
+ clear_has_content();
+ if (content_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = content_;
+ content_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// -------------------------------------------------------------------
@@ -641,45 +688,61 @@ inline ::std::string* CodeGeneratorResponse_File::mutable_content() {
// optional string error = 1;
inline bool CodeGeneratorResponse::has_error() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void CodeGeneratorResponse::set_has_error() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void CodeGeneratorResponse::clear_has_error() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void CodeGeneratorResponse::clear_error() {
- if (error_ != &_default_error_) {
+ if (error_ != &::google::protobuf::internal::kEmptyString) {
error_->clear();
}
- _clear_bit(0);
+ clear_has_error();
}
inline const ::std::string& CodeGeneratorResponse::error() const {
return *error_;
}
inline void CodeGeneratorResponse::set_error(const ::std::string& value) {
- _set_bit(0);
- if (error_ == &_default_error_) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::kEmptyString) {
error_ = new ::std::string;
}
error_->assign(value);
}
inline void CodeGeneratorResponse::set_error(const char* value) {
- _set_bit(0);
- if (error_ == &_default_error_) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::kEmptyString) {
error_ = new ::std::string;
}
error_->assign(value);
}
inline void CodeGeneratorResponse::set_error(const char* value, size_t size) {
- _set_bit(0);
- if (error_ == &_default_error_) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::kEmptyString) {
error_ = new ::std::string;
}
error_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* CodeGeneratorResponse::mutable_error() {
- _set_bit(0);
- if (error_ == &_default_error_) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::kEmptyString) {
error_ = new ::std::string;
}
return error_;
}
+inline ::std::string* CodeGeneratorResponse::release_error() {
+ clear_has_error();
+ if (error_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = error_;
+ error_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
inline int CodeGeneratorResponse::file_size() const {
diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto
index 4e928b0d..651ed10c 100644
--- a/src/google/protobuf/compiler/plugin.proto
+++ b/src/google/protobuf/compiler/plugin.proto
@@ -131,7 +131,7 @@ message CodeGeneratorResponse {
// in order to work correctly in that context.
//
// The code generator that generates the initial file and the one which
- // inserts into it must both run as part of a single invocatino of protoc.
+ // inserts into it must both run as part of a single invocation of protoc.
// Code generators are executed in the order in which they appear on the
// command line.
//
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index fae83a37..9b109378 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -230,7 +230,7 @@ Generator::~Generator() {
bool Generator::Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
// Completely serialize all Generate() calls on this instance. The
@@ -252,20 +252,18 @@ bool Generator::Generate(const FileDescriptor* file,
fdp.SerializeToString(&file_descriptor_serialized_);
- scoped_ptr<io::ZeroCopyOutputStream> output(output_directory->Open(filename));
+ scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
GOOGLE_CHECK(output.get());
io::Printer printer(output.get(), '$');
printer_ = &printer;
PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
+ PrintImports();
PrintFileDescriptor();
PrintTopLevelEnums();
PrintTopLevelExtensions();
PrintAllNestedEnumsInFile();
PrintMessageDescriptors();
- // We have to print the imports after the descriptors, so that mutually
- // recursive protos in separate files can successfully reference each other.
- PrintImports();
FixForeignFieldsInDescriptors();
PrintMessages();
// We have to fix up the extensions after the message classes themselves,
@@ -377,7 +375,7 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
printer_->Print("containing_type=None,\n");
printer_->Print("options=$options_value$,\n",
"options_value",
- OptionsValue("EnumOptions", CEscape(options_string)));
+ OptionsValue("EnumOptions", options_string));
EnumDescriptorProto edp;
PrintSerializedPbInterval(enum_descriptor, edp);
printer_->Outdent();
@@ -674,6 +672,17 @@ void Generator::FixForeignFieldsInDescriptor(
}
}
+void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
+ map<string, string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["message_name"] = descriptor.name();
+ m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+ const char file_descriptor_template[] =
+ "$descriptor_name$.message_types_by_name['$message_name$'] = "
+ "$message_descriptor_name$\n";
+ printer_->Print(m, file_descriptor_template);
+}
+
// Sets any necessary message_type and enum_type attributes
// for the Python version of |field|.
//
@@ -752,6 +761,9 @@ void Generator::FixForeignFieldsInDescriptors() const {
for (int i = 0; i < file_->message_type_count(); ++i) {
FixForeignFieldsInDescriptor(*file_->message_type(i), NULL);
}
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ AddMessageToFileDescriptor(*file_->message_type(i));
+ }
printer_->Print("\n");
}
@@ -823,6 +835,8 @@ void Generator::PrintEnumValueDescriptor(
" type=None)");
}
+// Returns a Python expression that calls descriptor._ParseOptions using
+// the given descriptor class name and serialized options protobuf string.
string Generator::OptionsValue(
const string& class_name, const string& serialized_options) const {
if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h
index 43c20876..84eaf8ab 100644
--- a/src/google/protobuf/compiler/python/python_generator.h
+++ b/src/google/protobuf/compiler/python/python_generator.h
@@ -66,7 +66,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator {
// CodeGenerator methods.
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* generator_context,
string* error) const;
private:
@@ -104,6 +104,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator {
void FixForeignFieldsInField(const Descriptor* containing_type,
const FieldDescriptor& field,
const string& python_dict_name) const;
+ void AddMessageToFileDescriptor(const Descriptor& descriptor) const;
string FieldReferencingExpression(const Descriptor* containing_type,
const FieldDescriptor& field,
const string& python_dict_name) const;
diff --git a/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/src/google/protobuf/compiler/python/python_plugin_unittest.cc
index fde88761..da619ad3 100644
--- a/src/google/protobuf/compiler/python/python_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/python/python_plugin_unittest.cc
@@ -56,19 +56,19 @@ class TestGenerator : public CodeGenerator {
virtual bool Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
- TryInsert("test_pb2.py", "imports", output_directory);
- TryInsert("test_pb2.py", "module_scope", output_directory);
- TryInsert("test_pb2.py", "class_scope:foo.Bar", output_directory);
- TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", output_directory);
+ TryInsert("test_pb2.py", "imports", context);
+ TryInsert("test_pb2.py", "module_scope", context);
+ TryInsert("test_pb2.py", "class_scope:foo.Bar", context);
+ TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", context);
return true;
}
void TryInsert(const string& filename, const string& insertion_point,
- OutputDirectory* output_directory) const {
+ GeneratorContext* context) const {
scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->OpenForInsert(filename, insertion_point));
+ context->OpenForInsert(filename, insertion_point));
io::Printer printer(output.get(), '$');
printer.Print("// inserted $name$\n", "name", insertion_point);
}
diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc
index dbd813e1..5fb5d5cb 100644
--- a/src/google/protobuf/compiler/subprocess.cc
+++ b/src/google/protobuf/compiler/subprocess.cc
@@ -32,6 +32,8 @@
#include <google/protobuf/compiler/subprocess.h>
+#include <algorithm>
+
#ifndef _WIN32
#include <errno.h>
#include <sys/select.h>
@@ -39,7 +41,6 @@
#include <signal.h>
#endif
-#include <algorithm>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message.h>
#include <google/protobuf/stubs/substitute.h>
diff --git a/src/google/protobuf/compiler/subprocess.h b/src/google/protobuf/compiler/subprocess.h
index 7a6fa70c..de9fce9e 100644
--- a/src/google/protobuf/compiler/subprocess.h
+++ b/src/google/protobuf/compiler/subprocess.h
@@ -40,9 +40,10 @@
#include <sys/types.h>
#include <unistd.h>
#endif // !_WIN32
+#include <google/protobuf/stubs/common.h>
#include <string>
-#include <google/protobuf/stubs/common.h>
+
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 259d5d21..3a024364 100755
--- a/src/google/protobuf/compiler/zip_output_unittest.sh
+++ b/src/google/protobuf/compiler/zip_output_unittest.sh
@@ -39,45 +39,51 @@ fail() {
exit 1
}
+TEST_TMPDIR=.
+PROTOC=./protoc
+
echo '
+ syntax = "proto2";
option java_multiple_files = true;
option java_package = "test.jar";
option java_outer_classname = "Outer";
message Foo {}
message Bar {}
-' > testzip.proto
+' > $TEST_TMPDIR/testzip.proto
-./protoc --cpp_out=testzip.zip --python_out=testzip.zip --java_out=testzip.jar \
- testzip.proto || fail 'protoc failed.'
+$PROTOC \
+ --cpp_out=$TEST_TMPDIR/testzip.zip --python_out=$TEST_TMPDIR/testzip.zip \
+ --java_out=$TEST_TMPDIR/testzip.jar -I$TEST_TMPDIR testzip.proto \
+ || fail 'protoc failed.'
echo "Testing output to zip..."
if unzip -h > /dev/null; then
- unzip -t testzip.zip > testzip.list || fail 'unzip failed.'
+ unzip -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list || fail 'unzip failed.'
- grep 'testing: testzip\.pb\.cc *OK$' testzip.list > /dev/null \
+ grep 'testing: testzip\.pb\.cc *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'testzip.pb.cc not found in output zip.'
- grep 'testing: testzip\.pb\.h *OK$' testzip.list > /dev/null \
+ grep 'testing: testzip\.pb\.h *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'testzip.pb.h not found in output zip.'
- grep 'testing: testzip_pb2\.py *OK$' testzip.list > /dev/null \
+ grep 'testing: testzip_pb2\.py *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'testzip_pb2.py not found in output zip.'
- grep -i 'manifest' testzip.list > /dev/null \
+ grep -i 'manifest' $TEST_TMPDIR/testzip.list > /dev/null \
&& fail 'Zip file contained manifest.'
else
echo "Warning: 'unzip' command not available. Skipping test."
fi
echo "Testing output to jar..."
-if jar c testzip.proto > /dev/null; then
- jar tf testzip.jar > 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.'
- grep '^test/jar/Foo\.java$' testzip.list > /dev/null \
+ grep '^test/jar/Foo\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'Foo.java not found in output jar.'
- grep '^test/jar/Bar\.java$' testzip.list > /dev/null \
+ grep '^test/jar/Bar\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'Bar.java not found in output jar.'
- grep '^test/jar/Outer\.java$' testzip.list > /dev/null \
+ grep '^test/jar/Outer\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
|| fail 'Outer.java not found in output jar.'
- grep '^META-INF/MANIFEST\.MF$' testzip.list > /dev/null \
- || fail 'Manifest not ofund in output jar.'
+ grep '^META-INF/MANIFEST\.MF$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'Manifest not found in output jar.'
else
echo "Warning: 'jar' command not available. Skipping test."
fi
diff --git a/src/google/protobuf/compiler/zip_writer.cc b/src/google/protobuf/compiler/zip_writer.cc
index 53c18771..65d73527 100644
--- a/src/google/protobuf/compiler/zip_writer.cc
+++ b/src/google/protobuf/compiler/zip_writer.cc
@@ -28,6 +28,36 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: ambrose@google.com (Ambrose Feinstein),
// kenton@google.com (Kenton Varda)
//
@@ -183,6 +213,6 @@ bool ZipWriter::WriteDirectory() {
return output.HadError();
}
-} // namespace google
-} // namespace protobuf
} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/zip_writer.h b/src/google/protobuf/compiler/zip_writer.h
index 42895530..be73972a 100644
--- a/src/google/protobuf/compiler/zip_writer.h
+++ b/src/google/protobuf/compiler/zip_writer.h
@@ -28,6 +28,36 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
// Author: kenton@google.com (Kenton Varda)
#include <vector>
@@ -58,6 +88,6 @@ class ZipWriter {
vector<FileInfo> files_;
};
-} // namespace google
-} // namespace protobuf
} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index 9226dfbc..76b7219f 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -42,10 +42,12 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor_database.h>
#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
@@ -2056,6 +2058,8 @@ class DescriptorBuilder {
// Otherwise returns true.
bool InterpretOptions(OptionsToInterpret* options_to_interpret);
+ class AggregateOptionFinder;
+
private:
// Interprets uninterpreted_option_ on the specified message, which
// must be the mutable copy of the original options message to which
@@ -2082,6 +2086,11 @@ class DescriptorBuilder {
bool SetOptionValue(const FieldDescriptor* option_field,
UnknownFieldSet* unknown_fields);
+ // Parses an aggregate value for a CPPTYPE_MESSAGE option and
+ // saves it into *unknown_fields.
+ bool SetAggregateOption(const FieldDescriptor* option_field,
+ UnknownFieldSet* unknown_fields);
+
// Convenience functions to set an int field the right way, depending on
// its wire type (a single int CppType can represent multiple wire types).
void SetInt32(int number, int32 value, FieldDescriptor::Type type,
@@ -2128,6 +2137,10 @@ class DescriptorBuilder {
// can use it to find locations recorded by the parser.
const UninterpretedOption* uninterpreted_option_;
+ // Factory used to create the dynamic messages we need to parse
+ // any aggregate option values we encounter.
+ DynamicMessageFactory dynamic_factory_;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter);
};
@@ -2139,6 +2152,8 @@ class DescriptorBuilder {
// redundantly declare OptionInterpreter a friend just to make things extra
// clear for these bad compilers.
friend class OptionInterpreter;
+ friend class OptionInterpreter::AggregateOptionFinder;
+
static inline bool get_allow_unknown(const DescriptorPool* pool) {
return pool->allow_unknown_;
}
@@ -3973,9 +3988,6 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
intermediate_fields.push_back(field);
descriptor = field->message_type();
}
- } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- return AddNameError("Option field \"" + debug_msg_name +
- "\" cannot be of message type.");
}
}
@@ -4310,18 +4322,95 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
- // We don't currently support defining a message-typed option, so we
- // should never actually get here.
- return AddValueError("Option \"" + option_field->full_name() +
- "\" is a message. To set fields within it, use "
- "syntax like \"" + option_field->name() +
- ".foo = value\".");
+ if (!SetAggregateOption(option_field, unknown_fields)) {
+ return false;
+ }
break;
}
return true;
}
+class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder
+ : public TextFormat::Finder {
+ public:
+ DescriptorBuilder* builder_;
+
+ virtual const FieldDescriptor* FindExtension(
+ Message* message, const string& name) const {
+ if (builder_->pool_->mutex_ != NULL) {
+ builder_->pool_->mutex_->AssertHeld();
+ }
+ Symbol result = builder_->LookupSymbolNoPlaceholder(
+ name, message->GetDescriptor()->full_name());
+ if (result.type == Symbol::FIELD &&
+ result.field_descriptor->is_extension()) {
+ return result.field_descriptor;
+ } else {
+ return NULL;
+ }
+ }
+};
+
+// A custom error collector to record any text-format parsing errors
+namespace {
+class AggregateErrorCollector : public io::ErrorCollector {
+ public:
+ string error_;
+
+ virtual void AddError(int line, int column, const string& message) {
+ if (!error_.empty()) {
+ error_ += "; ";
+ }
+ error_ += message;
+ }
+
+ virtual void AddWarning(int line, int column, const string& message) {
+ // Ignore warnings
+ }
+};
+}
+
+// We construct a dynamic message of the type corresponding to
+// option_field, parse the supplied text-format string into this
+// message, and serialize the resulting message to produce the value.
+bool DescriptorBuilder::OptionInterpreter::SetAggregateOption(
+ const FieldDescriptor* option_field,
+ UnknownFieldSet* unknown_fields) {
+ if (!uninterpreted_option_->has_aggregate_value()) {
+ return AddValueError("Option \"" + option_field->full_name() +
+ "\" is a message. To set the entire message, use "
+ "syntax like \"" + option_field->name() +
+ " = { <proto text format> }\". "
+ "To set fields within it, use "
+ "syntax like \"" + option_field->name() +
+ ".foo = value\".");
+ }
+
+ const Descriptor* type = option_field->message_type();
+ scoped_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New());
+ GOOGLE_CHECK(dynamic.get() != NULL)
+ << "Could not create an instance of " << option_field->DebugString();
+
+ AggregateErrorCollector collector;
+ AggregateOptionFinder finder;
+ finder.builder_ = builder_;
+ TextFormat::Parser parser;
+ parser.RecordErrorsTo(&collector);
+ parser.SetFinder(&finder);
+ if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(),
+ dynamic.get())) {
+ AddValueError("Error while parsing option value for \"" +
+ option_field->name() + "\": " + collector.error_);
+ return false;
+ } else {
+ string serial;
+ dynamic->SerializeToString(&serial); // Never fails
+ unknown_fields->AddLengthDelimited(option_field->number(), serial);
+ return true;
+ }
+}
+
void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value,
FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
switch (type) {
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index 922237f5..87303ef8 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -76,6 +76,12 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
const ::google::protobuf::Descriptor* UninterpretedOption_NamePart_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
UninterpretedOption_NamePart_reflection_ = NULL;
+const ::google::protobuf::Descriptor* SourceCodeInfo_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ SourceCodeInfo_reflection_ = NULL;
+const ::google::protobuf::Descriptor* SourceCodeInfo_Location_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ SourceCodeInfo_Location_reflection_ = NULL;
} // namespace
@@ -102,7 +108,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::MessageFactory::generated_factory(),
sizeof(FileDescriptorSet));
FileDescriptorProto_descriptor_ = file->message_type(1);
- static const int FileDescriptorProto_offsets_[8] = {
+ static const int FileDescriptorProto_offsets_[9] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_),
@@ -111,6 +117,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, service_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, extension_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, options_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, source_code_info_),
};
FileDescriptorProto_reflection_ =
new ::google::protobuf::internal::GeneratedMessageReflection(
@@ -254,10 +261,11 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::MessageFactory::generated_factory(),
sizeof(MethodDescriptorProto));
FileOptions_descriptor_ = file->message_type(8);
- static const int FileOptions_offsets_[8] = {
+ static const int FileOptions_offsets_[9] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generate_equals_and_hash_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_),
@@ -374,13 +382,14 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::MessageFactory::generated_factory(),
sizeof(MethodOptions));
UninterpretedOption_descriptor_ = file->message_type(15);
- static const int UninterpretedOption_offsets_[6] = {
+ static const int UninterpretedOption_offsets_[7] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, negative_int_value_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, double_value_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, string_value_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, aggregate_value_),
};
UninterpretedOption_reflection_ =
new ::google::protobuf::internal::GeneratedMessageReflection(
@@ -409,6 +418,37 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
::google::protobuf::DescriptorPool::generated_pool(),
::google::protobuf::MessageFactory::generated_factory(),
sizeof(UninterpretedOption_NamePart));
+ SourceCodeInfo_descriptor_ = file->message_type(16);
+ static const int SourceCodeInfo_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_),
+ };
+ SourceCodeInfo_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ SourceCodeInfo_descriptor_,
+ SourceCodeInfo::default_instance_,
+ SourceCodeInfo_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(SourceCodeInfo));
+ SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0);
+ static const int SourceCodeInfo_Location_offsets_[2] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_),
+ };
+ SourceCodeInfo_Location_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ SourceCodeInfo_Location_descriptor_,
+ SourceCodeInfo_Location::default_instance_,
+ SourceCodeInfo_Location_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(SourceCodeInfo_Location));
}
namespace {
@@ -457,6 +497,10 @@ void protobuf_RegisterTypes(const ::std::string&) {
UninterpretedOption_descriptor_, &UninterpretedOption::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
UninterpretedOption_NamePart_descriptor_, &UninterpretedOption_NamePart::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ SourceCodeInfo_descriptor_, &SourceCodeInfo::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ SourceCodeInfo_Location_descriptor_, &SourceCodeInfo_Location::default_instance());
}
} // namespace
@@ -498,6 +542,10 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
delete UninterpretedOption_reflection_;
delete UninterpretedOption_NamePart::default_instance_;
delete UninterpretedOption_NamePart_reflection_;
+ delete SourceCodeInfo::default_instance_;
+ delete SourceCodeInfo_reflection_;
+ delete SourceCodeInfo_Location::default_instance_;
+ delete SourceCodeInfo_Location_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
@@ -510,7 +558,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
"\n google/protobuf/descriptor.proto\022\017goog"
"le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
"\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
- "roto\"\334\002\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
+ "roto\"\227\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
"(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
"6\n\014message_type\030\004 \003(\0132 .google.protobuf."
"DescriptorProto\0227\n\tenum_type\030\005 \003(\0132$.goo"
@@ -518,88 +566,94 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
"ice\030\006 \003(\0132\'.google.protobuf.ServiceDescr"
"iptorProto\0228\n\textension\030\007 \003(\0132%.google.p"
"rotobuf.FieldDescriptorProto\022-\n\007options\030"
- "\010 \001(\0132\034.google.protobuf.FileOptions\"\251\003\n\017"
- "DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005field\030\002"
- " \003(\0132%.google.protobuf.FieldDescriptorPr"
- "oto\0228\n\textension\030\006 \003(\0132%.google.protobuf"
- ".FieldDescriptorProto\0225\n\013nested_type\030\003 \003"
- "(\0132 .google.protobuf.DescriptorProto\0227\n\t"
- "enum_type\030\004 \003(\0132$.google.protobuf.EnumDe"
- "scriptorProto\022H\n\017extension_range\030\005 \003(\0132/"
- ".google.protobuf.DescriptorProto.Extensi"
- "onRange\0220\n\007options\030\007 \001(\0132\037.google.protob"
- "uf.MessageOptions\032,\n\016ExtensionRange\022\r\n\005s"
- "tart\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\224\005\n\024FieldDescrip"
- "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\003 \001(\005\022:"
- "\n\005label\030\004 \001(\0162+.google.protobuf.FieldDes"
- "criptorProto.Label\0228\n\004type\030\005 \001(\0162*.googl"
- "e.protobuf.FieldDescriptorProto.Type\022\021\n\t"
- "type_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001(\t\022\025\n\rdef"
- "ault_value\030\007 \001(\t\022.\n\007options\030\010 \001(\0132\035.goog"
- "le.protobuf.FieldOptions\"\266\002\n\004Type\022\017\n\013TYP"
- "E_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64"
- "\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014T"
- "YPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_"
- "BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022"
- "\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYP"
- "E_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED"
- "32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021"
- "\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTI"
- "ONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPE"
- "ATED\020\003\"\214\001\n\023EnumDescriptorProto\022\014\n\004name\030\001"
- " \001(\t\0228\n\005value\030\002 \003(\0132).google.protobuf.En"
- "umValueDescriptorProto\022-\n\007options\030\003 \001(\0132"
- "\034.google.protobuf.EnumOptions\"l\n\030EnumVal"
- "ueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006numbe"
- "r\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google.protob"
- "uf.EnumValueOptions\"\220\001\n\026ServiceDescripto"
- "rProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.g"
- "oogle.protobuf.MethodDescriptorProto\0220\n\007"
- "options\030\003 \001(\0132\037.google.protobuf.ServiceO"
- "ptions\"\177\n\025MethodDescriptorProto\022\014\n\004name\030"
- "\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013output_type"
- "\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.protobu"
- "f.MethodOptions\"\244\003\n\013FileOptions\022\024\n\014java_"
- "package\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 "
- "\001(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false\022"
- "F\n\014optimize_for\030\t \001(\0162).google.protobuf."
- "FileOptions.OptimizeMode:\005SPEED\022!\n\023cc_ge"
- "neric_services\030\020 \001(\010:\004true\022#\n\025java_gener"
- "ic_services\030\021 \001(\010:\004true\022!\n\023py_generic_se"
- "rvices\030\022 \001(\010:\004true\022C\n\024uninterpreted_opti"
- "on\030\347\007 \003(\0132$.google.protobuf.Uninterprete"
- "dOption\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCO"
- "DE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270"
- "\001\n\016MessageOptions\022&\n\027message_set_wire_fo"
- "rmat\030\001 \001(\010:\005false\022.\n\037no_standard_descrip"
- "tor_accessor\030\002 \001(\010:\005false\022C\n\024uninterpret"
+ "\010 \001(\0132\034.google.protobuf.FileOptions\0229\n\020s"
+ "ource_code_info\030\t \001(\0132\037.google.protobuf."
+ "SourceCodeInfo\"\251\003\n\017DescriptorProto\022\014\n\004na"
+ "me\030\001 \001(\t\0224\n\005field\030\002 \003(\0132%.google.protobu"
+ "f.FieldDescriptorProto\0228\n\textension\030\006 \003("
+ "\0132%.google.protobuf.FieldDescriptorProto"
+ "\0225\n\013nested_type\030\003 \003(\0132 .google.protobuf."
+ "DescriptorProto\0227\n\tenum_type\030\004 \003(\0132$.goo"
+ "gle.protobuf.EnumDescriptorProto\022H\n\017exte"
+ "nsion_range\030\005 \003(\0132/.google.protobuf.Desc"
+ "riptorProto.ExtensionRange\0220\n\007options\030\007 "
+ "\001(\0132\037.google.protobuf.MessageOptions\032,\n\016"
+ "ExtensionRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001"
+ "(\005\"\224\005\n\024FieldDescriptorProto\022\014\n\004name\030\001 \001("
+ "\t\022\016\n\006number\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.googl"
+ "e.protobuf.FieldDescriptorProto.Label\0228\n"
+ "\004type\030\005 \001(\0162*.google.protobuf.FieldDescr"
+ "iptorProto.Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010ex"
+ "tendee\030\002 \001(\t\022\025\n\rdefault_value\030\007 \001(\t\022.\n\007o"
+ "ptions\030\010 \001(\0132\035.google.protobuf.FieldOpti"
+ "ons\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FL"
+ "OAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016"
+ "\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE"
+ "_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING"
+ "\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\n"
+ "TYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_EN"
+ "UM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64"
+ "\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005"
+ "Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n\016LABEL_REQUI"
+ "RED\020\002\022\022\n\016LABEL_REPEATED\020\003\"\214\001\n\023EnumDescri"
+ "ptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132)"
+ ".google.protobuf.EnumValueDescriptorProt"
+ "o\022-\n\007options\030\003 \001(\0132\034.google.protobuf.Enu"
+ "mOptions\"l\n\030EnumValueDescriptorProto\022\014\n\004"
+ "name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007options\030\003 "
+ "\001(\0132!.google.protobuf.EnumValueOptions\"\220"
+ "\001\n\026ServiceDescriptorProto\022\014\n\004name\030\001 \001(\t\022"
+ "6\n\006method\030\002 \003(\0132&.google.protobuf.Method"
+ "DescriptorProto\0220\n\007options\030\003 \001(\0132\037.googl"
+ "e.protobuf.ServiceOptions\"\177\n\025MethodDescr"
+ "iptorProto\022\014\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002"
+ " \001(\t\022\023\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001"
+ "(\0132\036.google.protobuf.MethodOptions\"\325\003\n\013F"
+ "ileOptions\022\024\n\014java_package\030\001 \001(\t\022\034\n\024java"
+ "_outer_classname\030\010 \001(\t\022\"\n\023java_multiple_"
+ "files\030\n \001(\010:\005false\022,\n\035java_generate_equa"
+ "ls_and_hash\030\024 \001(\010:\005false\022F\n\014optimize_for"
+ "\030\t \001(\0162).google.protobuf.FileOptions.Opt"
+ "imizeMode:\005SPEED\022\"\n\023cc_generic_services\030"
+ "\020 \001(\010:\005false\022$\n\025java_generic_services\030\021 "
+ "\001(\010:\005false\022\"\n\023py_generic_services\030\022 \001(\010:"
+ "\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$."
+ "google.protobuf.UninterpretedOption\":\n\014O"
+ "ptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n"
+ "\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270\001\n\016MessageOp"
+ "tions\022&\n\027message_set_wire_format\030\001 \001(\010:\005"
+ "false\022.\n\037no_standard_descriptor_accessor"
+ "\030\002 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007"
+ " \003(\0132$.google.protobuf.UninterpretedOpti"
+ "on*\t\010\350\007\020\200\200\200\200\002\"\224\002\n\014FieldOptions\022:\n\005ctype\030"
+ "\001 \001(\0162#.google.protobuf.FieldOptions.CTy"
+ "pe:\006STRING\022\016\n\006packed\030\002 \001(\010\022\031\n\ndeprecated"
+ "\030\003 \001(\010:\005false\022\034\n\024experimental_map_key\030\t "
+ "\001(\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo"
+ "gle.protobuf.UninterpretedOption\"/\n\005CTyp"
+ "e\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020"
+ "\002*\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022C\n\024uninterpr"
+ "eted_option\030\347\007 \003(\0132$.google.protobuf.Uni"
+ "nterpretedOption*\t\010\350\007\020\200\200\200\200\002\"b\n\020EnumValue"
+ "Options\022C\n\024uninterpreted_option\030\347\007 \003(\0132$"
+ ".google.protobuf.UninterpretedOption*\t\010\350"
+ "\007\020\200\200\200\200\002\"`\n\016ServiceOptions\022C\n\024uninterpret"
"ed_option\030\347\007 \003(\0132$.google.protobuf.Unint"
- "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"\224\002\n\014FieldOptio"
- "ns\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.Fiel"
- "dOptions.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\031"
- "\n\ndeprecated\030\003 \001(\010:\005false\022\034\n\024experimenta"
- "l_map_key\030\t \001(\t\022C\n\024uninterpreted_option\030"
- "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
- "tion\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014S"
- "TRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022"
- "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
- "protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\""
- "b\n\020EnumValueOptions\022C\n\024uninterpreted_opt"
- "ion\030\347\007 \003(\0132$.google.protobuf.Uninterpret"
- "edOption*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceOptions\022C\n"
- "\024uninterpreted_option\030\347\007 \003(\0132$.google.pr"
- "otobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n"
- "\rMethodOptions\022C\n\024uninterpreted_option\030\347"
- "\007 \003(\0132$.google.protobuf.UninterpretedOpt"
- "ion*\t\010\350\007\020\200\200\200\200\002\"\205\002\n\023UninterpretedOption\022;"
- "\n\004name\030\002 \003(\0132-.google.protobuf.Uninterpr"
- "etedOption.NamePart\022\030\n\020identifier_value\030"
- "\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022neg"
- "ative_int_value\030\005 \001(\003\022\024\n\014double_value\030\006 "
- "\001(\001\022\024\n\014string_value\030\007 \001(\014\0323\n\010NamePart\022\021\n"
- "\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010B)"
- "\n\023com.google.protobufB\020DescriptorProtosH"
- "\001", 3681);
+ "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n\rMethodOptio"
+ "ns\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goog"
+ "le.protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200"
+ "\200\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\013"
+ "2-.google.protobuf.UninterpretedOption.N"
+ "amePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022pos"
+ "itive_int_value\030\004 \001(\004\022\032\n\022negative_int_va"
+ "lue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014strin"
+ "g_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323"
+ "\n\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_exte"
+ "nsion\030\002 \002(\010\"|\n\016SourceCodeInfo\022:\n\010locatio"
+ "n\030\001 \003(\0132(.google.protobuf.SourceCodeInfo"
+ ".Location\032.\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022"
+ "\020\n\004span\030\002 \003(\005B\002\020\001B)\n\023com.google.protobuf"
+ "B\020DescriptorProtosH\001", 3940);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
FileDescriptorSet::default_instance_ = new FileDescriptorSet();
@@ -620,6 +674,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
MethodOptions::default_instance_ = new MethodOptions();
UninterpretedOption::default_instance_ = new UninterpretedOption();
UninterpretedOption_NamePart::default_instance_ = new UninterpretedOption_NamePart();
+ SourceCodeInfo::default_instance_ = new SourceCodeInfo();
+ SourceCodeInfo_Location::default_instance_ = new SourceCodeInfo_Location();
FileDescriptorSet::default_instance_->InitAsDefaultInstance();
FileDescriptorProto::default_instance_->InitAsDefaultInstance();
DescriptorProto::default_instance_->InitAsDefaultInstance();
@@ -638,6 +694,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
MethodOptions::default_instance_->InitAsDefaultInstance();
UninterpretedOption::default_instance_->InitAsDefaultInstance();
UninterpretedOption_NamePart::default_instance_->InitAsDefaultInstance();
+ SourceCodeInfo::default_instance_->InitAsDefaultInstance();
+ SourceCodeInfo_Location::default_instance_->InitAsDefaultInstance();
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto);
}
@@ -856,8 +914,6 @@ void FileDescriptorSet::Swap(FileDescriptorSet* other) {
// ===================================================================
-const ::std::string FileDescriptorProto::_default_name_;
-const ::std::string FileDescriptorProto::_default_package_;
#ifndef _MSC_VER
const int FileDescriptorProto::kNameFieldNumber;
const int FileDescriptorProto::kPackageFieldNumber;
@@ -867,6 +923,7 @@ const int FileDescriptorProto::kEnumTypeFieldNumber;
const int FileDescriptorProto::kServiceFieldNumber;
const int FileDescriptorProto::kExtensionFieldNumber;
const int FileDescriptorProto::kOptionsFieldNumber;
+const int FileDescriptorProto::kSourceCodeInfoFieldNumber;
#endif // !_MSC_VER
FileDescriptorProto::FileDescriptorProto()
@@ -876,6 +933,7 @@ FileDescriptorProto::FileDescriptorProto()
void FileDescriptorProto::InitAsDefaultInstance() {
options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance());
+ source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>(&::google::protobuf::SourceCodeInfo::default_instance());
}
FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
@@ -886,9 +944,10 @@ FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
void FileDescriptorProto::SharedCtor() {
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
- package_ = const_cast< ::std::string*>(&_default_package_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
options_ = NULL;
+ source_code_info_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -897,14 +956,15 @@ FileDescriptorProto::~FileDescriptorProto() {
}
void FileDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
delete name_;
}
- if (package_ != &_default_package_) {
+ if (package_ != &::google::protobuf::internal::kEmptyString) {
delete package_;
}
if (this != default_instance_) {
delete options_;
+ delete source_code_info_;
}
}
@@ -930,20 +990,25 @@ FileDescriptorProto* FileDescriptorProto::New() const {
void FileDescriptorProto::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
}
- if (_has_bit(1)) {
- if (package_ != &_default_package_) {
+ if (has_package()) {
+ if (package_ != &::google::protobuf::internal::kEmptyString) {
package_->clear();
}
}
- if (_has_bit(7)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
}
}
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ if (has_source_code_info()) {
+ if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
+ }
+ }
dependency_.Clear();
message_type_.Clear();
enum_type_.Clear();
@@ -1080,6 +1145,20 @@ bool FileDescriptorProto::MergePartialFromCodedStream(
} else {
goto handle_uninterpreted;
}
+ if (input->ExpectTag(74)) goto parse_source_code_info;
+ break;
+ }
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ case 9: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_source_code_info:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_source_code_info()));
+ } else {
+ goto handle_uninterpreted;
+ }
if (input->ExpectAtEnd()) return true;
break;
}
@@ -1103,7 +1182,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream(
void FileDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -1112,7 +1191,7 @@ void FileDescriptorProto::SerializeWithCachedSizes(
}
// optional string package = 2;
- if (_has_bit(1)) {
+ if (has_package()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->package().data(), this->package().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -1154,11 +1233,17 @@ void FileDescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.FileOptions options = 8;
- if (_has_bit(7)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
8, this->options(), output);
}
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (has_source_code_info()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 9, this->source_code_info(), output);
+ }
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
@@ -1168,7 +1253,7 @@ void FileDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -1178,7 +1263,7 @@ void FileDescriptorProto::SerializeWithCachedSizes(
}
// optional string package = 2;
- if (_has_bit(1)) {
+ if (has_package()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->package().data(), this->package().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -1225,12 +1310,19 @@ void FileDescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.FileOptions options = 8;
- if (_has_bit(7)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
8, this->options(), target);
}
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (has_source_code_info()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 9, this->source_code_info(), target);
+ }
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
@@ -1264,6 +1356,15 @@ int FileDescriptorProto::ByteSize() const {
}
}
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (has_source_code_info()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->source_code_info());
+ }
+
+ }
// repeated string dependency = 3;
total_size += 1 * this->dependency_size();
for (int i = 0; i < this->dependency_size(); i++) {
@@ -1334,16 +1435,21 @@ void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
service_.MergeFrom(from.service_);
extension_.MergeFrom(from.extension_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(1)) {
+ if (from.has_package()) {
set_package(from.package());
}
- if (from._has_bit(7)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options());
}
}
+ if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ if (from.has_source_code_info()) {
+ mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info());
+ }
+ }
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
@@ -1389,6 +1495,7 @@ void FileDescriptorProto::Swap(FileDescriptorProto* other) {
service_.Swap(&other->service_);
extension_.Swap(&other->extension_);
std::swap(options_, other->options_);
+ std::swap(source_code_info_, other->source_code_info_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
std::swap(_cached_size_, other->_cached_size_);
@@ -1483,7 +1590,7 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &start_)));
- _set_bit(0);
+ set_has_start();
} else {
goto handle_uninterpreted;
}
@@ -1499,7 +1606,7 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &end_)));
- _set_bit(1);
+ set_has_end();
} else {
goto handle_uninterpreted;
}
@@ -1526,12 +1633,12 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional int32 start = 1;
- if (_has_bit(0)) {
+ if (has_start()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
}
// optional int32 end = 2;
- if (_has_bit(1)) {
+ if (has_end()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
}
@@ -1544,12 +1651,12 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional int32 start = 1;
- if (_has_bit(0)) {
+ if (has_start()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
}
// optional int32 end = 2;
- if (_has_bit(1)) {
+ if (has_end()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
}
@@ -1605,10 +1712,10 @@ void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message
void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_start()) {
set_start(from.start());
}
- if (from._has_bit(1)) {
+ if (from.has_end()) {
set_end(from.end());
}
}
@@ -1653,7 +1760,6 @@ void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other)
// -------------------------------------------------------------------
-const ::std::string DescriptorProto::_default_name_;
#ifndef _MSC_VER
const int DescriptorProto::kNameFieldNumber;
const int DescriptorProto::kFieldFieldNumber;
@@ -1681,7 +1787,7 @@ DescriptorProto::DescriptorProto(const DescriptorProto& from)
void DescriptorProto::SharedCtor() {
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -1691,7 +1797,7 @@ DescriptorProto::~DescriptorProto() {
}
void DescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
delete name_;
}
if (this != default_instance_) {
@@ -1721,12 +1827,12 @@ DescriptorProto* DescriptorProto::New() const {
void DescriptorProto::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
}
- if (_has_bit(6)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
}
}
@@ -1869,7 +1975,7 @@ bool DescriptorProto::MergePartialFromCodedStream(
void DescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -1908,7 +2014,7 @@ void DescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.MessageOptions options = 7;
- if (_has_bit(6)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
7, this->options(), output);
}
@@ -1922,7 +2028,7 @@ void DescriptorProto::SerializeWithCachedSizes(
::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -1967,7 +2073,7 @@ void DescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.MessageOptions options = 7;
- if (_has_bit(6)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
7, this->options(), target);
@@ -2070,10 +2176,10 @@ void DescriptorProto::MergeFrom(const DescriptorProto& from) {
enum_type_.MergeFrom(from.enum_type_);
extension_range_.MergeFrom(from.extension_range_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(6)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options());
}
}
@@ -2214,10 +2320,6 @@ const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
const int FieldDescriptorProto::Label_ARRAYSIZE;
#endif // _MSC_VER
-const ::std::string FieldDescriptorProto::_default_name_;
-const ::std::string FieldDescriptorProto::_default_type_name_;
-const ::std::string FieldDescriptorProto::_default_extendee_;
-const ::std::string FieldDescriptorProto::_default_default_value_;
#ifndef _MSC_VER
const int FieldDescriptorProto::kNameFieldNumber;
const int FieldDescriptorProto::kNumberFieldNumber;
@@ -2246,13 +2348,13 @@ FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
void FieldDescriptorProto::SharedCtor() {
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
number_ = 0;
label_ = 1;
type_ = 1;
- type_name_ = const_cast< ::std::string*>(&_default_type_name_);
- extendee_ = const_cast< ::std::string*>(&_default_extendee_);
- default_value_ = const_cast< ::std::string*>(&_default_default_value_);
+ type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -2262,16 +2364,16 @@ FieldDescriptorProto::~FieldDescriptorProto() {
}
void FieldDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
delete name_;
}
- if (type_name_ != &_default_type_name_) {
+ if (type_name_ != &::google::protobuf::internal::kEmptyString) {
delete type_name_;
}
- if (extendee_ != &_default_extendee_) {
+ if (extendee_ != &::google::protobuf::internal::kEmptyString) {
delete extendee_;
}
- if (default_value_ != &_default_default_value_) {
+ if (default_value_ != &::google::protobuf::internal::kEmptyString) {
delete default_value_;
}
if (this != default_instance_) {
@@ -2301,30 +2403,30 @@ FieldDescriptorProto* FieldDescriptorProto::New() const {
void FieldDescriptorProto::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
}
number_ = 0;
label_ = 1;
type_ = 1;
- if (_has_bit(4)) {
- if (type_name_ != &_default_type_name_) {
+ if (has_type_name()) {
+ if (type_name_ != &::google::protobuf::internal::kEmptyString) {
type_name_->clear();
}
}
- if (_has_bit(5)) {
- if (extendee_ != &_default_extendee_) {
+ if (has_extendee()) {
+ if (extendee_ != &::google::protobuf::internal::kEmptyString) {
extendee_->clear();
}
}
- if (_has_bit(6)) {
- if (default_value_ != &_default_default_value_) {
+ if (has_default_value()) {
+ if (default_value_ != &::google::protobuf::internal::kEmptyString) {
default_value_->clear();
}
}
- if (_has_bit(7)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
}
}
@@ -2379,7 +2481,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &number_)));
- _set_bit(1);
+ set_has_number();
} else {
goto handle_uninterpreted;
}
@@ -2496,7 +2598,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream(
void FieldDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -2505,7 +2607,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
}
// optional string extendee = 2;
- if (_has_bit(5)) {
+ if (has_extendee()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->extendee().data(), this->extendee().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -2514,24 +2616,24 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
}
// optional int32 number = 3;
- if (_has_bit(1)) {
+ if (has_number()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output);
}
// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
- if (_has_bit(2)) {
+ if (has_label()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
4, this->label(), output);
}
// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
- if (_has_bit(3)) {
+ if (has_type()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
5, this->type(), output);
}
// optional string type_name = 6;
- if (_has_bit(4)) {
+ if (has_type_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->type_name().data(), this->type_name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -2540,7 +2642,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
}
// optional string default_value = 7;
- if (_has_bit(6)) {
+ if (has_default_value()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->default_value().data(), this->default_value().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -2549,7 +2651,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.FieldOptions options = 8;
- if (_has_bit(7)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
8, this->options(), output);
}
@@ -2563,7 +2665,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -2573,7 +2675,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
}
// optional string extendee = 2;
- if (_has_bit(5)) {
+ if (has_extendee()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->extendee().data(), this->extendee().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -2583,24 +2685,24 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
}
// optional int32 number = 3;
- if (_has_bit(1)) {
+ if (has_number()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target);
}
// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
- if (_has_bit(2)) {
+ if (has_label()) {
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
4, this->label(), target);
}
// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
- if (_has_bit(3)) {
+ if (has_type()) {
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
5, this->type(), target);
}
// optional string type_name = 6;
- if (_has_bit(4)) {
+ if (has_type_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->type_name().data(), this->type_name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -2610,7 +2712,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
}
// optional string default_value = 7;
- if (_has_bit(6)) {
+ if (has_default_value()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->default_value().data(), this->default_value().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -2620,7 +2722,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.FieldOptions options = 8;
- if (_has_bit(7)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
8, this->options(), target);
@@ -2718,28 +2820,28 @@ void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(1)) {
+ if (from.has_number()) {
set_number(from.number());
}
- if (from._has_bit(2)) {
+ if (from.has_label()) {
set_label(from.label());
}
- if (from._has_bit(3)) {
+ if (from.has_type()) {
set_type(from.type());
}
- if (from._has_bit(4)) {
+ if (from.has_type_name()) {
set_type_name(from.type_name());
}
- if (from._has_bit(5)) {
+ if (from.has_extendee()) {
set_extendee(from.extendee());
}
- if (from._has_bit(6)) {
+ if (from.has_default_value()) {
set_default_value(from.default_value());
}
- if (from._has_bit(7)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options());
}
}
@@ -2793,7 +2895,6 @@ void FieldDescriptorProto::Swap(FieldDescriptorProto* other) {
// ===================================================================
-const ::std::string EnumDescriptorProto::_default_name_;
#ifndef _MSC_VER
const int EnumDescriptorProto::kNameFieldNumber;
const int EnumDescriptorProto::kValueFieldNumber;
@@ -2817,7 +2918,7 @@ EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
void EnumDescriptorProto::SharedCtor() {
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -2827,7 +2928,7 @@ EnumDescriptorProto::~EnumDescriptorProto() {
}
void EnumDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
delete name_;
}
if (this != default_instance_) {
@@ -2857,12 +2958,12 @@ EnumDescriptorProto* EnumDescriptorProto::New() const {
void EnumDescriptorProto::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
}
- if (_has_bit(2)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
}
}
@@ -2941,7 +3042,7 @@ bool EnumDescriptorProto::MergePartialFromCodedStream(
void EnumDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -2956,7 +3057,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.EnumOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
3, this->options(), output);
}
@@ -2970,7 +3071,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -2987,7 +3088,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.EnumOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
3, this->options(), target);
@@ -3054,10 +3155,10 @@ void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
value_.MergeFrom(from.value_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(2)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options());
}
}
@@ -3109,7 +3210,6 @@ void EnumDescriptorProto::Swap(EnumDescriptorProto* other) {
// ===================================================================
-const ::std::string EnumValueDescriptorProto::_default_name_;
#ifndef _MSC_VER
const int EnumValueDescriptorProto::kNameFieldNumber;
const int EnumValueDescriptorProto::kNumberFieldNumber;
@@ -3133,7 +3233,7 @@ EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProt
void EnumValueDescriptorProto::SharedCtor() {
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
number_ = 0;
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -3144,7 +3244,7 @@ EnumValueDescriptorProto::~EnumValueDescriptorProto() {
}
void EnumValueDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
delete name_;
}
if (this != default_instance_) {
@@ -3174,13 +3274,13 @@ EnumValueDescriptorProto* EnumValueDescriptorProto::New() const {
void EnumValueDescriptorProto::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
}
number_ = 0;
- if (_has_bit(2)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
}
}
@@ -3218,7 +3318,7 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &number_)));
- _set_bit(1);
+ set_has_number();
} else {
goto handle_uninterpreted;
}
@@ -3259,7 +3359,7 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream(
void EnumValueDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -3268,12 +3368,12 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes(
}
// optional int32 number = 2;
- if (_has_bit(1)) {
+ if (has_number()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output);
}
// optional .google.protobuf.EnumValueOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
3, this->options(), output);
}
@@ -3287,7 +3387,7 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -3297,12 +3397,12 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes(
}
// optional int32 number = 2;
- if (_has_bit(1)) {
+ if (has_number()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target);
}
// optional .google.protobuf.EnumValueOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
3, this->options(), target);
@@ -3367,13 +3467,13 @@ void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from
void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(1)) {
+ if (from.has_number()) {
set_number(from.number());
}
- if (from._has_bit(2)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options());
}
}
@@ -3422,7 +3522,6 @@ void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) {
// ===================================================================
-const ::std::string ServiceDescriptorProto::_default_name_;
#ifndef _MSC_VER
const int ServiceDescriptorProto::kNameFieldNumber;
const int ServiceDescriptorProto::kMethodFieldNumber;
@@ -3446,7 +3545,7 @@ ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& fro
void ServiceDescriptorProto::SharedCtor() {
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -3456,7 +3555,7 @@ ServiceDescriptorProto::~ServiceDescriptorProto() {
}
void ServiceDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
delete name_;
}
if (this != default_instance_) {
@@ -3486,12 +3585,12 @@ ServiceDescriptorProto* ServiceDescriptorProto::New() const {
void ServiceDescriptorProto::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
}
- if (_has_bit(2)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
}
}
@@ -3570,7 +3669,7 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream(
void ServiceDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -3585,7 +3684,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.ServiceOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
3, this->options(), output);
}
@@ -3599,7 +3698,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -3616,7 +3715,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.ServiceOptions options = 3;
- if (_has_bit(2)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
3, this->options(), target);
@@ -3683,10 +3782,10 @@ void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
method_.MergeFrom(from.method_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(2)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options());
}
}
@@ -3738,9 +3837,6 @@ void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) {
// ===================================================================
-const ::std::string MethodDescriptorProto::_default_name_;
-const ::std::string MethodDescriptorProto::_default_input_type_;
-const ::std::string MethodDescriptorProto::_default_output_type_;
#ifndef _MSC_VER
const int MethodDescriptorProto::kNameFieldNumber;
const int MethodDescriptorProto::kInputTypeFieldNumber;
@@ -3765,9 +3861,9 @@ MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
void MethodDescriptorProto::SharedCtor() {
_cached_size_ = 0;
- name_ = const_cast< ::std::string*>(&_default_name_);
- input_type_ = const_cast< ::std::string*>(&_default_input_type_);
- output_type_ = const_cast< ::std::string*>(&_default_output_type_);
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -3777,13 +3873,13 @@ MethodDescriptorProto::~MethodDescriptorProto() {
}
void MethodDescriptorProto::SharedDtor() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
delete name_;
}
- if (input_type_ != &_default_input_type_) {
+ if (input_type_ != &::google::protobuf::internal::kEmptyString) {
delete input_type_;
}
- if (output_type_ != &_default_output_type_) {
+ if (output_type_ != &::google::protobuf::internal::kEmptyString) {
delete output_type_;
}
if (this != default_instance_) {
@@ -3813,22 +3909,22 @@ MethodDescriptorProto* MethodDescriptorProto::New() const {
void MethodDescriptorProto::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_ != &_default_name_) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
}
- if (_has_bit(1)) {
- if (input_type_ != &_default_input_type_) {
+ if (has_input_type()) {
+ if (input_type_ != &::google::protobuf::internal::kEmptyString) {
input_type_->clear();
}
}
- if (_has_bit(2)) {
- if (output_type_ != &_default_output_type_) {
+ if (has_output_type()) {
+ if (output_type_ != &::google::protobuf::internal::kEmptyString) {
output_type_->clear();
}
}
- if (_has_bit(3)) {
+ if (has_options()) {
if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
}
}
@@ -3925,7 +4021,7 @@ bool MethodDescriptorProto::MergePartialFromCodedStream(
void MethodDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -3934,7 +4030,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
}
// optional string input_type = 2;
- if (_has_bit(1)) {
+ if (has_input_type()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->input_type().data(), this->input_type().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -3943,7 +4039,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
}
// optional string output_type = 3;
- if (_has_bit(2)) {
+ if (has_output_type()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->output_type().data(), this->output_type().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -3952,7 +4048,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.MethodOptions options = 4;
- if (_has_bit(3)) {
+ if (has_options()) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
4, this->options(), output);
}
@@ -3966,7 +4062,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional string name = 1;
- if (_has_bit(0)) {
+ if (has_name()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name().data(), this->name().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -3976,7 +4072,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
}
// optional string input_type = 2;
- if (_has_bit(1)) {
+ if (has_input_type()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->input_type().data(), this->input_type().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -3986,7 +4082,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
}
// optional string output_type = 3;
- if (_has_bit(2)) {
+ if (has_output_type()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->output_type().data(), this->output_type().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -3996,7 +4092,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
}
// optional .google.protobuf.MethodOptions options = 4;
- if (_has_bit(3)) {
+ if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
4, this->options(), target);
@@ -4068,16 +4164,16 @@ void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name()) {
set_name(from.name());
}
- if (from._has_bit(1)) {
+ if (from.has_input_type()) {
set_input_type(from.input_type());
}
- if (from._has_bit(2)) {
+ if (from.has_output_type()) {
set_output_type(from.output_type());
}
- if (from._has_bit(3)) {
+ if (from.has_options()) {
mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options());
}
}
@@ -4150,12 +4246,11 @@ const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
const int FileOptions::OptimizeMode_ARRAYSIZE;
#endif // _MSC_VER
-const ::std::string FileOptions::_default_java_package_;
-const ::std::string FileOptions::_default_java_outer_classname_;
#ifndef _MSC_VER
const int FileOptions::kJavaPackageFieldNumber;
const int FileOptions::kJavaOuterClassnameFieldNumber;
const int FileOptions::kJavaMultipleFilesFieldNumber;
+const int FileOptions::kJavaGenerateEqualsAndHashFieldNumber;
const int FileOptions::kOptimizeForFieldNumber;
const int FileOptions::kCcGenericServicesFieldNumber;
const int FileOptions::kJavaGenericServicesFieldNumber;
@@ -4179,13 +4274,14 @@ FileOptions::FileOptions(const FileOptions& from)
void FileOptions::SharedCtor() {
_cached_size_ = 0;
- java_package_ = const_cast< ::std::string*>(&_default_java_package_);
- java_outer_classname_ = const_cast< ::std::string*>(&_default_java_outer_classname_);
+ java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
java_multiple_files_ = false;
+ java_generate_equals_and_hash_ = false;
optimize_for_ = 1;
- cc_generic_services_ = true;
- java_generic_services_ = true;
- py_generic_services_ = true;
+ cc_generic_services_ = false;
+ java_generic_services_ = false;
+ py_generic_services_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -4194,10 +4290,10 @@ FileOptions::~FileOptions() {
}
void FileOptions::SharedDtor() {
- if (java_package_ != &_default_java_package_) {
+ if (java_package_ != &::google::protobuf::internal::kEmptyString) {
delete java_package_;
}
- if (java_outer_classname_ != &_default_java_outer_classname_) {
+ if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) {
delete java_outer_classname_;
}
if (this != default_instance_) {
@@ -4227,21 +4323,22 @@ FileOptions* FileOptions::New() const {
void FileOptions::Clear() {
_extensions_.Clear();
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (java_package_ != &_default_java_package_) {
+ if (has_java_package()) {
+ if (java_package_ != &::google::protobuf::internal::kEmptyString) {
java_package_->clear();
}
}
- if (_has_bit(1)) {
- if (java_outer_classname_ != &_default_java_outer_classname_) {
+ if (has_java_outer_classname()) {
+ if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) {
java_outer_classname_->clear();
}
}
java_multiple_files_ = false;
+ java_generate_equals_and_hash_ = false;
optimize_for_ = 1;
- cc_generic_services_ = true;
- java_generic_services_ = true;
- py_generic_services_ = true;
+ cc_generic_services_ = false;
+ java_generic_services_ = false;
+ py_generic_services_ = false;
}
uninterpreted_option_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -4316,7 +4413,7 @@ bool FileOptions::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &java_multiple_files_)));
- _set_bit(2);
+ set_has_java_multiple_files();
} else {
goto handle_uninterpreted;
}
@@ -4324,7 +4421,7 @@ bool FileOptions::MergePartialFromCodedStream(
break;
}
- // optional bool cc_generic_services = 16 [default = true];
+ // optional bool cc_generic_services = 16 [default = false];
case 16: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
@@ -4332,7 +4429,7 @@ bool FileOptions::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &cc_generic_services_)));
- _set_bit(4);
+ set_has_cc_generic_services();
} else {
goto handle_uninterpreted;
}
@@ -4340,7 +4437,7 @@ bool FileOptions::MergePartialFromCodedStream(
break;
}
- // optional bool java_generic_services = 17 [default = true];
+ // optional bool java_generic_services = 17 [default = false];
case 17: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
@@ -4348,7 +4445,7 @@ bool FileOptions::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &java_generic_services_)));
- _set_bit(5);
+ set_has_java_generic_services();
} else {
goto handle_uninterpreted;
}
@@ -4356,7 +4453,7 @@ bool FileOptions::MergePartialFromCodedStream(
break;
}
- // optional bool py_generic_services = 18 [default = true];
+ // optional bool py_generic_services = 18 [default = false];
case 18: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
@@ -4364,7 +4461,23 @@ bool FileOptions::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &py_generic_services_)));
- _set_bit(6);
+ set_has_py_generic_services();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(160)) goto parse_java_generate_equals_and_hash;
+ break;
+ }
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ case 20: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_java_generate_equals_and_hash:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &java_generate_equals_and_hash_)));
+ set_has_java_generate_equals_and_hash();
} else {
goto handle_uninterpreted;
}
@@ -4411,7 +4524,7 @@ bool FileOptions::MergePartialFromCodedStream(
void FileOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional string java_package = 1;
- if (_has_bit(0)) {
+ if (has_java_package()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->java_package().data(), this->java_package().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -4420,7 +4533,7 @@ void FileOptions::SerializeWithCachedSizes(
}
// optional string java_outer_classname = 8;
- if (_has_bit(1)) {
+ if (has_java_outer_classname()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->java_outer_classname().data(), this->java_outer_classname().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -4429,31 +4542,36 @@ void FileOptions::SerializeWithCachedSizes(
}
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
- if (_has_bit(3)) {
+ if (has_optimize_for()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
9, this->optimize_for(), output);
}
// optional bool java_multiple_files = 10 [default = false];
- if (_has_bit(2)) {
+ if (has_java_multiple_files()) {
::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output);
}
- // optional bool cc_generic_services = 16 [default = true];
- if (_has_bit(4)) {
+ // optional bool cc_generic_services = 16 [default = false];
+ if (has_cc_generic_services()) {
::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output);
}
- // optional bool java_generic_services = 17 [default = true];
- if (_has_bit(5)) {
+ // optional bool java_generic_services = 17 [default = false];
+ if (has_java_generic_services()) {
::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output);
}
- // optional bool py_generic_services = 18 [default = true];
- if (_has_bit(6)) {
+ // optional bool py_generic_services = 18 [default = false];
+ if (has_py_generic_services()) {
::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output);
}
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ if (has_java_generate_equals_and_hash()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
@@ -4473,7 +4591,7 @@ void FileOptions::SerializeWithCachedSizes(
::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional string java_package = 1;
- if (_has_bit(0)) {
+ if (has_java_package()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->java_package().data(), this->java_package().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -4483,7 +4601,7 @@ void FileOptions::SerializeWithCachedSizes(
}
// optional string java_outer_classname = 8;
- if (_has_bit(1)) {
+ if (has_java_outer_classname()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->java_outer_classname().data(), this->java_outer_classname().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -4493,31 +4611,36 @@ void FileOptions::SerializeWithCachedSizes(
}
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
- if (_has_bit(3)) {
+ if (has_optimize_for()) {
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
9, this->optimize_for(), target);
}
// optional bool java_multiple_files = 10 [default = false];
- if (_has_bit(2)) {
+ if (has_java_multiple_files()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target);
}
- // optional bool cc_generic_services = 16 [default = true];
- if (_has_bit(4)) {
+ // optional bool cc_generic_services = 16 [default = false];
+ if (has_cc_generic_services()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target);
}
- // optional bool java_generic_services = 17 [default = true];
- if (_has_bit(5)) {
+ // optional bool java_generic_services = 17 [default = false];
+ if (has_java_generic_services()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target);
}
- // optional bool py_generic_services = 18 [default = true];
- if (_has_bit(6)) {
+ // optional bool py_generic_services = 18 [default = false];
+ if (has_py_generic_services()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target);
}
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ if (has_java_generate_equals_and_hash()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target);
+ }
+
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (int i = 0; i < this->uninterpreted_option_size(); i++) {
target = ::google::protobuf::internal::WireFormatLite::
@@ -4559,23 +4682,28 @@ int FileOptions::ByteSize() const {
total_size += 1 + 1;
}
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ if (has_java_generate_equals_and_hash()) {
+ total_size += 2 + 1;
+ }
+
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
if (has_optimize_for()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for());
}
- // optional bool cc_generic_services = 16 [default = true];
+ // optional bool cc_generic_services = 16 [default = false];
if (has_cc_generic_services()) {
total_size += 2 + 1;
}
- // optional bool java_generic_services = 17 [default = true];
+ // optional bool java_generic_services = 17 [default = false];
if (has_java_generic_services()) {
total_size += 2 + 1;
}
- // optional bool py_generic_services = 18 [default = true];
+ // optional bool py_generic_services = 18 [default = false];
if (has_py_generic_services()) {
total_size += 2 + 1;
}
@@ -4618,25 +4746,28 @@ void FileOptions::MergeFrom(const FileOptions& from) {
GOOGLE_CHECK_NE(&from, this);
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_java_package()) {
set_java_package(from.java_package());
}
- if (from._has_bit(1)) {
+ if (from.has_java_outer_classname()) {
set_java_outer_classname(from.java_outer_classname());
}
- if (from._has_bit(2)) {
+ if (from.has_java_multiple_files()) {
set_java_multiple_files(from.java_multiple_files());
}
- if (from._has_bit(3)) {
+ if (from.has_java_generate_equals_and_hash()) {
+ set_java_generate_equals_and_hash(from.java_generate_equals_and_hash());
+ }
+ if (from.has_optimize_for()) {
set_optimize_for(from.optimize_for());
}
- if (from._has_bit(4)) {
+ if (from.has_cc_generic_services()) {
set_cc_generic_services(from.cc_generic_services());
}
- if (from._has_bit(5)) {
+ if (from.has_java_generic_services()) {
set_java_generic_services(from.java_generic_services());
}
- if (from._has_bit(6)) {
+ if (from.has_py_generic_services()) {
set_py_generic_services(from.py_generic_services());
}
}
@@ -4670,6 +4801,7 @@ void FileOptions::Swap(FileOptions* other) {
std::swap(java_package_, other->java_package_);
std::swap(java_outer_classname_, other->java_outer_classname_);
std::swap(java_multiple_files_, other->java_multiple_files_);
+ std::swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_);
std::swap(optimize_for_, other->optimize_for_);
std::swap(cc_generic_services_, other->cc_generic_services_);
std::swap(java_generic_services_, other->java_generic_services_);
@@ -4773,7 +4905,7 @@ bool MessageOptions::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &message_set_wire_format_)));
- _set_bit(0);
+ set_has_message_set_wire_format();
} else {
goto handle_uninterpreted;
}
@@ -4789,7 +4921,7 @@ bool MessageOptions::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &no_standard_descriptor_accessor_)));
- _set_bit(1);
+ set_has_no_standard_descriptor_accessor();
} else {
goto handle_uninterpreted;
}
@@ -4836,12 +4968,12 @@ bool MessageOptions::MergePartialFromCodedStream(
void MessageOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional bool message_set_wire_format = 1 [default = false];
- if (_has_bit(0)) {
+ if (has_message_set_wire_format()) {
::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output);
}
// optional bool no_standard_descriptor_accessor = 2 [default = false];
- if (_has_bit(1)) {
+ if (has_no_standard_descriptor_accessor()) {
::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output);
}
@@ -4864,12 +4996,12 @@ void MessageOptions::SerializeWithCachedSizes(
::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional bool message_set_wire_format = 1 [default = false];
- if (_has_bit(0)) {
+ if (has_message_set_wire_format()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target);
}
// optional bool no_standard_descriptor_accessor = 2 [default = false];
- if (_has_bit(1)) {
+ if (has_no_standard_descriptor_accessor()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target);
}
@@ -4943,10 +5075,10 @@ void MessageOptions::MergeFrom(const MessageOptions& from) {
GOOGLE_CHECK_NE(&from, this);
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_message_set_wire_format()) {
set_message_set_wire_format(from.message_set_wire_format());
}
- if (from._has_bit(1)) {
+ if (from.has_no_standard_descriptor_accessor()) {
set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor());
}
}
@@ -5021,7 +5153,6 @@ const FieldOptions_CType FieldOptions::CType_MIN;
const FieldOptions_CType FieldOptions::CType_MAX;
const int FieldOptions::CType_ARRAYSIZE;
#endif // _MSC_VER
-const ::std::string FieldOptions::_default_experimental_map_key_;
#ifndef _MSC_VER
const int FieldOptions::kCtypeFieldNumber;
const int FieldOptions::kPackedFieldNumber;
@@ -5049,7 +5180,7 @@ void FieldOptions::SharedCtor() {
ctype_ = 0;
packed_ = false;
deprecated_ = false;
- experimental_map_key_ = const_cast< ::std::string*>(&_default_experimental_map_key_);
+ experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -5058,7 +5189,7 @@ FieldOptions::~FieldOptions() {
}
void FieldOptions::SharedDtor() {
- if (experimental_map_key_ != &_default_experimental_map_key_) {
+ if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
delete experimental_map_key_;
}
if (this != default_instance_) {
@@ -5091,8 +5222,8 @@ void FieldOptions::Clear() {
ctype_ = 0;
packed_ = false;
deprecated_ = false;
- if (_has_bit(3)) {
- if (experimental_map_key_ != &_default_experimental_map_key_) {
+ if (has_experimental_map_key()) {
+ if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
experimental_map_key_->clear();
}
}
@@ -5136,7 +5267,7 @@ bool FieldOptions::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &packed_)));
- _set_bit(1);
+ set_has_packed();
} else {
goto handle_uninterpreted;
}
@@ -5152,7 +5283,7 @@ bool FieldOptions::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &deprecated_)));
- _set_bit(2);
+ set_has_deprecated();
} else {
goto handle_uninterpreted;
}
@@ -5216,23 +5347,23 @@ bool FieldOptions::MergePartialFromCodedStream(
void FieldOptions::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
- if (_has_bit(0)) {
+ if (has_ctype()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
1, this->ctype(), output);
}
// optional bool packed = 2;
- if (_has_bit(1)) {
+ if (has_packed()) {
::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output);
}
// optional bool deprecated = 3 [default = false];
- if (_has_bit(2)) {
+ if (has_deprecated()) {
::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
}
// optional string experimental_map_key = 9;
- if (_has_bit(3)) {
+ if (has_experimental_map_key()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->experimental_map_key().data(), this->experimental_map_key().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -5259,23 +5390,23 @@ void FieldOptions::SerializeWithCachedSizes(
::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
- if (_has_bit(0)) {
+ if (has_ctype()) {
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
1, this->ctype(), target);
}
// optional bool packed = 2;
- if (_has_bit(1)) {
+ if (has_packed()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target);
}
// optional bool deprecated = 3 [default = false];
- if (_has_bit(2)) {
+ if (has_deprecated()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
}
// optional string experimental_map_key = 9;
- if (_has_bit(3)) {
+ if (has_experimental_map_key()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->experimental_map_key().data(), this->experimental_map_key().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -5367,16 +5498,16 @@ void FieldOptions::MergeFrom(const FieldOptions& from) {
GOOGLE_CHECK_NE(&from, this);
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_ctype()) {
set_ctype(from.ctype());
}
- if (from._has_bit(1)) {
+ if (from.has_packed()) {
set_packed(from.packed());
}
- if (from._has_bit(2)) {
+ if (from.has_deprecated()) {
set_deprecated(from.deprecated());
}
- if (from._has_bit(3)) {
+ if (from.has_experimental_map_key()) {
set_experimental_map_key(from.experimental_map_key());
}
}
@@ -6326,7 +6457,6 @@ void MethodOptions::Swap(MethodOptions* other) {
// ===================================================================
-const ::std::string UninterpretedOption_NamePart::_default_name_part_;
#ifndef _MSC_VER
const int UninterpretedOption_NamePart::kNamePartFieldNumber;
const int UninterpretedOption_NamePart::kIsExtensionFieldNumber;
@@ -6348,7 +6478,7 @@ UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOp
void UninterpretedOption_NamePart::SharedCtor() {
_cached_size_ = 0;
- name_part_ = const_cast< ::std::string*>(&_default_name_part_);
+ name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
is_extension_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -6358,7 +6488,7 @@ UninterpretedOption_NamePart::~UninterpretedOption_NamePart() {
}
void UninterpretedOption_NamePart::SharedDtor() {
- if (name_part_ != &_default_name_part_) {
+ if (name_part_ != &::google::protobuf::internal::kEmptyString) {
delete name_part_;
}
if (this != default_instance_) {
@@ -6387,8 +6517,8 @@ UninterpretedOption_NamePart* UninterpretedOption_NamePart::New() const {
void UninterpretedOption_NamePart::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (_has_bit(0)) {
- if (name_part_ != &_default_name_part_) {
+ if (has_name_part()) {
+ if (name_part_ != &::google::protobuf::internal::kEmptyString) {
name_part_->clear();
}
}
@@ -6428,7 +6558,7 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
input, &is_extension_)));
- _set_bit(1);
+ set_has_is_extension();
} else {
goto handle_uninterpreted;
}
@@ -6455,7 +6585,7 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
void UninterpretedOption_NamePart::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// required string name_part = 1;
- if (_has_bit(0)) {
+ if (has_name_part()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name_part().data(), this->name_part().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -6464,7 +6594,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes(
}
// required bool is_extension = 2;
- if (_has_bit(1)) {
+ if (has_is_extension()) {
::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output);
}
@@ -6477,7 +6607,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes(
::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray(
::google::protobuf::uint8* target) const {
// required string name_part = 1;
- if (_has_bit(0)) {
+ if (has_name_part()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->name_part().data(), this->name_part().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -6487,7 +6617,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes(
}
// required bool is_extension = 2;
- if (_has_bit(1)) {
+ if (has_is_extension()) {
target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target);
}
@@ -6541,10 +6671,10 @@ void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message&
void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
+ if (from.has_name_part()) {
set_name_part(from.name_part());
}
- if (from._has_bit(1)) {
+ if (from.has_is_extension()) {
set_is_extension(from.is_extension());
}
}
@@ -6590,8 +6720,6 @@ void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) {
// -------------------------------------------------------------------
-const ::std::string UninterpretedOption::_default_identifier_value_;
-const ::std::string UninterpretedOption::_default_string_value_;
#ifndef _MSC_VER
const int UninterpretedOption::kNameFieldNumber;
const int UninterpretedOption::kIdentifierValueFieldNumber;
@@ -6599,6 +6727,7 @@ const int UninterpretedOption::kPositiveIntValueFieldNumber;
const int UninterpretedOption::kNegativeIntValueFieldNumber;
const int UninterpretedOption::kDoubleValueFieldNumber;
const int UninterpretedOption::kStringValueFieldNumber;
+const int UninterpretedOption::kAggregateValueFieldNumber;
#endif // !_MSC_VER
UninterpretedOption::UninterpretedOption()
@@ -6617,11 +6746,12 @@ UninterpretedOption::UninterpretedOption(const UninterpretedOption& from)
void UninterpretedOption::SharedCtor() {
_cached_size_ = 0;
- identifier_value_ = const_cast< ::std::string*>(&_default_identifier_value_);
+ identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
positive_int_value_ = GOOGLE_ULONGLONG(0);
negative_int_value_ = GOOGLE_LONGLONG(0);
double_value_ = 0;
- string_value_ = const_cast< ::std::string*>(&_default_string_value_);
+ string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -6630,12 +6760,15 @@ UninterpretedOption::~UninterpretedOption() {
}
void UninterpretedOption::SharedDtor() {
- if (identifier_value_ != &_default_identifier_value_) {
+ if (identifier_value_ != &::google::protobuf::internal::kEmptyString) {
delete identifier_value_;
}
- if (string_value_ != &_default_string_value_) {
+ if (string_value_ != &::google::protobuf::internal::kEmptyString) {
delete string_value_;
}
+ if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) {
+ delete aggregate_value_;
+ }
if (this != default_instance_) {
}
}
@@ -6662,19 +6795,24 @@ UninterpretedOption* UninterpretedOption::New() const {
void UninterpretedOption::Clear() {
if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
- if (_has_bit(1)) {
- if (identifier_value_ != &_default_identifier_value_) {
+ if (has_identifier_value()) {
+ if (identifier_value_ != &::google::protobuf::internal::kEmptyString) {
identifier_value_->clear();
}
}
positive_int_value_ = GOOGLE_ULONGLONG(0);
negative_int_value_ = GOOGLE_LONGLONG(0);
double_value_ = 0;
- if (_has_bit(5)) {
- if (string_value_ != &_default_string_value_) {
+ if (has_string_value()) {
+ if (string_value_ != &::google::protobuf::internal::kEmptyString) {
string_value_->clear();
}
}
+ if (has_aggregate_value()) {
+ if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_->clear();
+ }
+ }
}
name_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -6727,7 +6865,7 @@ bool UninterpretedOption::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
input, &positive_int_value_)));
- _set_bit(2);
+ set_has_positive_int_value();
} else {
goto handle_uninterpreted;
}
@@ -6743,7 +6881,7 @@ bool UninterpretedOption::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
input, &negative_int_value_)));
- _set_bit(3);
+ set_has_negative_int_value();
} else {
goto handle_uninterpreted;
}
@@ -6759,7 +6897,7 @@ bool UninterpretedOption::MergePartialFromCodedStream(
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
input, &double_value_)));
- _set_bit(4);
+ set_has_double_value();
} else {
goto handle_uninterpreted;
}
@@ -6777,6 +6915,23 @@ bool UninterpretedOption::MergePartialFromCodedStream(
} else {
goto handle_uninterpreted;
}
+ if (input->ExpectTag(66)) goto parse_aggregate_value;
+ break;
+ }
+
+ // optional string aggregate_value = 8;
+ case 8: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_aggregate_value:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_aggregate_value()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->aggregate_value().data(), this->aggregate_value().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
if (input->ExpectAtEnd()) return true;
break;
}
@@ -6806,7 +6961,7 @@ void UninterpretedOption::SerializeWithCachedSizes(
}
// optional string identifier_value = 3;
- if (_has_bit(1)) {
+ if (has_identifier_value()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->identifier_value().data(), this->identifier_value().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -6815,26 +6970,35 @@ void UninterpretedOption::SerializeWithCachedSizes(
}
// optional uint64 positive_int_value = 4;
- if (_has_bit(2)) {
+ if (has_positive_int_value()) {
::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output);
}
// optional int64 negative_int_value = 5;
- if (_has_bit(3)) {
+ if (has_negative_int_value()) {
::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output);
}
// optional double double_value = 6;
- if (_has_bit(4)) {
+ if (has_double_value()) {
::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output);
}
// optional bytes string_value = 7;
- if (_has_bit(5)) {
+ if (has_string_value()) {
::google::protobuf::internal::WireFormatLite::WriteBytes(
7, this->string_value(), output);
}
+ // optional string aggregate_value = 8;
+ if (has_aggregate_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->aggregate_value().data(), this->aggregate_value().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 8, this->aggregate_value(), output);
+ }
+
if (!unknown_fields().empty()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
@@ -6851,7 +7015,7 @@ void UninterpretedOption::SerializeWithCachedSizes(
}
// optional string identifier_value = 3;
- if (_has_bit(1)) {
+ if (has_identifier_value()) {
::google::protobuf::internal::WireFormat::VerifyUTF8String(
this->identifier_value().data(), this->identifier_value().length(),
::google::protobuf::internal::WireFormat::SERIALIZE);
@@ -6861,27 +7025,37 @@ void UninterpretedOption::SerializeWithCachedSizes(
}
// optional uint64 positive_int_value = 4;
- if (_has_bit(2)) {
+ if (has_positive_int_value()) {
target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target);
}
// optional int64 negative_int_value = 5;
- if (_has_bit(3)) {
+ if (has_negative_int_value()) {
target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target);
}
// optional double double_value = 6;
- if (_has_bit(4)) {
+ if (has_double_value()) {
target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target);
}
// optional bytes string_value = 7;
- if (_has_bit(5)) {
+ if (has_string_value()) {
target =
::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
7, this->string_value(), target);
}
+ // optional string aggregate_value = 8;
+ if (has_aggregate_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->aggregate_value().data(), this->aggregate_value().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 8, this->aggregate_value(), target);
+ }
+
if (!unknown_fields().empty()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
@@ -6926,6 +7100,13 @@ int UninterpretedOption::ByteSize() const {
this->string_value());
}
+ // optional string aggregate_value = 8;
+ if (has_aggregate_value()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->aggregate_value());
+ }
+
}
// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
total_size += 1 * this->name_size();
@@ -6962,21 +7143,24 @@ void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
GOOGLE_CHECK_NE(&from, this);
name_.MergeFrom(from.name_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
- if (from._has_bit(1)) {
+ if (from.has_identifier_value()) {
set_identifier_value(from.identifier_value());
}
- if (from._has_bit(2)) {
+ if (from.has_positive_int_value()) {
set_positive_int_value(from.positive_int_value());
}
- if (from._has_bit(3)) {
+ if (from.has_negative_int_value()) {
set_negative_int_value(from.negative_int_value());
}
- if (from._has_bit(4)) {
+ if (from.has_double_value()) {
set_double_value(from.double_value());
}
- if (from._has_bit(5)) {
+ if (from.has_string_value()) {
set_string_value(from.string_value());
}
+ if (from.has_aggregate_value()) {
+ set_aggregate_value(from.aggregate_value());
+ }
}
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}
@@ -7009,6 +7193,7 @@ void UninterpretedOption::Swap(UninterpretedOption* other) {
std::swap(negative_int_value_, other->negative_int_value_);
std::swap(double_value_, other->double_value_);
std::swap(string_value_, other->string_value_);
+ std::swap(aggregate_value_, other->aggregate_value_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_unknown_fields_.Swap(&other->_unknown_fields_);
std::swap(_cached_size_, other->_cached_size_);
@@ -7024,6 +7209,497 @@ void UninterpretedOption::Swap(UninterpretedOption* other) {
}
+// ===================================================================
+
+#ifndef _MSC_VER
+const int SourceCodeInfo_Location::kPathFieldNumber;
+const int SourceCodeInfo_Location::kSpanFieldNumber;
+#endif // !_MSC_VER
+
+SourceCodeInfo_Location::SourceCodeInfo_Location()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void SourceCodeInfo_Location::InitAsDefaultInstance() {
+}
+
+SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void SourceCodeInfo_Location::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SourceCodeInfo_Location::~SourceCodeInfo_Location() {
+ SharedDtor();
+}
+
+void SourceCodeInfo_Location::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void SourceCodeInfo_Location::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return SourceCodeInfo_Location_descriptor_;
+}
+
+const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+}
+
+SourceCodeInfo_Location* SourceCodeInfo_Location::default_instance_ = NULL;
+
+SourceCodeInfo_Location* SourceCodeInfo_Location::New() const {
+ return new SourceCodeInfo_Location;
+}
+
+void SourceCodeInfo_Location::Clear() {
+ path_.Clear();
+ span_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool SourceCodeInfo_Location::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated int32 path = 1 [packed = true];
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, this->mutable_path())));
+ } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
+ == ::google::protobuf::internal::WireFormatLite::
+ WIRETYPE_VARINT) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ 1, 10, input, this->mutable_path())));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_span;
+ break;
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_span:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, this->mutable_span())));
+ } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
+ == ::google::protobuf::internal::WireFormatLite::
+ WIRETYPE_VARINT) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ 1, 18, input, this->mutable_span())));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void SourceCodeInfo_Location::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated int32 path = 1 [packed = true];
+ if (this->path_size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+ output->WriteVarint32(_path_cached_byte_size_);
+ }
+ for (int i = 0; i < this->path_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
+ this->path(i), output);
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ if (this->span_size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+ output->WriteVarint32(_span_cached_byte_size_);
+ }
+ for (int i = 0; i < this->span_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
+ this->span(i), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* SourceCodeInfo_Location::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated int32 path = 1 [packed = true];
+ if (this->path_size() > 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+ 1,
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ target);
+ target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+ _path_cached_byte_size_, target);
+ }
+ for (int i = 0; i < this->path_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteInt32NoTagToArray(this->path(i), target);
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ if (this->span_size() > 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+ 2,
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ target);
+ target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+ _span_cached_byte_size_, target);
+ }
+ for (int i = 0; i < this->span_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteInt32NoTagToArray(this->span(i), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int SourceCodeInfo_Location::ByteSize() const {
+ int total_size = 0;
+
+ // repeated int32 path = 1 [packed = true];
+ {
+ int data_size = 0;
+ for (int i = 0; i < this->path_size(); i++) {
+ data_size += ::google::protobuf::internal::WireFormatLite::
+ Int32Size(this->path(i));
+ }
+ if (data_size > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+ }
+ _path_cached_byte_size_ = data_size;
+ total_size += data_size;
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ {
+ int data_size = 0;
+ for (int i = 0; i < this->span_size(); i++) {
+ data_size += ::google::protobuf::internal::WireFormatLite::
+ Int32Size(this->span(i));
+ }
+ if (data_size > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+ }
+ _span_cached_byte_size_ = data_size;
+ total_size += data_size;
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const SourceCodeInfo_Location* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo_Location*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ path_.MergeFrom(from.path_);
+ span_.MergeFrom(from.span_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void SourceCodeInfo_Location::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SourceCodeInfo_Location::IsInitialized() const {
+
+ return true;
+}
+
+void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) {
+ if (other != this) {
+ path_.Swap(&other->path_);
+ span_.Swap(&other->span_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = SourceCodeInfo_Location_descriptor_;
+ metadata.reflection = SourceCodeInfo_Location_reflection_;
+ return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int SourceCodeInfo::kLocationFieldNumber;
+#endif // !_MSC_VER
+
+SourceCodeInfo::SourceCodeInfo()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void SourceCodeInfo::InitAsDefaultInstance() {
+}
+
+SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void SourceCodeInfo::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SourceCodeInfo::~SourceCodeInfo() {
+ SharedDtor();
+}
+
+void SourceCodeInfo::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void SourceCodeInfo::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return SourceCodeInfo_descriptor_;
+}
+
+const SourceCodeInfo& SourceCodeInfo::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_;
+}
+
+SourceCodeInfo* SourceCodeInfo::default_instance_ = NULL;
+
+SourceCodeInfo* SourceCodeInfo::New() const {
+ return new SourceCodeInfo;
+}
+
+void SourceCodeInfo::Clear() {
+ location_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool SourceCodeInfo::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_location:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_location()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(10)) goto parse_location;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void SourceCodeInfo::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ for (int i = 0; i < this->location_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 1, this->location(i), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* SourceCodeInfo::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ for (int i = 0; i < this->location_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 1, this->location(i), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int SourceCodeInfo::ByteSize() const {
+ int total_size = 0;
+
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ total_size += 1 * this->location_size();
+ for (int i = 0; i < this->location_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->location(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const SourceCodeInfo* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ location_.MergeFrom(from.location_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void SourceCodeInfo::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SourceCodeInfo::IsInitialized() const {
+
+ return true;
+}
+
+void SourceCodeInfo::Swap(SourceCodeInfo* other) {
+ if (other != this) {
+ location_.Swap(&other->location_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = SourceCodeInfo_descriptor_;
+ metadata.reflection = SourceCodeInfo_reflection_;
+ return metadata;
+}
+
+
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 205c5476..e85a9336 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -51,6 +51,8 @@ class ServiceOptions;
class MethodOptions;
class UninterpretedOption;
class UninterpretedOption_NamePart;
+class SourceCodeInfo;
+class SourceCodeInfo_Location;
enum FieldDescriptorProto_Type {
FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
@@ -217,26 +219,17 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message
// @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
private:
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static FileDescriptorSet* default_instance_;
@@ -306,6 +299,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
// optional string package = 2;
inline bool has_package() const;
@@ -316,6 +310,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
inline void set_package(const char* value);
inline void set_package(const char* value, size_t size);
inline ::std::string* mutable_package();
+ inline ::std::string* release_package();
// repeated string dependency = 3;
inline int dependency_size() const;
@@ -387,39 +382,46 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
static const int kOptionsFieldNumber = 8;
inline const ::google::protobuf::FileOptions& options() const;
inline ::google::protobuf::FileOptions* mutable_options();
+ inline ::google::protobuf::FileOptions* release_options();
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ inline bool has_source_code_info() const;
+ inline void clear_source_code_info();
+ static const int kSourceCodeInfoFieldNumber = 9;
+ inline const ::google::protobuf::SourceCodeInfo& source_code_info() const;
+ inline ::google::protobuf::SourceCodeInfo* mutable_source_code_info();
+ inline ::google::protobuf::SourceCodeInfo* release_source_code_info();
// @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_package();
+ inline void clear_has_package();
+ inline void set_has_options();
+ inline void clear_has_options();
+ inline void set_has_source_code_info();
+ inline void clear_has_source_code_info();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* name_;
- static const ::std::string _default_name_;
::std::string* package_;
- static const ::std::string _default_package_;
::google::protobuf::RepeatedPtrField< ::std::string> dependency_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
::google::protobuf::FileOptions* options_;
+ ::google::protobuf::SourceCodeInfo* source_code_info_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32];
+
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
- ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
void InitAsDefaultInstance();
static FileDescriptorProto* default_instance_;
};
@@ -495,27 +497,22 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto
// @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
private:
+ inline void set_has_start();
+ inline void clear_has_start();
+ inline void set_has_end();
+ inline void clear_has_end();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::google::protobuf::int32 start_;
::google::protobuf::int32 end_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static DescriptorProto_ExtensionRange* default_instance_;
@@ -587,6 +584,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
// repeated .google.protobuf.FieldDescriptorProto field = 2;
inline int field_size() const;
@@ -654,36 +652,31 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
static const int kOptionsFieldNumber = 7;
inline const ::google::protobuf::MessageOptions& options() const;
inline ::google::protobuf::MessageOptions* mutable_options();
+ inline ::google::protobuf::MessageOptions* release_options();
// @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* name_;
- static const ::std::string _default_name_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_;
::google::protobuf::MessageOptions* options_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static DescriptorProto* default_instance_;
@@ -818,6 +811,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
// optional int32 number = 3;
inline bool has_number() const;
@@ -849,6 +843,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
inline void set_type_name(const char* value);
inline void set_type_name(const char* value, size_t size);
inline ::std::string* mutable_type_name();
+ inline ::std::string* release_type_name();
// optional string extendee = 2;
inline bool has_extendee() const;
@@ -859,6 +854,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
inline void set_extendee(const char* value);
inline void set_extendee(const char* value, size_t size);
inline ::std::string* mutable_extendee();
+ inline ::std::string* release_extendee();
// optional string default_value = 7;
inline bool has_default_value() const;
@@ -869,6 +865,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
inline void set_default_value(const char* value);
inline void set_default_value(const char* value, size_t size);
inline ::std::string* mutable_default_value();
+ inline ::std::string* release_default_value();
// optional .google.protobuf.FieldOptions options = 8;
inline bool has_options() const;
@@ -876,40 +873,44 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
static const int kOptionsFieldNumber = 8;
inline const ::google::protobuf::FieldOptions& options() const;
inline ::google::protobuf::FieldOptions* mutable_options();
+ inline ::google::protobuf::FieldOptions* release_options();
// @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_number();
+ inline void clear_has_number();
+ inline void set_has_label();
+ inline void clear_has_label();
+ inline void set_has_type();
+ inline void clear_has_type();
+ inline void set_has_type_name();
+ inline void clear_has_type_name();
+ inline void set_has_extendee();
+ inline void clear_has_extendee();
+ inline void set_has_default_value();
+ inline void clear_has_default_value();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* name_;
- static const ::std::string _default_name_;
::google::protobuf::int32 number_;
int label_;
- int type_;
::std::string* type_name_;
- static const ::std::string _default_type_name_;
::std::string* extendee_;
- static const ::std::string _default_extendee_;
::std::string* default_value_;
- static const ::std::string _default_default_value_;
::google::protobuf::FieldOptions* options_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ int type_;
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(8 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static FieldDescriptorProto* default_instance_;
@@ -979,6 +980,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
inline int value_size() const;
@@ -998,32 +1000,27 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
static const int kOptionsFieldNumber = 3;
inline const ::google::protobuf::EnumOptions& options() const;
inline ::google::protobuf::EnumOptions* mutable_options();
+ inline ::google::protobuf::EnumOptions* release_options();
// @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* name_;
- static const ::std::string _default_name_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
::google::protobuf::EnumOptions* options_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static EnumDescriptorProto* default_instance_;
@@ -1093,6 +1090,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
// optional int32 number = 2;
inline bool has_number() const;
@@ -1107,32 +1105,29 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
static const int kOptionsFieldNumber = 3;
inline const ::google::protobuf::EnumValueOptions& options() const;
inline ::google::protobuf::EnumValueOptions* mutable_options();
+ inline ::google::protobuf::EnumValueOptions* release_options();
// @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_number();
+ inline void clear_has_number();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* name_;
- static const ::std::string _default_name_;
- ::google::protobuf::int32 number_;
::google::protobuf::EnumValueOptions* options_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ ::google::protobuf::int32 number_;
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static EnumValueDescriptorProto* default_instance_;
@@ -1202,6 +1197,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
// repeated .google.protobuf.MethodDescriptorProto method = 2;
inline int method_size() const;
@@ -1221,32 +1217,27 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
static const int kOptionsFieldNumber = 3;
inline const ::google::protobuf::ServiceOptions& options() const;
inline ::google::protobuf::ServiceOptions* mutable_options();
+ inline ::google::protobuf::ServiceOptions* release_options();
// @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* name_;
- static const ::std::string _default_name_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
::google::protobuf::ServiceOptions* options_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static ServiceDescriptorProto* default_instance_;
@@ -1316,6 +1307,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
inline void set_name(const char* value);
inline void set_name(const char* value, size_t size);
inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
// optional string input_type = 2;
inline bool has_input_type() const;
@@ -1326,6 +1318,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
inline void set_input_type(const char* value);
inline void set_input_type(const char* value, size_t size);
inline ::std::string* mutable_input_type();
+ inline ::std::string* release_input_type();
// optional string output_type = 3;
inline bool has_output_type() const;
@@ -1336,6 +1329,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
inline void set_output_type(const char* value);
inline void set_output_type(const char* value, size_t size);
inline ::std::string* mutable_output_type();
+ inline ::std::string* release_output_type();
// optional .google.protobuf.MethodOptions options = 4;
inline bool has_options() const;
@@ -1343,35 +1337,32 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
static const int kOptionsFieldNumber = 4;
inline const ::google::protobuf::MethodOptions& options() const;
inline ::google::protobuf::MethodOptions* mutable_options();
+ inline ::google::protobuf::MethodOptions* release_options();
// @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_input_type();
+ inline void clear_has_input_type();
+ inline void set_has_output_type();
+ inline void clear_has_output_type();
+ inline void set_has_options();
+ inline void clear_has_options();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* name_;
- static const ::std::string _default_name_;
::std::string* input_type_;
- static const ::std::string _default_input_type_;
::std::string* output_type_;
- static const ::std::string _default_output_type_;
::google::protobuf::MethodOptions* options_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(4 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static MethodDescriptorProto* default_instance_;
@@ -1466,6 +1457,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
inline void set_java_package(const char* value);
inline void set_java_package(const char* value, size_t size);
inline ::std::string* mutable_java_package();
+ inline ::std::string* release_java_package();
// optional string java_outer_classname = 8;
inline bool has_java_outer_classname() const;
@@ -1476,6 +1468,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
inline void set_java_outer_classname(const char* value);
inline void set_java_outer_classname(const char* value, size_t size);
inline ::std::string* mutable_java_outer_classname();
+ inline ::std::string* release_java_outer_classname();
// optional bool java_multiple_files = 10 [default = false];
inline bool has_java_multiple_files() const;
@@ -1484,6 +1477,13 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
inline bool java_multiple_files() const;
inline void set_java_multiple_files(bool value);
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ inline bool has_java_generate_equals_and_hash() const;
+ inline void clear_java_generate_equals_and_hash();
+ static const int kJavaGenerateEqualsAndHashFieldNumber = 20;
+ inline bool java_generate_equals_and_hash() const;
+ inline void set_java_generate_equals_and_hash(bool value);
+
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
inline bool has_optimize_for() const;
inline void clear_optimize_for();
@@ -1491,21 +1491,21 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const;
inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);
- // optional bool cc_generic_services = 16 [default = true];
+ // optional bool cc_generic_services = 16 [default = false];
inline bool has_cc_generic_services() const;
inline void clear_cc_generic_services();
static const int kCcGenericServicesFieldNumber = 16;
inline bool cc_generic_services() const;
inline void set_cc_generic_services(bool value);
- // optional bool java_generic_services = 17 [default = true];
+ // optional bool java_generic_services = 17 [default = false];
inline bool has_java_generic_services() const;
inline void clear_java_generic_services();
static const int kJavaGenericServicesFieldNumber = 17;
inline bool java_generic_services() const;
inline void set_java_generic_services(bool value);
- // optional bool py_generic_services = 18 [default = true];
+ // optional bool py_generic_services = 18 [default = false];
inline bool has_py_generic_services() const;
inline void clear_py_generic_services();
static const int kPyGenericServicesFieldNumber = 18;
@@ -1527,37 +1527,44 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
private:
+ inline void set_has_java_package();
+ inline void clear_has_java_package();
+ inline void set_has_java_outer_classname();
+ inline void clear_has_java_outer_classname();
+ inline void set_has_java_multiple_files();
+ inline void clear_has_java_multiple_files();
+ inline void set_has_java_generate_equals_and_hash();
+ inline void clear_has_java_generate_equals_and_hash();
+ inline void set_has_optimize_for();
+ inline void clear_has_optimize_for();
+ inline void set_has_cc_generic_services();
+ inline void clear_has_cc_generic_services();
+ inline void set_has_java_generic_services();
+ inline void clear_has_java_generic_services();
+ inline void set_has_py_generic_services();
+ inline void clear_has_py_generic_services();
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* java_package_;
- static const ::std::string _default_java_package_;
::std::string* java_outer_classname_;
- static const ::std::string _default_java_outer_classname_;
- bool java_multiple_files_;
int optimize_for_;
+ bool java_multiple_files_;
+ bool java_generate_equals_and_hash_;
bool cc_generic_services_;
bool java_generic_services_;
- bool py_generic_services_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+ bool py_generic_services_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32];
+
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
- ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
void InitAsDefaultInstance();
static FileOptions* default_instance_;
};
@@ -1646,29 +1653,25 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
private:
+ inline void set_has_message_set_wire_format();
+ inline void clear_has_message_set_wire_format();
+ inline void set_has_no_standard_descriptor_accessor();
+ inline void clear_has_no_standard_descriptor_accessor();
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
bool message_set_wire_format_;
bool no_standard_descriptor_accessor_;
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static MessageOptions* default_instance_;
@@ -1784,6 +1787,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
inline void set_experimental_map_key(const char* value);
inline void set_experimental_map_key(const char* value, size_t size);
inline ::std::string* mutable_experimental_map_key();
+ inline ::std::string* release_experimental_map_key();
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int uninterpreted_option_size() const;
@@ -1800,32 +1804,31 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
private:
+ inline void set_has_ctype();
+ inline void clear_has_ctype();
+ inline void set_has_packed();
+ inline void clear_has_packed();
+ inline void set_has_deprecated();
+ inline void clear_has_deprecated();
+ inline void set_has_experimental_map_key();
+ inline void clear_has_experimental_map_key();
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
int ctype_;
bool packed_;
bool deprecated_;
::std::string* experimental_map_key_;
- static const ::std::string _default_experimental_map_key_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(5 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static FieldOptions* default_instance_;
@@ -1901,27 +1904,19 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
private:
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static EnumOptions* default_instance_;
@@ -1997,27 +1992,19 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
private:
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static EnumValueOptions* default_instance_;
@@ -2093,27 +2080,19 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
private:
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static ServiceOptions* default_instance_;
@@ -2189,27 +2168,19 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
private:
+
::google::protobuf::internal::ExtensionSet _extensions_;
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static MethodOptions* default_instance_;
@@ -2279,6 +2250,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu
inline void set_name_part(const char* value);
inline void set_name_part(const char* value, size_t size);
inline ::std::string* mutable_name_part();
+ inline ::std::string* release_name_part();
// required bool is_extension = 2;
inline bool has_is_extension() const;
@@ -2289,28 +2261,22 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu
// @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
private:
+ inline void set_has_name_part();
+ inline void clear_has_name_part();
+ inline void set_has_is_extension();
+ inline void clear_has_is_extension();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::std::string* name_part_;
- static const ::std::string _default_name_part_;
bool is_extension_;
- friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
- friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+ mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
void InitAsDefaultInstance();
static UninterpretedOption_NamePart* default_instance_;
@@ -2394,6 +2360,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
inline void set_identifier_value(const char* value);
inline void set_identifier_value(const char* value, size_t size);
inline ::std::string* mutable_identifier_value();
+ inline ::std::string* release_identifier_value();
// optional uint64 positive_int_value = 4;
inline bool has_positive_int_value() const;
@@ -2425,39 +2392,240 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
inline void set_string_value(const char* value);
inline void set_string_value(const void* value, size_t size);
inline ::std::string* mutable_string_value();
+ inline ::std::string* release_string_value();
+
+ // optional string aggregate_value = 8;
+ inline bool has_aggregate_value() const;
+ inline void clear_aggregate_value();
+ static const int kAggregateValueFieldNumber = 8;
+ inline const ::std::string& aggregate_value() const;
+ inline void set_aggregate_value(const ::std::string& value);
+ inline void set_aggregate_value(const char* value);
+ inline void set_aggregate_value(const char* value, size_t size);
+ inline ::std::string* mutable_aggregate_value();
+ inline ::std::string* release_aggregate_value();
// @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
private:
+ inline void set_has_identifier_value();
+ inline void clear_has_identifier_value();
+ inline void set_has_positive_int_value();
+ inline void clear_has_positive_int_value();
+ inline void set_has_negative_int_value();
+ inline void clear_has_negative_int_value();
+ inline void set_has_double_value();
+ inline void clear_has_double_value();
+ inline void set_has_string_value();
+ inline void clear_has_string_value();
+ inline void set_has_aggregate_value();
+ inline void clear_has_aggregate_value();
+
::google::protobuf::UnknownFieldSet _unknown_fields_;
- mutable int _cached_size_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_;
::std::string* identifier_value_;
- static const ::std::string _default_identifier_value_;
::google::protobuf::uint64 positive_int_value_;
::google::protobuf::int64 negative_int_value_;
double double_value_;
::std::string* string_value_;
- static const ::std::string _default_string_value_;
+ ::std::string* aggregate_value_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static UninterpretedOption* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message {
+ public:
+ SourceCodeInfo_Location();
+ virtual ~SourceCodeInfo_Location();
+
+ SourceCodeInfo_Location(const SourceCodeInfo_Location& from);
+
+ inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const SourceCodeInfo_Location& default_instance();
+
+ void Swap(SourceCodeInfo_Location* other);
+
+ // implements Message ----------------------------------------------
+
+ SourceCodeInfo_Location* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const SourceCodeInfo_Location& from);
+ void MergeFrom(const SourceCodeInfo_Location& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated int32 path = 1 [packed = true];
+ inline int path_size() const;
+ inline void clear_path();
+ static const int kPathFieldNumber = 1;
+ inline ::google::protobuf::int32 path(int index) const;
+ inline void set_path(int index, ::google::protobuf::int32 value);
+ inline void add_path(::google::protobuf::int32 value);
+ inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ path() const;
+ inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ mutable_path();
+
+ // repeated int32 span = 2 [packed = true];
+ inline int span_size() const;
+ inline void clear_span();
+ static const int kSpanFieldNumber = 2;
+ inline ::google::protobuf::int32 span(int index) const;
+ inline void set_span(int index, ::google::protobuf::int32 value);
+ inline void add_span(::google::protobuf::int32 value);
+ inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ span() const;
+ inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ mutable_span();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
+ private:
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
+ mutable int _path_cached_byte_size_;
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_;
+ mutable int _span_cached_byte_size_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
+
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
- ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32];
+ void InitAsDefaultInstance();
+ static SourceCodeInfo_Location* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message {
+ public:
+ SourceCodeInfo();
+ virtual ~SourceCodeInfo();
+
+ SourceCodeInfo(const SourceCodeInfo& from);
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
+ inline SourceCodeInfo& operator=(const SourceCodeInfo& from) {
+ CopyFrom(from);
+ return *this;
}
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
}
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
}
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const SourceCodeInfo& default_instance();
+
+ void Swap(SourceCodeInfo* other);
+
+ // implements Message ----------------------------------------------
+
+ SourceCodeInfo* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const SourceCodeInfo& from);
+ void MergeFrom(const SourceCodeInfo& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef SourceCodeInfo_Location Location;
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ inline int location_size() const;
+ inline void clear_location();
+ static const int kLocationFieldNumber = 1;
+ inline const ::google::protobuf::SourceCodeInfo_Location& location(int index) const;
+ inline ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index);
+ inline ::google::protobuf::SourceCodeInfo_Location* add_location();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+ location() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+ mutable_location();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
+ private:
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
void InitAsDefaultInstance();
- static UninterpretedOption* default_instance_;
+ static SourceCodeInfo* default_instance_;
};
// ===================================================================
@@ -2497,87 +2665,119 @@ FileDescriptorSet::mutable_file() {
// optional string name = 1;
inline bool FileDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FileDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FileDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void FileDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& FileDescriptorProto::name() const {
return *name_;
}
inline void FileDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void FileDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void FileDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
return name_;
}
+inline ::std::string* FileDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional string package = 2;
inline bool FileDescriptorProto::has_package() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FileDescriptorProto::set_has_package() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FileDescriptorProto::clear_has_package() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void FileDescriptorProto::clear_package() {
- if (package_ != &_default_package_) {
+ if (package_ != &::google::protobuf::internal::kEmptyString) {
package_->clear();
}
- _clear_bit(1);
+ clear_has_package();
}
inline const ::std::string& FileDescriptorProto::package() const {
return *package_;
}
inline void FileDescriptorProto::set_package(const ::std::string& value) {
- _set_bit(1);
- if (package_ == &_default_package_) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::kEmptyString) {
package_ = new ::std::string;
}
package_->assign(value);
}
inline void FileDescriptorProto::set_package(const char* value) {
- _set_bit(1);
- if (package_ == &_default_package_) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::kEmptyString) {
package_ = new ::std::string;
}
package_->assign(value);
}
inline void FileDescriptorProto::set_package(const char* value, size_t size) {
- _set_bit(1);
- if (package_ == &_default_package_) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::kEmptyString) {
package_ = new ::std::string;
}
package_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileDescriptorProto::mutable_package() {
- _set_bit(1);
- if (package_ == &_default_package_) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::kEmptyString) {
package_ = new ::std::string;
}
return package_;
}
+inline ::std::string* FileDescriptorProto::release_package() {
+ clear_has_package();
+ if (package_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = package_;
+ package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// repeated string dependency = 3;
inline int FileDescriptorProto::dependency_size() const {
@@ -2725,20 +2925,61 @@ FileDescriptorProto::mutable_extension() {
// optional .google.protobuf.FileOptions options = 8;
inline bool FileDescriptorProto::has_options() const {
- return _has_bit(7);
+ return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FileDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000080u;
+}
+inline void FileDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000080u;
}
inline void FileDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
- _clear_bit(7);
+ clear_has_options();
}
inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
- _set_bit(7);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::FileOptions;
return options_;
}
+inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::FileOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+
+// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+inline bool FileDescriptorProto::has_source_code_info() const {
+ return (_has_bits_[0] & 0x00000100u) != 0;
+}
+inline void FileDescriptorProto::set_has_source_code_info() {
+ _has_bits_[0] |= 0x00000100u;
+}
+inline void FileDescriptorProto::clear_has_source_code_info() {
+ _has_bits_[0] &= ~0x00000100u;
+}
+inline void FileDescriptorProto::clear_source_code_info() {
+ if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
+ clear_has_source_code_info();
+}
+inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
+ return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_;
+}
+inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
+ set_has_source_code_info();
+ if (source_code_info_ == NULL) source_code_info_ = new ::google::protobuf::SourceCodeInfo;
+ return source_code_info_;
+}
+inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
+ clear_has_source_code_info();
+ ::google::protobuf::SourceCodeInfo* temp = source_code_info_;
+ source_code_info_ = NULL;
+ return temp;
+}
// -------------------------------------------------------------------
@@ -2746,33 +2987,45 @@ inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
// optional int32 start = 1;
inline bool DescriptorProto_ExtensionRange::has_start() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void DescriptorProto_ExtensionRange::set_has_start() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void DescriptorProto_ExtensionRange::clear_has_start() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void DescriptorProto_ExtensionRange::clear_start() {
start_ = 0;
- _clear_bit(0);
+ clear_has_start();
}
inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const {
return start_;
}
inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) {
- _set_bit(0);
+ set_has_start();
start_ = value;
}
// optional int32 end = 2;
inline bool DescriptorProto_ExtensionRange::has_end() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void DescriptorProto_ExtensionRange::set_has_end() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void DescriptorProto_ExtensionRange::clear_has_end() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void DescriptorProto_ExtensionRange::clear_end() {
end_ = 0;
- _clear_bit(1);
+ clear_has_end();
}
inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const {
return end_;
}
inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) {
- _set_bit(1);
+ set_has_end();
end_ = value;
}
@@ -2782,45 +3035,61 @@ inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 va
// optional string name = 1;
inline bool DescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void DescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void DescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void DescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& DescriptorProto::name() const {
return *name_;
}
inline void DescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void DescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void DescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* DescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
return name_;
}
+inline ::std::string* DescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// repeated .google.protobuf.FieldDescriptorProto field = 2;
inline int DescriptorProto::field_size() const {
@@ -2949,20 +3218,32 @@ DescriptorProto::mutable_extension_range() {
// optional .google.protobuf.MessageOptions options = 7;
inline bool DescriptorProto::has_options() const {
- return _has_bit(6);
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void DescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void DescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000040u;
}
inline void DescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
- _clear_bit(6);
+ clear_has_options();
}
inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
- _set_bit(6);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions;
return options_;
}
+inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::MessageOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
// -------------------------------------------------------------------
@@ -2970,238 +3251,332 @@ inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
// optional string name = 1;
inline bool FieldDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FieldDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FieldDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void FieldDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& FieldDescriptorProto::name() const {
return *name_;
}
inline void FieldDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void FieldDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void FieldDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FieldDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
return name_;
}
+inline ::std::string* FieldDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional int32 number = 3;
inline bool FieldDescriptorProto::has_number() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FieldDescriptorProto::set_has_number() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FieldDescriptorProto::clear_has_number() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void FieldDescriptorProto::clear_number() {
number_ = 0;
- _clear_bit(1);
+ clear_has_number();
}
inline ::google::protobuf::int32 FieldDescriptorProto::number() const {
return number_;
}
inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) {
- _set_bit(1);
+ set_has_number();
number_ = value;
}
// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
inline bool FieldDescriptorProto::has_label() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FieldDescriptorProto::set_has_label() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void FieldDescriptorProto::clear_has_label() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void FieldDescriptorProto::clear_label() {
label_ = 1;
- _clear_bit(2);
+ clear_has_label();
}
inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_);
}
inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
- _set_bit(2);
+ set_has_label();
label_ = value;
}
// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
inline bool FieldDescriptorProto::has_type() const {
- return _has_bit(3);
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FieldDescriptorProto::set_has_type() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void FieldDescriptorProto::clear_has_type() {
+ _has_bits_[0] &= ~0x00000008u;
}
inline void FieldDescriptorProto::clear_type() {
type_ = 1;
- _clear_bit(3);
+ clear_has_type();
}
inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_);
}
inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
- _set_bit(3);
+ set_has_type();
type_ = value;
}
// optional string type_name = 6;
inline bool FieldDescriptorProto::has_type_name() const {
- return _has_bit(4);
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void FieldDescriptorProto::set_has_type_name() {
+ _has_bits_[0] |= 0x00000010u;
+}
+inline void FieldDescriptorProto::clear_has_type_name() {
+ _has_bits_[0] &= ~0x00000010u;
}
inline void FieldDescriptorProto::clear_type_name() {
- if (type_name_ != &_default_type_name_) {
+ if (type_name_ != &::google::protobuf::internal::kEmptyString) {
type_name_->clear();
}
- _clear_bit(4);
+ clear_has_type_name();
}
inline const ::std::string& FieldDescriptorProto::type_name() const {
return *type_name_;
}
inline void FieldDescriptorProto::set_type_name(const ::std::string& value) {
- _set_bit(4);
- if (type_name_ == &_default_type_name_) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::kEmptyString) {
type_name_ = new ::std::string;
}
type_name_->assign(value);
}
inline void FieldDescriptorProto::set_type_name(const char* value) {
- _set_bit(4);
- if (type_name_ == &_default_type_name_) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::kEmptyString) {
type_name_ = new ::std::string;
}
type_name_->assign(value);
}
inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) {
- _set_bit(4);
- if (type_name_ == &_default_type_name_) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::kEmptyString) {
type_name_ = new ::std::string;
}
type_name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FieldDescriptorProto::mutable_type_name() {
- _set_bit(4);
- if (type_name_ == &_default_type_name_) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::kEmptyString) {
type_name_ = new ::std::string;
}
return type_name_;
}
+inline ::std::string* FieldDescriptorProto::release_type_name() {
+ clear_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = type_name_;
+ type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional string extendee = 2;
inline bool FieldDescriptorProto::has_extendee() const {
- return _has_bit(5);
+ return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void FieldDescriptorProto::set_has_extendee() {
+ _has_bits_[0] |= 0x00000020u;
+}
+inline void FieldDescriptorProto::clear_has_extendee() {
+ _has_bits_[0] &= ~0x00000020u;
}
inline void FieldDescriptorProto::clear_extendee() {
- if (extendee_ != &_default_extendee_) {
+ if (extendee_ != &::google::protobuf::internal::kEmptyString) {
extendee_->clear();
}
- _clear_bit(5);
+ clear_has_extendee();
}
inline const ::std::string& FieldDescriptorProto::extendee() const {
return *extendee_;
}
inline void FieldDescriptorProto::set_extendee(const ::std::string& value) {
- _set_bit(5);
- if (extendee_ == &_default_extendee_) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::kEmptyString) {
extendee_ = new ::std::string;
}
extendee_->assign(value);
}
inline void FieldDescriptorProto::set_extendee(const char* value) {
- _set_bit(5);
- if (extendee_ == &_default_extendee_) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::kEmptyString) {
extendee_ = new ::std::string;
}
extendee_->assign(value);
}
inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) {
- _set_bit(5);
- if (extendee_ == &_default_extendee_) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::kEmptyString) {
extendee_ = new ::std::string;
}
extendee_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FieldDescriptorProto::mutable_extendee() {
- _set_bit(5);
- if (extendee_ == &_default_extendee_) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::kEmptyString) {
extendee_ = new ::std::string;
}
return extendee_;
}
+inline ::std::string* FieldDescriptorProto::release_extendee() {
+ clear_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = extendee_;
+ extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional string default_value = 7;
inline bool FieldDescriptorProto::has_default_value() const {
- return _has_bit(6);
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void FieldDescriptorProto::set_has_default_value() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void FieldDescriptorProto::clear_has_default_value() {
+ _has_bits_[0] &= ~0x00000040u;
}
inline void FieldDescriptorProto::clear_default_value() {
- if (default_value_ != &_default_default_value_) {
+ if (default_value_ != &::google::protobuf::internal::kEmptyString) {
default_value_->clear();
}
- _clear_bit(6);
+ clear_has_default_value();
}
inline const ::std::string& FieldDescriptorProto::default_value() const {
return *default_value_;
}
inline void FieldDescriptorProto::set_default_value(const ::std::string& value) {
- _set_bit(6);
- if (default_value_ == &_default_default_value_) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::kEmptyString) {
default_value_ = new ::std::string;
}
default_value_->assign(value);
}
inline void FieldDescriptorProto::set_default_value(const char* value) {
- _set_bit(6);
- if (default_value_ == &_default_default_value_) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::kEmptyString) {
default_value_ = new ::std::string;
}
default_value_->assign(value);
}
inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) {
- _set_bit(6);
- if (default_value_ == &_default_default_value_) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::kEmptyString) {
default_value_ = new ::std::string;
}
default_value_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FieldDescriptorProto::mutable_default_value() {
- _set_bit(6);
- if (default_value_ == &_default_default_value_) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::kEmptyString) {
default_value_ = new ::std::string;
}
return default_value_;
}
+inline ::std::string* FieldDescriptorProto::release_default_value() {
+ clear_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = default_value_;
+ default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional .google.protobuf.FieldOptions options = 8;
inline bool FieldDescriptorProto::has_options() const {
- return _has_bit(7);
+ return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FieldDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000080u;
+}
+inline void FieldDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000080u;
}
inline void FieldDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
- _clear_bit(7);
+ clear_has_options();
}
inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
- _set_bit(7);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions;
return options_;
}
+inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::FieldOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
// -------------------------------------------------------------------
@@ -3209,45 +3584,61 @@ inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options()
// optional string name = 1;
inline bool EnumDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void EnumDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& EnumDescriptorProto::name() const {
return *name_;
}
inline void EnumDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void EnumDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void EnumDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* EnumDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
return name_;
}
+inline ::std::string* EnumDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
inline int EnumDescriptorProto::value_size() const {
@@ -3276,20 +3667,32 @@ EnumDescriptorProto::mutable_value() {
// optional .google.protobuf.EnumOptions options = 3;
inline bool EnumDescriptorProto::has_options() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void EnumDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void EnumDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void EnumDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
- _clear_bit(2);
+ clear_has_options();
}
inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
- _set_bit(2);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions;
return options_;
}
+inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::EnumOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
// -------------------------------------------------------------------
@@ -3297,78 +3700,112 @@ inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
// optional string name = 1;
inline bool EnumValueDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumValueDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void EnumValueDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& EnumValueDescriptorProto::name() const {
return *name_;
}
inline void EnumValueDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void EnumValueDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* EnumValueDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
return name_;
}
+inline ::std::string* EnumValueDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional int32 number = 2;
inline bool EnumValueDescriptorProto::has_number() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_number() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void EnumValueDescriptorProto::clear_has_number() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void EnumValueDescriptorProto::clear_number() {
number_ = 0;
- _clear_bit(1);
+ clear_has_number();
}
inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const {
return number_;
}
inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) {
- _set_bit(1);
+ set_has_number();
number_ = value;
}
// optional .google.protobuf.EnumValueOptions options = 3;
inline bool EnumValueDescriptorProto::has_options() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void EnumValueDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void EnumValueDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
- _clear_bit(2);
+ clear_has_options();
}
inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
- _set_bit(2);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions;
return options_;
}
+inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::EnumValueOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
// -------------------------------------------------------------------
@@ -3376,45 +3813,61 @@ inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_o
// optional string name = 1;
inline bool ServiceDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void ServiceDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void ServiceDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void ServiceDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& ServiceDescriptorProto::name() const {
return *name_;
}
inline void ServiceDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void ServiceDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void ServiceDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* ServiceDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
return name_;
}
+inline ::std::string* ServiceDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// repeated .google.protobuf.MethodDescriptorProto method = 2;
inline int ServiceDescriptorProto::method_size() const {
@@ -3443,20 +3896,32 @@ ServiceDescriptorProto::mutable_method() {
// optional .google.protobuf.ServiceOptions options = 3;
inline bool ServiceDescriptorProto::has_options() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void ServiceDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void ServiceDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void ServiceDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
- _clear_bit(2);
+ clear_has_options();
}
inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
- _set_bit(2);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions;
return options_;
}
+inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::ServiceOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
// -------------------------------------------------------------------
@@ -3464,146 +3929,206 @@ inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_optio
// optional string name = 1;
inline bool MethodDescriptorProto::has_name() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MethodDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void MethodDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void MethodDescriptorProto::clear_name() {
- if (name_ != &_default_name_) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
name_->clear();
}
- _clear_bit(0);
+ clear_has_name();
}
inline const ::std::string& MethodDescriptorProto::name() const {
return *name_;
}
inline void MethodDescriptorProto::set_name(const ::std::string& value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void MethodDescriptorProto::set_name(const char* value) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(value);
}
inline void MethodDescriptorProto::set_name(const char* value, size_t size) {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* MethodDescriptorProto::mutable_name() {
- _set_bit(0);
- if (name_ == &_default_name_) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
name_ = new ::std::string;
}
return name_;
}
+inline ::std::string* MethodDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional string input_type = 2;
inline bool MethodDescriptorProto::has_input_type() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void MethodDescriptorProto::set_has_input_type() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void MethodDescriptorProto::clear_has_input_type() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void MethodDescriptorProto::clear_input_type() {
- if (input_type_ != &_default_input_type_) {
+ if (input_type_ != &::google::protobuf::internal::kEmptyString) {
input_type_->clear();
}
- _clear_bit(1);
+ clear_has_input_type();
}
inline const ::std::string& MethodDescriptorProto::input_type() const {
return *input_type_;
}
inline void MethodDescriptorProto::set_input_type(const ::std::string& value) {
- _set_bit(1);
- if (input_type_ == &_default_input_type_) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::kEmptyString) {
input_type_ = new ::std::string;
}
input_type_->assign(value);
}
inline void MethodDescriptorProto::set_input_type(const char* value) {
- _set_bit(1);
- if (input_type_ == &_default_input_type_) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::kEmptyString) {
input_type_ = new ::std::string;
}
input_type_->assign(value);
}
inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) {
- _set_bit(1);
- if (input_type_ == &_default_input_type_) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::kEmptyString) {
input_type_ = new ::std::string;
}
input_type_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* MethodDescriptorProto::mutable_input_type() {
- _set_bit(1);
- if (input_type_ == &_default_input_type_) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::kEmptyString) {
input_type_ = new ::std::string;
}
return input_type_;
}
+inline ::std::string* MethodDescriptorProto::release_input_type() {
+ clear_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = input_type_;
+ input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional string output_type = 3;
inline bool MethodDescriptorProto::has_output_type() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void MethodDescriptorProto::set_has_output_type() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void MethodDescriptorProto::clear_has_output_type() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void MethodDescriptorProto::clear_output_type() {
- if (output_type_ != &_default_output_type_) {
+ if (output_type_ != &::google::protobuf::internal::kEmptyString) {
output_type_->clear();
}
- _clear_bit(2);
+ clear_has_output_type();
}
inline const ::std::string& MethodDescriptorProto::output_type() const {
return *output_type_;
}
inline void MethodDescriptorProto::set_output_type(const ::std::string& value) {
- _set_bit(2);
- if (output_type_ == &_default_output_type_) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::kEmptyString) {
output_type_ = new ::std::string;
}
output_type_->assign(value);
}
inline void MethodDescriptorProto::set_output_type(const char* value) {
- _set_bit(2);
- if (output_type_ == &_default_output_type_) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::kEmptyString) {
output_type_ = new ::std::string;
}
output_type_->assign(value);
}
inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) {
- _set_bit(2);
- if (output_type_ == &_default_output_type_) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::kEmptyString) {
output_type_ = new ::std::string;
}
output_type_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* MethodDescriptorProto::mutable_output_type() {
- _set_bit(2);
- if (output_type_ == &_default_output_type_) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::kEmptyString) {
output_type_ = new ::std::string;
}
return output_type_;
}
+inline ::std::string* MethodDescriptorProto::release_output_type() {
+ clear_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = output_type_;
+ output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional .google.protobuf.MethodOptions options = 4;
inline bool MethodDescriptorProto::has_options() const {
- return _has_bit(3);
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void MethodDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void MethodDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000008u;
}
inline void MethodDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
- _clear_bit(3);
+ clear_has_options();
}
inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
return options_ != NULL ? *options_ : *default_instance_->options_;
}
inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
- _set_bit(3);
+ set_has_options();
if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions;
return options_;
}
+inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::MethodOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
// -------------------------------------------------------------------
@@ -3611,166 +4136,250 @@ inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options
// optional string java_package = 1;
inline bool FileOptions::has_java_package() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FileOptions::set_has_java_package() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FileOptions::clear_has_java_package() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void FileOptions::clear_java_package() {
- if (java_package_ != &_default_java_package_) {
+ if (java_package_ != &::google::protobuf::internal::kEmptyString) {
java_package_->clear();
}
- _clear_bit(0);
+ clear_has_java_package();
}
inline const ::std::string& FileOptions::java_package() const {
return *java_package_;
}
inline void FileOptions::set_java_package(const ::std::string& value) {
- _set_bit(0);
- if (java_package_ == &_default_java_package_) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::kEmptyString) {
java_package_ = new ::std::string;
}
java_package_->assign(value);
}
inline void FileOptions::set_java_package(const char* value) {
- _set_bit(0);
- if (java_package_ == &_default_java_package_) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::kEmptyString) {
java_package_ = new ::std::string;
}
java_package_->assign(value);
}
inline void FileOptions::set_java_package(const char* value, size_t size) {
- _set_bit(0);
- if (java_package_ == &_default_java_package_) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::kEmptyString) {
java_package_ = new ::std::string;
}
java_package_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileOptions::mutable_java_package() {
- _set_bit(0);
- if (java_package_ == &_default_java_package_) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::kEmptyString) {
java_package_ = new ::std::string;
}
return java_package_;
}
+inline ::std::string* FileOptions::release_java_package() {
+ clear_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = java_package_;
+ java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional string java_outer_classname = 8;
inline bool FileOptions::has_java_outer_classname() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FileOptions::set_has_java_outer_classname() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FileOptions::clear_has_java_outer_classname() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void FileOptions::clear_java_outer_classname() {
- if (java_outer_classname_ != &_default_java_outer_classname_) {
+ if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) {
java_outer_classname_->clear();
}
- _clear_bit(1);
+ clear_has_java_outer_classname();
}
inline const ::std::string& FileOptions::java_outer_classname() const {
return *java_outer_classname_;
}
inline void FileOptions::set_java_outer_classname(const ::std::string& value) {
- _set_bit(1);
- if (java_outer_classname_ == &_default_java_outer_classname_) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
java_outer_classname_ = new ::std::string;
}
java_outer_classname_->assign(value);
}
inline void FileOptions::set_java_outer_classname(const char* value) {
- _set_bit(1);
- if (java_outer_classname_ == &_default_java_outer_classname_) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
java_outer_classname_ = new ::std::string;
}
java_outer_classname_->assign(value);
}
inline void FileOptions::set_java_outer_classname(const char* value, size_t size) {
- _set_bit(1);
- if (java_outer_classname_ == &_default_java_outer_classname_) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
java_outer_classname_ = new ::std::string;
}
java_outer_classname_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileOptions::mutable_java_outer_classname() {
- _set_bit(1);
- if (java_outer_classname_ == &_default_java_outer_classname_) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
java_outer_classname_ = new ::std::string;
}
return java_outer_classname_;
}
+inline ::std::string* FileOptions::release_java_outer_classname() {
+ clear_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = java_outer_classname_;
+ java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional bool java_multiple_files = 10 [default = false];
inline bool FileOptions::has_java_multiple_files() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FileOptions::set_has_java_multiple_files() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void FileOptions::clear_has_java_multiple_files() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void FileOptions::clear_java_multiple_files() {
java_multiple_files_ = false;
- _clear_bit(2);
+ clear_has_java_multiple_files();
}
inline bool FileOptions::java_multiple_files() const {
return java_multiple_files_;
}
inline void FileOptions::set_java_multiple_files(bool value) {
- _set_bit(2);
+ set_has_java_multiple_files();
java_multiple_files_ = value;
}
+// optional bool java_generate_equals_and_hash = 20 [default = false];
+inline bool FileOptions::has_java_generate_equals_and_hash() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FileOptions::set_has_java_generate_equals_and_hash() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void FileOptions::clear_has_java_generate_equals_and_hash() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline void FileOptions::clear_java_generate_equals_and_hash() {
+ java_generate_equals_and_hash_ = false;
+ clear_has_java_generate_equals_and_hash();
+}
+inline bool FileOptions::java_generate_equals_and_hash() const {
+ return java_generate_equals_and_hash_;
+}
+inline void FileOptions::set_java_generate_equals_and_hash(bool value) {
+ set_has_java_generate_equals_and_hash();
+ java_generate_equals_and_hash_ = value;
+}
+
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
inline bool FileOptions::has_optimize_for() const {
- return _has_bit(3);
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void FileOptions::set_has_optimize_for() {
+ _has_bits_[0] |= 0x00000010u;
+}
+inline void FileOptions::clear_has_optimize_for() {
+ _has_bits_[0] &= ~0x00000010u;
}
inline void FileOptions::clear_optimize_for() {
optimize_for_ = 1;
- _clear_bit(3);
+ clear_has_optimize_for();
}
inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const {
return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_);
}
inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) {
GOOGLE_DCHECK(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
- _set_bit(3);
+ set_has_optimize_for();
optimize_for_ = value;
}
-// optional bool cc_generic_services = 16 [default = true];
+// optional bool cc_generic_services = 16 [default = false];
inline bool FileOptions::has_cc_generic_services() const {
- return _has_bit(4);
+ return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void FileOptions::set_has_cc_generic_services() {
+ _has_bits_[0] |= 0x00000020u;
+}
+inline void FileOptions::clear_has_cc_generic_services() {
+ _has_bits_[0] &= ~0x00000020u;
}
inline void FileOptions::clear_cc_generic_services() {
- cc_generic_services_ = true;
- _clear_bit(4);
+ cc_generic_services_ = false;
+ clear_has_cc_generic_services();
}
inline bool FileOptions::cc_generic_services() const {
return cc_generic_services_;
}
inline void FileOptions::set_cc_generic_services(bool value) {
- _set_bit(4);
+ set_has_cc_generic_services();
cc_generic_services_ = value;
}
-// optional bool java_generic_services = 17 [default = true];
+// optional bool java_generic_services = 17 [default = false];
inline bool FileOptions::has_java_generic_services() const {
- return _has_bit(5);
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void FileOptions::set_has_java_generic_services() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void FileOptions::clear_has_java_generic_services() {
+ _has_bits_[0] &= ~0x00000040u;
}
inline void FileOptions::clear_java_generic_services() {
- java_generic_services_ = true;
- _clear_bit(5);
+ java_generic_services_ = false;
+ clear_has_java_generic_services();
}
inline bool FileOptions::java_generic_services() const {
return java_generic_services_;
}
inline void FileOptions::set_java_generic_services(bool value) {
- _set_bit(5);
+ set_has_java_generic_services();
java_generic_services_ = value;
}
-// optional bool py_generic_services = 18 [default = true];
+// optional bool py_generic_services = 18 [default = false];
inline bool FileOptions::has_py_generic_services() const {
- return _has_bit(6);
+ return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FileOptions::set_has_py_generic_services() {
+ _has_bits_[0] |= 0x00000080u;
+}
+inline void FileOptions::clear_has_py_generic_services() {
+ _has_bits_[0] &= ~0x00000080u;
}
inline void FileOptions::clear_py_generic_services() {
- py_generic_services_ = true;
- _clear_bit(6);
+ py_generic_services_ = false;
+ clear_has_py_generic_services();
}
inline bool FileOptions::py_generic_services() const {
return py_generic_services_;
}
inline void FileOptions::set_py_generic_services(bool value) {
- _set_bit(6);
+ set_has_py_generic_services();
py_generic_services_ = value;
}
@@ -3805,33 +4414,45 @@ FileOptions::mutable_uninterpreted_option() {
// optional bool message_set_wire_format = 1 [default = false];
inline bool MessageOptions::has_message_set_wire_format() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MessageOptions::set_has_message_set_wire_format() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void MessageOptions::clear_has_message_set_wire_format() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void MessageOptions::clear_message_set_wire_format() {
message_set_wire_format_ = false;
- _clear_bit(0);
+ clear_has_message_set_wire_format();
}
inline bool MessageOptions::message_set_wire_format() const {
return message_set_wire_format_;
}
inline void MessageOptions::set_message_set_wire_format(bool value) {
- _set_bit(0);
+ set_has_message_set_wire_format();
message_set_wire_format_ = value;
}
// optional bool no_standard_descriptor_accessor = 2 [default = false];
inline bool MessageOptions::has_no_standard_descriptor_accessor() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void MessageOptions::set_has_no_standard_descriptor_accessor() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void MessageOptions::clear_has_no_standard_descriptor_accessor() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void MessageOptions::clear_no_standard_descriptor_accessor() {
no_standard_descriptor_accessor_ = false;
- _clear_bit(1);
+ clear_has_no_standard_descriptor_accessor();
}
inline bool MessageOptions::no_standard_descriptor_accessor() const {
return no_standard_descriptor_accessor_;
}
inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) {
- _set_bit(1);
+ set_has_no_standard_descriptor_accessor();
no_standard_descriptor_accessor_ = value;
}
@@ -3866,94 +4487,128 @@ MessageOptions::mutable_uninterpreted_option() {
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
inline bool FieldOptions::has_ctype() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FieldOptions::set_has_ctype() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FieldOptions::clear_has_ctype() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void FieldOptions::clear_ctype() {
ctype_ = 0;
- _clear_bit(0);
+ clear_has_ctype();
}
inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const {
return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_);
}
inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) {
GOOGLE_DCHECK(::google::protobuf::FieldOptions_CType_IsValid(value));
- _set_bit(0);
+ set_has_ctype();
ctype_ = value;
}
// optional bool packed = 2;
inline bool FieldOptions::has_packed() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FieldOptions::set_has_packed() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FieldOptions::clear_has_packed() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void FieldOptions::clear_packed() {
packed_ = false;
- _clear_bit(1);
+ clear_has_packed();
}
inline bool FieldOptions::packed() const {
return packed_;
}
inline void FieldOptions::set_packed(bool value) {
- _set_bit(1);
+ set_has_packed();
packed_ = value;
}
// optional bool deprecated = 3 [default = false];
inline bool FieldOptions::has_deprecated() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FieldOptions::set_has_deprecated() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void FieldOptions::clear_has_deprecated() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void FieldOptions::clear_deprecated() {
deprecated_ = false;
- _clear_bit(2);
+ clear_has_deprecated();
}
inline bool FieldOptions::deprecated() const {
return deprecated_;
}
inline void FieldOptions::set_deprecated(bool value) {
- _set_bit(2);
+ set_has_deprecated();
deprecated_ = value;
}
// optional string experimental_map_key = 9;
inline bool FieldOptions::has_experimental_map_key() const {
- return _has_bit(3);
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FieldOptions::set_has_experimental_map_key() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void FieldOptions::clear_has_experimental_map_key() {
+ _has_bits_[0] &= ~0x00000008u;
}
inline void FieldOptions::clear_experimental_map_key() {
- if (experimental_map_key_ != &_default_experimental_map_key_) {
+ if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
experimental_map_key_->clear();
}
- _clear_bit(3);
+ clear_has_experimental_map_key();
}
inline const ::std::string& FieldOptions::experimental_map_key() const {
return *experimental_map_key_;
}
inline void FieldOptions::set_experimental_map_key(const ::std::string& value) {
- _set_bit(3);
- if (experimental_map_key_ == &_default_experimental_map_key_) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
experimental_map_key_ = new ::std::string;
}
experimental_map_key_->assign(value);
}
inline void FieldOptions::set_experimental_map_key(const char* value) {
- _set_bit(3);
- if (experimental_map_key_ == &_default_experimental_map_key_) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
experimental_map_key_ = new ::std::string;
}
experimental_map_key_->assign(value);
}
inline void FieldOptions::set_experimental_map_key(const char* value, size_t size) {
- _set_bit(3);
- if (experimental_map_key_ == &_default_experimental_map_key_) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
experimental_map_key_ = new ::std::string;
}
experimental_map_key_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FieldOptions::mutable_experimental_map_key() {
- _set_bit(3);
- if (experimental_map_key_ == &_default_experimental_map_key_) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
experimental_map_key_ = new ::std::string;
}
return experimental_map_key_;
}
+inline ::std::string* FieldOptions::release_experimental_map_key() {
+ clear_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = experimental_map_key_;
+ experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int FieldOptions::uninterpreted_option_size() const {
@@ -4102,59 +4757,81 @@ MethodOptions::mutable_uninterpreted_option() {
// required string name_part = 1;
inline bool UninterpretedOption_NamePart::has_name_part() const {
- return _has_bit(0);
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void UninterpretedOption_NamePart::set_has_name_part() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void UninterpretedOption_NamePart::clear_has_name_part() {
+ _has_bits_[0] &= ~0x00000001u;
}
inline void UninterpretedOption_NamePart::clear_name_part() {
- if (name_part_ != &_default_name_part_) {
+ if (name_part_ != &::google::protobuf::internal::kEmptyString) {
name_part_->clear();
}
- _clear_bit(0);
+ clear_has_name_part();
}
inline const ::std::string& UninterpretedOption_NamePart::name_part() const {
return *name_part_;
}
inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) {
- _set_bit(0);
- if (name_part_ == &_default_name_part_) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::kEmptyString) {
name_part_ = new ::std::string;
}
name_part_->assign(value);
}
inline void UninterpretedOption_NamePart::set_name_part(const char* value) {
- _set_bit(0);
- if (name_part_ == &_default_name_part_) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::kEmptyString) {
name_part_ = new ::std::string;
}
name_part_->assign(value);
}
inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) {
- _set_bit(0);
- if (name_part_ == &_default_name_part_) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::kEmptyString) {
name_part_ = new ::std::string;
}
name_part_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
- _set_bit(0);
- if (name_part_ == &_default_name_part_) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::kEmptyString) {
name_part_ = new ::std::string;
}
return name_part_;
}
+inline ::std::string* UninterpretedOption_NamePart::release_name_part() {
+ clear_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_part_;
+ name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// required bool is_extension = 2;
inline bool UninterpretedOption_NamePart::has_is_extension() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void UninterpretedOption_NamePart::set_has_is_extension() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void UninterpretedOption_NamePart::clear_has_is_extension() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void UninterpretedOption_NamePart::clear_is_extension() {
is_extension_ = false;
- _clear_bit(1);
+ clear_has_is_extension();
}
inline bool UninterpretedOption_NamePart::is_extension() const {
return is_extension_;
}
inline void UninterpretedOption_NamePart::set_is_extension(bool value) {
- _set_bit(1);
+ set_has_is_extension();
is_extension_ = value;
}
@@ -4189,135 +4866,326 @@ UninterpretedOption::mutable_name() {
// optional string identifier_value = 3;
inline bool UninterpretedOption::has_identifier_value() const {
- return _has_bit(1);
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void UninterpretedOption::set_has_identifier_value() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void UninterpretedOption::clear_has_identifier_value() {
+ _has_bits_[0] &= ~0x00000002u;
}
inline void UninterpretedOption::clear_identifier_value() {
- if (identifier_value_ != &_default_identifier_value_) {
+ if (identifier_value_ != &::google::protobuf::internal::kEmptyString) {
identifier_value_->clear();
}
- _clear_bit(1);
+ clear_has_identifier_value();
}
inline const ::std::string& UninterpretedOption::identifier_value() const {
return *identifier_value_;
}
inline void UninterpretedOption::set_identifier_value(const ::std::string& value) {
- _set_bit(1);
- if (identifier_value_ == &_default_identifier_value_) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
identifier_value_ = new ::std::string;
}
identifier_value_->assign(value);
}
inline void UninterpretedOption::set_identifier_value(const char* value) {
- _set_bit(1);
- if (identifier_value_ == &_default_identifier_value_) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
identifier_value_ = new ::std::string;
}
identifier_value_->assign(value);
}
inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) {
- _set_bit(1);
- if (identifier_value_ == &_default_identifier_value_) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
identifier_value_ = new ::std::string;
}
identifier_value_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* UninterpretedOption::mutable_identifier_value() {
- _set_bit(1);
- if (identifier_value_ == &_default_identifier_value_) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
identifier_value_ = new ::std::string;
}
return identifier_value_;
}
+inline ::std::string* UninterpretedOption::release_identifier_value() {
+ clear_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = identifier_value_;
+ identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
// optional uint64 positive_int_value = 4;
inline bool UninterpretedOption::has_positive_int_value() const {
- return _has_bit(2);
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void UninterpretedOption::set_has_positive_int_value() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void UninterpretedOption::clear_has_positive_int_value() {
+ _has_bits_[0] &= ~0x00000004u;
}
inline void UninterpretedOption::clear_positive_int_value() {
positive_int_value_ = GOOGLE_ULONGLONG(0);
- _clear_bit(2);
+ clear_has_positive_int_value();
}
inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const {
return positive_int_value_;
}
inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) {
- _set_bit(2);
+ set_has_positive_int_value();
positive_int_value_ = value;
}
// optional int64 negative_int_value = 5;
inline bool UninterpretedOption::has_negative_int_value() const {
- return _has_bit(3);
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void UninterpretedOption::set_has_negative_int_value() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void UninterpretedOption::clear_has_negative_int_value() {
+ _has_bits_[0] &= ~0x00000008u;
}
inline void UninterpretedOption::clear_negative_int_value() {
negative_int_value_ = GOOGLE_LONGLONG(0);
- _clear_bit(3);
+ clear_has_negative_int_value();
}
inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const {
return negative_int_value_;
}
inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) {
- _set_bit(3);
+ set_has_negative_int_value();
negative_int_value_ = value;
}
// optional double double_value = 6;
inline bool UninterpretedOption::has_double_value() const {
- return _has_bit(4);
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void UninterpretedOption::set_has_double_value() {
+ _has_bits_[0] |= 0x00000010u;
+}
+inline void UninterpretedOption::clear_has_double_value() {
+ _has_bits_[0] &= ~0x00000010u;
}
inline void UninterpretedOption::clear_double_value() {
double_value_ = 0;
- _clear_bit(4);
+ clear_has_double_value();
}
inline double UninterpretedOption::double_value() const {
return double_value_;
}
inline void UninterpretedOption::set_double_value(double value) {
- _set_bit(4);
+ set_has_double_value();
double_value_ = value;
}
// optional bytes string_value = 7;
inline bool UninterpretedOption::has_string_value() const {
- return _has_bit(5);
+ return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void UninterpretedOption::set_has_string_value() {
+ _has_bits_[0] |= 0x00000020u;
+}
+inline void UninterpretedOption::clear_has_string_value() {
+ _has_bits_[0] &= ~0x00000020u;
}
inline void UninterpretedOption::clear_string_value() {
- if (string_value_ != &_default_string_value_) {
+ if (string_value_ != &::google::protobuf::internal::kEmptyString) {
string_value_->clear();
}
- _clear_bit(5);
+ clear_has_string_value();
}
inline const ::std::string& UninterpretedOption::string_value() const {
return *string_value_;
}
inline void UninterpretedOption::set_string_value(const ::std::string& value) {
- _set_bit(5);
- if (string_value_ == &_default_string_value_) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::kEmptyString) {
string_value_ = new ::std::string;
}
string_value_->assign(value);
}
inline void UninterpretedOption::set_string_value(const char* value) {
- _set_bit(5);
- if (string_value_ == &_default_string_value_) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::kEmptyString) {
string_value_ = new ::std::string;
}
string_value_->assign(value);
}
inline void UninterpretedOption::set_string_value(const void* value, size_t size) {
- _set_bit(5);
- if (string_value_ == &_default_string_value_) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::kEmptyString) {
string_value_ = new ::std::string;
}
string_value_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* UninterpretedOption::mutable_string_value() {
- _set_bit(5);
- if (string_value_ == &_default_string_value_) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::kEmptyString) {
string_value_ = new ::std::string;
}
return string_value_;
}
+inline ::std::string* UninterpretedOption::release_string_value() {
+ clear_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = string_value_;
+ string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional string aggregate_value = 8;
+inline bool UninterpretedOption::has_aggregate_value() const {
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void UninterpretedOption::set_has_aggregate_value() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void UninterpretedOption::clear_has_aggregate_value() {
+ _has_bits_[0] &= ~0x00000040u;
+}
+inline void UninterpretedOption::clear_aggregate_value() {
+ if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_->clear();
+ }
+ clear_has_aggregate_value();
+}
+inline const ::std::string& UninterpretedOption::aggregate_value() const {
+ return *aggregate_value_;
+}
+inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_ = new ::std::string;
+ }
+ aggregate_value_->assign(value);
+}
+inline void UninterpretedOption::set_aggregate_value(const char* value) {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_ = new ::std::string;
+ }
+ aggregate_value_->assign(value);
+}
+inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_ = new ::std::string;
+ }
+ aggregate_value_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* UninterpretedOption::mutable_aggregate_value() {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_ = new ::std::string;
+ }
+ return aggregate_value_;
+}
+inline ::std::string* UninterpretedOption::release_aggregate_value() {
+ clear_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = aggregate_value_;
+ aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo_Location
+
+// repeated int32 path = 1 [packed = true];
+inline int SourceCodeInfo_Location::path_size() const {
+ return path_.size();
+}
+inline void SourceCodeInfo_Location::clear_path() {
+ path_.Clear();
+}
+inline ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const {
+ return path_.Get(index);
+}
+inline void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) {
+ path_.Set(index, value);
+}
+inline void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) {
+ path_.Add(value);
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+SourceCodeInfo_Location::path() const {
+ return path_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+SourceCodeInfo_Location::mutable_path() {
+ return &path_;
+}
+
+// repeated int32 span = 2 [packed = true];
+inline int SourceCodeInfo_Location::span_size() const {
+ return span_.size();
+}
+inline void SourceCodeInfo_Location::clear_span() {
+ span_.Clear();
+}
+inline ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const {
+ return span_.Get(index);
+}
+inline void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) {
+ span_.Set(index, value);
+}
+inline void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) {
+ span_.Add(value);
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+SourceCodeInfo_Location::span() const {
+ return span_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+SourceCodeInfo_Location::mutable_span() {
+ return &span_;
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo
+
+// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+inline int SourceCodeInfo::location_size() const {
+ return location_.size();
+}
+inline void SourceCodeInfo::clear_location() {
+ location_.Clear();
+}
+inline const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const {
+ return location_.Get(index);
+}
+inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
+ return location_.Mutable(index);
+}
+inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
+ return location_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+SourceCodeInfo::location() const {
+ return location_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+SourceCodeInfo::mutable_location() {
+ return &location_;
+}
// @@protoc_insertion_point(namespace_scope)
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index cc04aa8e..233f8794 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -67,6 +67,12 @@ message FileDescriptorProto {
repeated FieldDescriptorProto extension = 7;
optional FileOptions options = 8;
+
+ // This field contains optional information about the original source code.
+ // You may safely remove this entire field whithout harming runtime
+ // functionality of the descriptors -- the information is needed only by
+ // development tools.
+ optional SourceCodeInfo source_code_info = 9;
}
// Describes a message type.
@@ -245,6 +251,12 @@ message FileOptions {
// top-level extensions defined in the file.
optional bool java_multiple_files = 10 [default=false];
+ // If set true, then the Java code generator will generate equals() and
+ // hashCode() methods for all messages defined in the .proto file. This is
+ // purely a speed optimization, as the AbstractMessage base class includes
+ // reflection-based implementations of these methods.
+ optional bool java_generate_equals_and_hash = 20 [default=false];
+
// Generated classes can be optimized for speed or code size.
enum OptimizeMode {
SPEED = 1; // Generate complete code for parsing, serialization,
@@ -264,13 +276,12 @@ message FileOptions {
// early versions of proto2.
//
// Generic services are now considered deprecated in favor of using plugins
- // that generate code specific to your particular RPC system. If you are
- // using such a plugin, set these to false. In the future, we may change
- // the default to false, so if you explicitly want generic services, you
- // should explicitly set these to true.
- optional bool cc_generic_services = 16 [default=true];
- optional bool java_generic_services = 17 [default=true];
- optional bool py_generic_services = 18 [default=true];
+ // that generate code specific to your particular RPC system. Therefore,
+ // these default to false. Old code which depends on generic services should
+ // explicitly set them to true.
+ optional bool cc_generic_services = 16 [default=false];
+ optional bool java_generic_services = 17 [default=false];
+ optional bool py_generic_services = 18 [default=false];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@@ -430,4 +441,93 @@ message UninterpretedOption {
optional int64 negative_int_value = 5;
optional double double_value = 6;
optional bytes string_value = 7;
+ optional string aggregate_value = 8;
+}
+
+// ===================================================================
+// Optional source code info
+
+// Encapsulates information about the original source file from which a
+// FileDescriptorProto was generated.
+message SourceCodeInfo {
+ // A Location identifies a piece of source code in a .proto file which
+ // corresponds to a particular definition. This information is intended
+ // to be useful to IDEs, code indexers, documentation generators, and similar
+ // tools.
+ //
+ // For example, say we have a file like:
+ // message Foo {
+ // optional string foo = 1;
+ // }
+ // Let's look at just the field definition:
+ // optional string foo = 1;
+ // ^ ^^ ^^ ^ ^^^
+ // a bc de f ghi
+ // We have the following locations:
+ // span path represents
+ // [a,i) [ 4, 0, 2, 0 ] The whole field definition.
+ // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
+ // [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
+ // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
+ // [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
+ //
+ // Notes:
+ // - A location may refer to a repeated field itself (i.e. not to any
+ // particular index within it). This is used whenever a set of elements are
+ // logically enclosed in a single code segment. For example, an entire
+ // extend block (possibly containing multiple extension definitions) will
+ // have an outer location whose path refers to the "extensions" repeated
+ // field without an index.
+ // - Multiple locations may have the same path. This happens when a single
+ // logical declaration is spread out across multiple places. The most
+ // obvious example is the "extend" block again -- there may be multiple
+ // extend blocks in the same scope, each of which will have the same path.
+ // - A location's span is not always a subset of its parent's span. For
+ // example, the "extendee" of an extension declaration appears at the
+ // beginning of the "extend" block and is shared by all extensions within
+ // the block.
+ // - Just because a location's span is a subset of some other location's span
+ // does not mean that it is a descendent. For example, a "group" defines
+ // both a type and a field in a single declaration. Thus, the locations
+ // corresponding to the type and field and their components will overlap.
+ // - Code which tries to interpret locations should probably be designed to
+ // ignore those that it doesn't understand, as more types of locations could
+ // be recorded in the future.
+ repeated Location location = 1;
+ message Location {
+ // Identifies which part of the FileDescriptorProto was defined at this
+ // location.
+ //
+ // Each element is a field number or an index. They form a path from
+ // the root FileDescriptorProto to the place where the definition. For
+ // example, this path:
+ // [ 4, 3, 2, 7, 1 ]
+ // refers to:
+ // file.message_type(3) // 4, 3
+ // .field(7) // 2, 7
+ // .name() // 1
+ // This is because FileDescriptorProto.message_type has field number 4:
+ // repeated DescriptorProto message_type = 4;
+ // and DescriptorProto.field has field number 2:
+ // repeated FieldDescriptorProto field = 2;
+ // and FieldDescriptorProto.name has field number 1:
+ // optional string name = 1;
+ //
+ // Thus, the above path gives the location of a field name. If we removed
+ // the last element:
+ // [ 4, 3, 2, 7 ]
+ // this path refers to the whole field declaration (from the beginning
+ // of the label to the terminating semicolon).
+ repeated int32 path = 1 [packed=true];
+
+ // Always has exactly three or four elements: start line, start column,
+ // end line (optional, otherwise assumed same as start line), end column.
+ // These are packed into a single field for efficiency. Note that line
+ // and column numbers are zero-based -- typically you will want to add
+ // 1 to each before displaying to a user.
+ repeated int32 span = 2 [packed=true];
+
+ // TODO(kenton): Record comments appearing before and after the
+ // declaration.
+ }
}
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index d70c9bf1..55aebfd1 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -2212,6 +2212,45 @@ TEST(CustomOptions, MessageOptionThreeFieldsSet) {
EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
}
+// Check that aggregate options were parsed and saved correctly in
+// the appropriate descriptors.
+TEST(CustomOptions, AggregateOptions) {
+ const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor();
+ const FileDescriptor* file = msg->file();
+ const FieldDescriptor* field = msg->FindFieldByName("fieldname");
+ const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum");
+ const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE");
+ const ServiceDescriptor* service = file->FindServiceByName(
+ "AggregateService");
+ const MethodDescriptor* method = service->FindMethodByName("Method");
+
+ // Tests for the different types of data embedded in fileopt
+ const protobuf_unittest::Aggregate& file_options =
+ file->options().GetExtension(protobuf_unittest::fileopt);
+ EXPECT_EQ(100, file_options.i());
+ EXPECT_EQ("FileAnnotation", file_options.s());
+ EXPECT_EQ("NestedFileAnnotation", file_options.sub().s());
+ EXPECT_EQ("FileExtensionAnnotation",
+ file_options.file().GetExtension(protobuf_unittest::fileopt).s());
+ EXPECT_EQ("EmbeddedMessageSetElement",
+ file_options.mset().GetExtension(
+ protobuf_unittest::AggregateMessageSetElement
+ ::message_set_extension).s());
+
+ // Simple tests for all the other types of annotations
+ EXPECT_EQ("MessageAnnotation",
+ msg->options().GetExtension(protobuf_unittest::msgopt).s());
+ EXPECT_EQ("FieldAnnotation",
+ field->options().GetExtension(protobuf_unittest::fieldopt).s());
+ EXPECT_EQ("EnumAnnotation",
+ enumd->options().GetExtension(protobuf_unittest::enumopt).s());
+ EXPECT_EQ("EnumValueAnnotation",
+ enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
+ EXPECT_EQ("ServiceAnnotation",
+ service->options().GetExtension(protobuf_unittest::serviceopt).s());
+ EXPECT_EQ("MethodAnnotation",
+ method->options().GetExtension(protobuf_unittest::methodopt).s());
+}
// ===================================================================
@@ -3425,25 +3464,50 @@ TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
"string option \"foo\".\n");
}
-TEST_F(ValidationErrorTest, TryingToSetMessageValuedOption) {
+// Helper function for tests that check for aggregate value parsing
+// errors. The "value" argument is embedded inside the
+// "uninterpreted_option" portion of the result.
+static string EmbedAggregateValue(const char* value) {
+ return strings::Substitute(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "message_type { name: \"Foo\" } "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_MESSAGE type_name: \"Foo\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " $0 } }",
+ value);
+}
+
+TEST_F(ValidationErrorTest, AggregateValueNotFound) {
BuildDescriptorMessagesInTestPool();
BuildFileWithErrors(
- "name: \"foo.proto\" "
- "dependency: \"google/protobuf/descriptor.proto\" "
- "message_type { "
- " name: \"TestMessage\" "
- " field { name:\"baz\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING }"
- "}"
- "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
- " type: TYPE_MESSAGE type_name: \"TestMessage\" "
- " extendee: \"google.protobuf.FileOptions\" }"
- "options { uninterpreted_option { name { name_part: \"bar\" "
- " is_extension: true } "
- " identifier_value: \"QUUX\" } }",
+ EmbedAggregateValue("string_value: \"\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
+ "To set the entire message, use syntax like "
+ "\"foo = { <proto text format> }\". To set fields within it, use "
+ "syntax like \"foo.foo = value\".\n");
+}
- "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" cannot be of "
- "message type.\n");
+TEST_F(ValidationErrorTest, AggregateValueParseError) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ EmbedAggregateValue("aggregate_value: \"1+2\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
+ "value for \"foo\": Expected identifier.\n");
+}
+
+TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ EmbedAggregateValue("aggregate_value: \"x:100\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
+ "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
}
TEST_F(ValidationErrorTest, NotLiteImportsLite) {
@@ -3483,7 +3547,11 @@ TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
TEST_F(ValidationErrorTest, NoLiteServices) {
BuildFileWithErrors(
"name: \"foo.proto\" "
- "options { optimize_for: LITE_RUNTIME } "
+ "options {"
+ " optimize_for: LITE_RUNTIME"
+ " cc_generic_services: true"
+ " java_generic_services: true"
+ "} "
"service { name: \"Foo\" }",
"foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
@@ -3497,7 +3565,7 @@ TEST_F(ValidationErrorTest, NoLiteServices) {
" cc_generic_services: false"
" java_generic_services: false"
"} "
- "service { name: \"Foo\" }");
+ "service { name: \"Bar\" }");
}
TEST_F(ValidationErrorTest, RollbackAfterError) {
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index 6084885b..1a6f5dfc 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -186,6 +186,18 @@ int ExtensionSet::ExtensionSize(int number) const {
return iter->second.GetSize();
}
+FieldType ExtensionSet::ExtensionType(int number) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ if (iter == extensions_.end()) {
+ GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
+ return 0;
+ }
+ if (iter->second.is_cleared) {
+ GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
+ }
+ return iter->second.type;
+}
+
void ExtensionSet::ClearExtension(int number) {
map<int, Extension>::iterator iter = extensions_.find(number);
if (iter == extensions_.end()) return;
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index 14d5d150..ac1ada02 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -39,11 +39,11 @@
#define GOOGLE_PROTOBUF_EXTENSION_SET_H__
#include <vector>
-#include <stack>
#include <map>
#include <utility>
#include <string>
+
#include <google/protobuf/stubs/common.h>
namespace google {
@@ -214,6 +214,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
bool Has(int number) const;
int ExtensionSize(int number) const; // Size of a repeated extension.
+ FieldType ExtensionType(int number) const;
void ClearExtension(int number);
// singular fields -------------------------------------------------
@@ -451,6 +452,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
int SpaceUsedExcludingSelf() const;
};
+
// Gets the extension with the given number, creating it if it does not
// already exist. Returns true if the extension did not already exist.
bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index 0f065ff2..a0dd75c6 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -45,8 +45,6 @@ namespace google {
namespace protobuf {
namespace internal {
-namespace { const string kEmptyString; }
-
int StringSpaceUsedExcludingSelf(const string& str) {
const void* start = &str;
const void* end = &str + 1;
@@ -69,7 +67,6 @@ bool ParseNamedEnum(const EnumDescriptor* descriptor,
}
const string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
- static string kEmptyString;
const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
return (d == NULL ? kEmptyString : d->name());
}
diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc
index 7ac015d0..76e547bb 100644
--- a/src/google/protobuf/generated_message_util.cc
+++ b/src/google/protobuf/generated_message_util.cc
@@ -47,6 +47,8 @@ double NaN() {
return std::numeric_limits<double>::quiet_NaN();
}
+const ::std::string kEmptyString;
+
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h
index daa16f77..1a2343d4 100644
--- a/src/google/protobuf/generated_message_util.h
+++ b/src/google/protobuf/generated_message_util.h
@@ -38,6 +38,8 @@
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
+#include <string>
+
#include <google/protobuf/stubs/common.h>
@@ -66,8 +68,11 @@ namespace internal {
// Constants for special floating point values.
-LIBPROTOBUF_EXPORT double Infinity();
-LIBPROTOBUF_EXPORT double NaN();
+double Infinity();
+double NaN();
+
+// Constant used for empty default strings.
+extern const ::std::string kEmptyString;
} // namespace internal
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index 6a91a13d..57d486f9 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -56,6 +56,15 @@ static const int kMaxVarintBytes = 10;
static const int kMaxVarint32Bytes = 5;
+inline bool NextNonEmpty(ZeroCopyInputStream* input,
+ const void** data, int* size) {
+ bool success;
+ do {
+ success = input->Next(data, size);
+ } while (success && *size == 0);
+ return success;
+}
+
} // namespace
// CodedInputStream ==================================================
@@ -489,7 +498,7 @@ bool CodedInputStream::Refresh() {
const void* void_buffer;
int buffer_size;
- if (input_->Next(&void_buffer, &buffer_size)) {
+ if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
buffer_ = reinterpret_cast<const uint8*>(void_buffer);
buffer_end_ = buffer_ + buffer_size;
GOOGLE_CHECK_GE(buffer_size, 0);
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index 93effc87..73a54ddd 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -129,8 +129,8 @@
#endif
#include <google/protobuf/stubs/common.h>
-namespace google {
+namespace google {
namespace protobuf {
class DescriptorPool;
@@ -782,7 +782,8 @@ inline const uint8* CodedInputStream::ReadLittleEndian64FromArray(
}
inline bool CodedInputStream::ReadLittleEndian32(uint32* value) {
-#if defined(PROTOBUF_LITTLE_ENDIAN)
+#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \
+ defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
memcpy(value, buffer_, sizeof(*value));
Advance(sizeof(*value));
@@ -796,7 +797,8 @@ inline bool CodedInputStream::ReadLittleEndian32(uint32* value) {
}
inline bool CodedInputStream::ReadLittleEndian64(uint64* value) {
-#if defined(PROTOBUF_LITTLE_ENDIAN)
+#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) && \
+ defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN
if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
memcpy(value, buffer_, sizeof(*value));
Advance(sizeof(*value));
@@ -1093,10 +1095,10 @@ inline CodedInputStream::~CodedInputStream() {
} // namespace io
} // namespace protobuf
-} // namespace google
#if defined(_MSC_VER) && _MSC_VER >= 1300
#pragma runtime_checks("c", restore)
#endif // _MSC_VER
+} // namespace google
#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc
index 7d298332..ff268ab9 100644
--- a/src/google/protobuf/io/coded_stream_unittest.cc
+++ b/src/google/protobuf/io/coded_stream_unittest.cc
@@ -208,6 +208,33 @@ TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) {
EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
}
+// This is the regression test that verifies that there is no issues
+// with the empty input buffers handling.
+TEST_F(CodedStreamTest, EmptyInputBeforeEos) {
+ class In : public ZeroCopyInputStream {
+ public:
+ In() : count_(0) {}
+ private:
+ virtual bool Next(const void** data, int* size) {
+ *data = NULL;
+ *size = 0;
+ return count_++ < 2;
+ }
+ virtual void BackUp(int count) {
+ GOOGLE_LOG(FATAL) << "Tests never call this.";
+ }
+ virtual bool Skip(int count) {
+ GOOGLE_LOG(FATAL) << "Tests never call this.";
+ return false;
+ }
+ virtual int64 ByteCount() const { return 0; }
+ int count_;
+ } in;
+ CodedInputStream input(&in);
+ input.ReadTag();
+ EXPECT_TRUE(input.ConsumedEntireMessage());
+}
+
TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) {
// Leave one byte at the beginning of the buffer so we can read it
// to force the first buffer to be loaded.
@@ -995,6 +1022,7 @@ TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) {
EXPECT_FALSE(coded_input.ConsumedEntireMessage());
}
+
TEST_F(CodedStreamTest, RecursionLimit) {
ArrayInputStream input(buffer_, sizeof(buffer_));
CodedInputStream coded_input(&input);
diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc
index 84d277f4..0f1ff872 100644
--- a/src/google/protobuf/io/gzip_stream.cc
+++ b/src/google/protobuf/io/gzip_stream.cc
@@ -73,6 +73,17 @@ GzipInputStream::~GzipInputStream() {
zerror_ = inflateEnd(&zcontext_);
}
+static inline int internalInflateInit2(
+ z_stream* zcontext, GzipInputStream::Format format) {
+ int windowBitsFormat = 0;
+ switch (format) {
+ case GzipInputStream::GZIP: windowBitsFormat = 16; break;
+ case GzipInputStream::AUTO: windowBitsFormat = 32; break;
+ case GzipInputStream::ZLIB: windowBitsFormat = 0; break;
+ }
+ return inflateInit2(zcontext, /* windowBits */15 | windowBitsFormat);
+}
+
int GzipInputStream::Inflate(int flush) {
if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) {
// previous inflate filled output buffer. don't change input params yet.
@@ -89,14 +100,7 @@ int GzipInputStream::Inflate(int flush) {
zcontext_.next_in = static_cast<Bytef*>(const_cast<void*>(in));
zcontext_.avail_in = in_size;
if (first) {
- int windowBitsFormat = 0;
- switch (format_) {
- case GZIP: windowBitsFormat = 16; break;
- case AUTO: windowBitsFormat = 32; break;
- case ZLIB: windowBitsFormat = 0; break;
- }
- int error = inflateInit2(&zcontext_,
- /* windowBits */15 | windowBitsFormat);
+ int error = internalInflateInit2(&zcontext_, format_);
if (error != Z_OK) {
return error;
}
@@ -127,9 +131,21 @@ bool GzipInputStream::Next(const void** data, int* size) {
return true;
}
if (zerror_ == Z_STREAM_END) {
- *data = NULL;
- *size = 0;
- return false;
+ if (zcontext_.next_out != NULL) {
+ // sub_stream_ may have concatenated streams to follow
+ zerror_ = inflateEnd(&zcontext_);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ zerror_ = internalInflateInit2(&zcontext_, format_);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ } else {
+ *data = NULL;
+ *size = 0;
+ return false;
+ }
}
zerror_ = Inflate(Z_NO_FLUSH);
if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) {
@@ -251,8 +267,7 @@ int GzipOutputStream::Deflate(int flush) {
}
error = deflate(&zcontext_, flush);
} while (error == Z_OK && zcontext_.avail_out == 0);
- if (((flush == Z_FULL_FLUSH) || (flush == Z_FINISH))
- && (zcontext_.avail_out != sub_data_size_)) {
+ if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) {
// Notify lower layer of data.
sub_stream_->BackUp(zcontext_.avail_out);
// We don't own the buffer anymore.
diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc
index c7d3074d..9ab90dee 100644
--- a/src/google/protobuf/io/printer.cc
+++ b/src/google/protobuf/io/printer.cc
@@ -132,6 +132,17 @@ void Printer::Print(const char* text,
Print(vars, text);
}
+void Printer::Print(const char* text,
+ const char* variable1, const string& value1,
+ const char* variable2, const string& value2,
+ const char* variable3, const string& value3) {
+ map<string, string> vars;
+ vars[variable1] = value1;
+ vars[variable2] = value2;
+ vars[variable3] = value3;
+ Print(vars, text);
+}
+
void Printer::Indent() {
indent_ += " ";
}
diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h
index de085389..5be48543 100644
--- a/src/google/protobuf/io/printer.h
+++ b/src/google/protobuf/io/printer.h
@@ -82,7 +82,11 @@ class LIBPROTOBUF_EXPORT Printer {
// Like the first Print(), except the substitutions are given as parameters.
void Print(const char* text, const char* variable1, const string& value1,
const char* variable2, const string& value2);
- // TODO(kenton): Overloaded versions with more variables? Two seems
+ // Like the first Print(), except the substitutions are given as parameters.
+ void Print(const char* text, const char* variable1, const string& value1,
+ const char* variable2, const string& value2,
+ const char* variable3, const string& value3);
+ // TODO(kenton): Overloaded versions with more variables? Three seems
// to be enough.
// Indent text by two spaces. After calling Indent(), two spaces will be
diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc
index 38fa351c..513831d5 100644
--- a/src/google/protobuf/io/tokenizer.cc
+++ b/src/google/protobuf/io/tokenizer.cc
@@ -193,6 +193,7 @@ Tokenizer::Tokenizer(ZeroCopyInputStream* input,
current_.line = 0;
current_.column = 0;
+ current_.end_column = 0;
current_.type = TYPE_START;
Refresh();
@@ -277,6 +278,7 @@ inline void Tokenizer::EndToken() {
current_.text.append(buffer_ + token_start_, buffer_pos_ - token_start_);
}
token_start_ = -1;
+ current_.end_column = column_;
}
// -------------------------------------------------------------------
@@ -462,7 +464,7 @@ void Tokenizer::ConsumeBlockComment() {
// -------------------------------------------------------------------
bool Tokenizer::Next() {
- TokenType last_token_type = current_.type;
+ previous_ = current_;
// Did we skip any characters after the last token?
bool skipped_stuff = false;
@@ -517,7 +519,7 @@ bool Tokenizer::Next() {
if (TryConsumeOne<Digit>()) {
// It's a floating-point number.
- if (last_token_type == TYPE_IDENTIFIER && !skipped_stuff) {
+ if (previous_.type == TYPE_IDENTIFIER && !skipped_stuff) {
// We don't accept syntax like "blah.123".
error_collector_->AddError(line_, column_ - 2,
"Need space between identifier and decimal point.");
@@ -551,6 +553,7 @@ bool Tokenizer::Next() {
current_.text.clear();
current_.line = line_;
current_.column = column_;
+ current_.end_column = column_;
return false;
}
diff --git a/src/google/protobuf/io/tokenizer.h b/src/google/protobuf/io/tokenizer.h
index d115161f..8f759abb 100644
--- a/src/google/protobuf/io/tokenizer.h
+++ b/src/google/protobuf/io/tokenizer.h
@@ -122,12 +122,17 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// the token within the input stream. They are zero-based.
int line;
int column;
+ int end_column;
};
// Get the current token. This is updated when Next() is called. Before
// the first call to Next(), current() has type TYPE_START and no contents.
const Token& current();
+ // Return the previous token -- i.e. what current() returned before the
+ // previous call to Next().
+ const Token& previous();
+
// Advance to the next token. Returns false if the end of the input is
// reached.
bool Next();
@@ -180,6 +185,7 @@ class LIBPROTOBUF_EXPORT Tokenizer {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer);
Token current_; // Returned by current().
+ Token previous_; // Returned by previous().
ZeroCopyInputStream* input_;
ErrorCollector* error_collector_;
@@ -291,6 +297,10 @@ inline const Tokenizer::Token& Tokenizer::current() {
return current_;
}
+inline const Tokenizer::Token& Tokenizer::previous() {
+ return previous_;
+}
+
inline void Tokenizer::ParseString(const string& text, string* output) {
output->clear();
ParseStringAppend(text, output);
diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc
index 358ec567..106d080f 100644
--- a/src/google/protobuf/io/tokenizer_unittest.cc
+++ b/src/google/protobuf/io/tokenizer_unittest.cc
@@ -257,6 +257,7 @@ TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) {
EXPECT_EQ("", tokenizer.current().text);
EXPECT_EQ(0, tokenizer.current().line);
EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(0, tokenizer.current().end_column);
// Parse the token.
ASSERT_TRUE(tokenizer.Next());
@@ -268,6 +269,8 @@ TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) {
// Check that it is located at the beginning of the input
EXPECT_EQ(0, tokenizer.current().line);
EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(kSimpleTokenCases_case.input.size(),
+ tokenizer.current().end_column);
// There should be no more input.
EXPECT_FALSE(tokenizer.Next());
@@ -277,6 +280,8 @@ TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) {
EXPECT_EQ("", tokenizer.current().text);
EXPECT_EQ(0, tokenizer.current().line);
EXPECT_EQ(kSimpleTokenCases_case.input.size(), tokenizer.current().column);
+ EXPECT_EQ(kSimpleTokenCases_case.input.size(),
+ tokenizer.current().end_column);
// There should be no errors.
EXPECT_TRUE(error_collector.text_.empty());
@@ -339,76 +344,83 @@ MultiTokenCase kMultiTokenCases[] = {
// Test all token types at the same time.
{ "foo 1 1.2 + 'bar'", {
- { Tokenizer::TYPE_IDENTIFIER, "foo" , 0, 0 },
- { Tokenizer::TYPE_INTEGER , "1" , 0, 4 },
- { Tokenizer::TYPE_FLOAT , "1.2" , 0, 6 },
- { Tokenizer::TYPE_SYMBOL , "+" , 0, 10 },
- { Tokenizer::TYPE_STRING , "'bar'", 0, 12 },
- { Tokenizer::TYPE_END , "" , 0, 17 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo" , 0, 0, 3 },
+ { Tokenizer::TYPE_INTEGER , "1" , 0, 4, 5 },
+ { Tokenizer::TYPE_FLOAT , "1.2" , 0, 6, 9 },
+ { Tokenizer::TYPE_SYMBOL , "+" , 0, 10, 11 },
+ { Tokenizer::TYPE_STRING , "'bar'", 0, 12, 17 },
+ { Tokenizer::TYPE_END , "" , 0, 17, 17 },
}},
// Test that consecutive symbols are parsed as separate tokens.
{ "!@+%", {
- { Tokenizer::TYPE_SYMBOL , "!" , 0, 0 },
- { Tokenizer::TYPE_SYMBOL , "@" , 0, 1 },
- { Tokenizer::TYPE_SYMBOL , "+" , 0, 2 },
- { Tokenizer::TYPE_SYMBOL , "%" , 0, 3 },
- { Tokenizer::TYPE_END , "" , 0, 4 },
+ { Tokenizer::TYPE_SYMBOL , "!" , 0, 0, 1 },
+ { Tokenizer::TYPE_SYMBOL , "@" , 0, 1, 2 },
+ { Tokenizer::TYPE_SYMBOL , "+" , 0, 2, 3 },
+ { Tokenizer::TYPE_SYMBOL , "%" , 0, 3, 4 },
+ { Tokenizer::TYPE_END , "" , 0, 4, 4 },
}},
// Test that newlines affect line numbers correctly.
{ "foo bar\nrab oof", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4 },
- { Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4 },
- { Tokenizer::TYPE_END , "" , 1, 7 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4, 7 },
+ { Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4, 7 },
+ { Tokenizer::TYPE_END , "" , 1, 7, 7 },
}},
// Test that tabs affect column numbers correctly.
{ "foo\tbar \tbaz", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8 },
- { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16 },
- { Tokenizer::TYPE_END , "" , 0, 19 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8, 11 },
+ { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16, 19 },
+ { Tokenizer::TYPE_END , "" , 0, 19, 19 },
+ }},
+
+ // Test that tabs in string literals affect column numbers correctly.
+ { "\"foo\tbar\" baz", {
+ { Tokenizer::TYPE_STRING , "\"foo\tbar\"", 0, 0, 12 },
+ { Tokenizer::TYPE_IDENTIFIER, "baz" , 0, 13, 16 },
+ { Tokenizer::TYPE_END , "" , 0, 16, 16 },
}},
// Test that line comments are ignored.
{ "foo // This is a comment\n"
"bar // This is another comment", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0 },
- { Tokenizer::TYPE_END , "" , 1, 30 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0, 3 },
+ { Tokenizer::TYPE_END , "" , 1, 30, 30 },
}},
// Test that block comments are ignored.
{ "foo /* This is a block comment */ bar", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34 },
- { Tokenizer::TYPE_END , "" , 0, 37 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34, 37 },
+ { Tokenizer::TYPE_END , "" , 0, 37, 37 },
}},
// Test that sh-style comments are not ignored by default.
{ "foo # bar\n"
"baz", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_SYMBOL , "#" , 0, 4 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6 },
- { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0 },
- { Tokenizer::TYPE_END , "" , 1, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_SYMBOL , "#" , 0, 4, 5 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6, 9 },
+ { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0, 3 },
+ { Tokenizer::TYPE_END , "" , 1, 3, 3 },
}},
// Bytes with the high-order bit set should not be seen as control characters.
{ "\300", {
- { Tokenizer::TYPE_SYMBOL, "\300", 0, 0 },
- { Tokenizer::TYPE_END , "" , 0, 1 },
+ { Tokenizer::TYPE_SYMBOL, "\300", 0, 0, 1 },
+ { Tokenizer::TYPE_END , "" , 0, 1, 1 },
}},
// Test all whitespace chars
{ "foo\n\t\r\v\fbar", {
- { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 },
- { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11 },
- { Tokenizer::TYPE_END , "" , 1, 14 },
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11, 14 },
+ { Tokenizer::TYPE_END , "" , 1, 14, 14 },
}},
};
@@ -425,6 +437,7 @@ TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) {
EXPECT_EQ("", tokenizer.current().text);
EXPECT_EQ(0, tokenizer.current().line);
EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(0, tokenizer.current().end_column);
// Loop through all expected tokens.
int i = 0;
@@ -434,6 +447,8 @@ TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) {
SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text);
+ Tokenizer::Token previous = tokenizer.current();
+
// Next() should only return false when it hits the end token.
if (token.type != Tokenizer::TYPE_END) {
ASSERT_TRUE(tokenizer.Next());
@@ -441,11 +456,19 @@ TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) {
ASSERT_FALSE(tokenizer.Next());
}
+ // Check that the previous token is set correctly.
+ EXPECT_EQ(previous.type, tokenizer.previous().type);
+ EXPECT_EQ(previous.text, tokenizer.previous().text);
+ EXPECT_EQ(previous.line, tokenizer.previous().line);
+ EXPECT_EQ(previous.column, tokenizer.previous().column);
+ EXPECT_EQ(previous.end_column, tokenizer.previous().end_column);
+
// Check that the token matches the expected one.
EXPECT_EQ(token.type, tokenizer.current().type);
EXPECT_EQ(token.text, tokenizer.current().text);
EXPECT_EQ(token.line, tokenizer.current().line);
EXPECT_EQ(token.column, tokenizer.current().column);
+ EXPECT_EQ(token.end_column, tokenizer.current().end_column);
} while (token.type != Tokenizer::TYPE_END);
diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc
index 8229ee6d..5196d905 100644
--- a/src/google/protobuf/io/zero_copy_stream_unittest.cc
+++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -61,6 +61,7 @@
#include <sstream>
#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/coded_stream.h>
#if HAVE_ZLIB
#include <google/protobuf/io/gzip_stream.h>
@@ -285,6 +286,57 @@ TEST_F(IoTest, ArrayIo) {
}
}
+TEST_F(IoTest, TwoSessionWrite) {
+ // Test that two concatenated write sessions read correctly
+
+ static const char* strA = "0123456789";
+ static const char* strB = "WhirledPeas";
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+ char* temp_buffer = new char[40];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ ArrayOutputStream* output =
+ new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]);
+ CodedOutputStream* coded_output = new CodedOutputStream(output);
+ coded_output->WriteVarint32(strlen(strA));
+ coded_output->WriteRaw(strA, strlen(strA));
+ delete coded_output; // flush
+ int64 pos = output->ByteCount();
+ delete output;
+ output = new ArrayOutputStream(
+ buffer + pos, kBufferSize - pos, kBlockSizes[i]);
+ coded_output = new CodedOutputStream(output);
+ coded_output->WriteVarint32(strlen(strB));
+ coded_output->WriteRaw(strB, strlen(strB));
+ delete coded_output; // flush
+ int64 size = pos + output->ByteCount();
+ delete output;
+
+ ArrayInputStream* input =
+ new ArrayInputStream(buffer, size, kBlockSizes[j]);
+ CodedInputStream* coded_input = new CodedInputStream(input);
+ uint32 insize;
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strA), insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strA, insize));
+
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strB), insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strB, insize));
+
+ delete coded_input;
+ delete input;
+ }
+ }
+
+ delete [] temp_buffer;
+ delete [] buffer;
+}
+
#if HAVE_ZLIB
TEST_F(IoTest, GzipIo) {
const int kBufferSize = 2*1024;
@@ -296,8 +348,12 @@ TEST_F(IoTest, GzipIo) {
int size;
{
ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
- GzipOutputStream gzout(
- &output, GzipOutputStream::GZIP, gzip_buffer_size);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
WriteStuff(&gzout);
gzout.Close();
size = output.ByteCount();
@@ -324,8 +380,12 @@ TEST_F(IoTest, ZlibIo) {
int size;
{
ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
- GzipOutputStream gzout(
- &output, GzipOutputStream::ZLIB, gzip_buffer_size);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::ZLIB;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
WriteStuff(&gzout);
gzout.Close();
size = output.ByteCount();
@@ -348,7 +408,9 @@ TEST_F(IoTest, ZlibIoInputAutodetect) {
int size;
{
ArrayOutputStream output(buffer, kBufferSize);
- GzipOutputStream gzout(&output, GzipOutputStream::ZLIB);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::ZLIB;
+ GzipOutputStream gzout(&output, options);
WriteStuff(&gzout);
gzout.Close();
size = output.ByteCount();
@@ -360,7 +422,9 @@ TEST_F(IoTest, ZlibIoInputAutodetect) {
}
{
ArrayOutputStream output(buffer, kBufferSize);
- GzipOutputStream gzout(&output, GzipOutputStream::GZIP);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ GzipOutputStream gzout(&output, options);
WriteStuff(&gzout);
gzout.Close();
size = output.ByteCount();
@@ -432,6 +496,71 @@ TEST_F(IoTest, CompressionOptions) {
EXPECT_TRUE(Uncompress(gzip_compressed) == golden);
EXPECT_TRUE(Uncompress(zlib_compressed) == golden);
}
+
+TEST_F(IoTest, TwoSessionWriteGzip) {
+ // Test that two concatenated gzip streams can be read correctly
+
+ static const char* strA = "0123456789";
+ static const char* strB = "QuickBrownFox";
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+ char* temp_buffer = new char[40];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ ArrayOutputStream* output =
+ new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]);
+ GzipOutputStream* gzout = new GzipOutputStream(output);
+ CodedOutputStream* coded_output = new CodedOutputStream(gzout);
+ int32 outlen = strlen(strA) + 1;
+ coded_output->WriteVarint32(outlen);
+ coded_output->WriteRaw(strA, outlen);
+ delete coded_output; // flush
+ delete gzout; // flush
+ int64 pos = output->ByteCount();
+ delete output;
+ output = new ArrayOutputStream(
+ buffer + pos, kBufferSize - pos, kBlockSizes[i]);
+ gzout = new GzipOutputStream(output);
+ coded_output = new CodedOutputStream(gzout);
+ outlen = strlen(strB) + 1;
+ coded_output->WriteVarint32(outlen);
+ coded_output->WriteRaw(strB, outlen);
+ delete coded_output; // flush
+ delete gzout; // flush
+ int64 size = pos + output->ByteCount();
+ delete output;
+
+ ArrayInputStream* input =
+ new ArrayInputStream(buffer, size, kBlockSizes[j]);
+ GzipInputStream* gzin = new GzipInputStream(input);
+ CodedInputStream* coded_input = new CodedInputStream(gzin);
+ uint32 insize;
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strA) + 1, insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strA, insize))
+ << "strA=" << strA << " in=" << temp_buffer;
+
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strB) + 1, insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strB, insize))
+ << " out_block_size=" << kBlockSizes[i]
+ << " in_block_size=" << kBlockSizes[j]
+ << " pos=" << pos
+ << " size=" << size
+ << " strB=" << strB << " in=" << temp_buffer;
+
+ delete coded_input;
+ delete gzin;
+ delete input;
+ }
+ }
+
+ delete [] temp_buffer;
+ delete [] buffer;
+}
#endif
// There is no string input, only string output. Also, it doesn't support
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index d117fe25..4bbc6418 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -123,6 +123,7 @@
#include <google/protobuf/stubs/common.h>
+
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc
index f7beb110..09377742 100644
--- a/src/google/protobuf/repeated_field.cc
+++ b/src/google/protobuf/repeated_field.cc
@@ -32,11 +32,14 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <algorithm>
+
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
+
namespace internal {
void RepeatedPtrFieldBase::Reserve(int new_size) {
@@ -88,8 +91,8 @@ void StringTypeHandlerBase::Delete(string* value) {
delete value;
}
+} // namespace internal
-} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index cc07fdb8..ae96107a 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -72,8 +72,11 @@ template <typename Element>
class RepeatedField {
public:
RepeatedField();
+ RepeatedField(const RepeatedField& other);
~RepeatedField();
+ RepeatedField& operator=(const RepeatedField& other);
+
int size() const;
const Element& Get(int index) const;
@@ -90,6 +93,7 @@ class RepeatedField {
void RemoveLast();
void Clear();
void MergeFrom(const RepeatedField& other);
+ void CopyFrom(const RepeatedField& other);
// Reserve space to expand the field to at least the given size. If the
// array is grown, it will always be at least doubled in size.
@@ -116,6 +120,7 @@ class RepeatedField {
// STL-like iterator support
typedef Element* iterator;
typedef const Element* const_iterator;
+ typedef Element value_type;
iterator begin();
const_iterator begin() const;
@@ -127,8 +132,6 @@ class RepeatedField {
int SpaceUsedExcludingSelf() const;
private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedField);
-
static const int kInitialSize = 4;
Element* elements_;
@@ -203,6 +206,8 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
void Clear();
template <typename TypeHandler>
void MergeFrom(const RepeatedPtrFieldBase& other);
+ template <typename TypeHandler>
+ void CopyFrom(const RepeatedPtrFieldBase& other);
void Reserve(int new_size);
@@ -300,7 +305,7 @@ class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
static void Merge(const string& from, string* to) { *to = from; }
};
-class StringTypeHandler : public StringTypeHandlerBase {
+class LIBPROTOBUF_EXPORT StringTypeHandler : public StringTypeHandlerBase {
public:
static int SpaceUsed(const string& value) {
return sizeof(value) + StringSpaceUsedExcludingSelf(value);
@@ -316,9 +321,11 @@ template <typename Element>
class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
public:
RepeatedPtrField();
-
+ RepeatedPtrField(const RepeatedPtrField& other);
~RepeatedPtrField();
+ RepeatedPtrField& operator=(const RepeatedPtrField& other);
+
int size() const;
const Element& Get(int index) const;
@@ -327,6 +334,7 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
void RemoveLast(); // Remove the last element in the array.
void Clear();
void MergeFrom(const RepeatedPtrField& other);
+ void CopyFrom(const RepeatedPtrField& other);
// Reserve space to expand the field to at least the given size. This only
// resizes the pointer array; it doesn't allocate any objects. If the
@@ -349,6 +357,7 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
// STL-like iterator support
typedef internal::RepeatedPtrIterator<Element> iterator;
typedef internal::RepeatedPtrIterator<const Element> const_iterator;
+ typedef Element value_type;
iterator begin();
const_iterator begin() const;
@@ -365,11 +374,6 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
// excluding sizeof(*this).
int SpaceUsedExcludingSelf() const;
- // The spaced used just by the pointer array, not counting the objects pointed
- // at. Returns zero if the array is inlined (i.e. initial_space_ is being
- // used).
- int SpaceUsedByArray() const;
-
// Advanced memory management --------------------------------------
// When hardcore memory management becomes necessary -- as it often
// does here at Google -- the following methods may be useful.
@@ -410,9 +414,6 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
// methods on RepeatedPtrFieldBase.
class TypeHandler;
-
- private:
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField);
};
// implementation ====================================================
@@ -425,6 +426,14 @@ inline RepeatedField<Element>::RepeatedField()
}
template <typename Element>
+inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
+ : elements_(initial_space_),
+ current_size_(0),
+ total_size_(kInitialSize) {
+ CopyFrom(other);
+}
+
+template <typename Element>
RepeatedField<Element>::~RepeatedField() {
if (elements_ != initial_space_) {
delete [] elements_;
@@ -432,6 +441,13 @@ RepeatedField<Element>::~RepeatedField() {
}
template <typename Element>
+inline RepeatedField<Element>&
+RepeatedField<Element>::operator=(const RepeatedField& other) {
+ CopyFrom(other);
+ return *this;
+}
+
+template <typename Element>
inline int RepeatedField<Element>::size() const {
return current_size_;
}
@@ -502,6 +518,12 @@ inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
}
template <typename Element>
+inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
+ Clear();
+ MergeFrom(other);
+}
+
+template <typename Element>
inline Element* RepeatedField<Element>::mutable_data() {
return elements_;
}
@@ -679,6 +701,12 @@ inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
}
}
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
+ RepeatedPtrFieldBase::Clear<TypeHandler>();
+ RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
+}
+
inline int RepeatedPtrFieldBase::Capacity() const {
return total_size_;
}
@@ -805,11 +833,24 @@ template <typename Element>
inline RepeatedPtrField<Element>::RepeatedPtrField() {}
template <typename Element>
+inline RepeatedPtrField<Element>::RepeatedPtrField(
+ const RepeatedPtrField& other) {
+ CopyFrom(other);
+}
+
+template <typename Element>
RepeatedPtrField<Element>::~RepeatedPtrField() {
Destroy<TypeHandler>();
}
template <typename Element>
+inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
+ const RepeatedPtrField& other) {
+ CopyFrom(other);
+ return *this;
+}
+
+template <typename Element>
inline int RepeatedPtrField<Element>::size() const {
return RepeatedPtrFieldBase::size();
}
@@ -846,6 +887,12 @@ inline void RepeatedPtrField<Element>::MergeFrom(
}
template <typename Element>
+inline void RepeatedPtrField<Element>::CopyFrom(
+ const RepeatedPtrField& other) {
+ RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
+}
+
+template <typename Element>
inline Element** RepeatedPtrField<Element>::mutable_data() {
return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
}
@@ -944,7 +991,7 @@ class RepeatedPtrIterator
template<typename OtherElement>
RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
: it_(other.it_) {
- // Force a compiler error if the other type is not convertable to ours.
+ // Force a compiler error if the other type is not convertible to ours.
if (false) {
implicit_cast<Element*, OtherElement*>(0);
}
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index 7c35f604..e7e1e99b 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -232,6 +232,54 @@ TEST(RepeatedField, MergeFrom) {
EXPECT_EQ(5, destination.Get(4));
}
+TEST(RepeatedField, CopyFrom) {
+ RepeatedField<int> source, destination;
+
+ source.Add(4);
+ source.Add(5);
+
+ destination.Add(1);
+ destination.Add(2);
+ destination.Add(3);
+
+ destination.CopyFrom(source);
+
+ ASSERT_EQ(2, destination.size());
+
+ EXPECT_EQ(4, destination.Get(0));
+ EXPECT_EQ(5, destination.Get(1));
+}
+
+TEST(RepeatedField, CopyConstruct) {
+ RepeatedField<int> source;
+ source.Add(1);
+ source.Add(2);
+
+ RepeatedField<int> destination(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ(1, destination.Get(0));
+ EXPECT_EQ(2, destination.Get(1));
+}
+
+TEST(RepeatedField, CopyAssign) {
+ RepeatedField<int> source, destination;
+
+ source.Add(4);
+ source.Add(5);
+
+ destination.Add(1);
+ destination.Add(2);
+ destination.Add(3);
+
+ destination = source;
+
+ ASSERT_EQ(2, destination.size());
+
+ EXPECT_EQ(4, destination.Get(0));
+ EXPECT_EQ(5, destination.Get(1));
+}
+
TEST(RepeatedField, MutableDataIsMutable) {
RepeatedField<int> field;
field.Add(1);
@@ -536,6 +584,55 @@ TEST(RepeatedPtrField, MergeFrom) {
EXPECT_EQ("5", destination.Get(4));
}
+TEST(RepeatedPtrField, CopyFrom) {
+ RepeatedPtrField<string> source, destination;
+
+ source.Add()->assign("4");
+ source.Add()->assign("5");
+
+ destination.Add()->assign("1");
+ destination.Add()->assign("2");
+ destination.Add()->assign("3");
+
+ destination.CopyFrom(source);
+
+ ASSERT_EQ(2, destination.size());
+
+ EXPECT_EQ("4", destination.Get(0));
+ EXPECT_EQ("5", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, CopyConstruct) {
+ RepeatedPtrField<string> source;
+
+ source.Add()->assign("1");
+ source.Add()->assign("2");
+
+ RepeatedPtrField<string> destination(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ("1", destination.Get(0));
+ EXPECT_EQ("2", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, CopyAssign) {
+ RepeatedPtrField<string> source, destination;
+
+ source.Add()->assign("4");
+ source.Add()->assign("5");
+
+ destination.Add()->assign("1");
+ destination.Add()->assign("2");
+ destination.Add()->assign("3");
+
+ destination = source;
+
+ ASSERT_EQ(2, destination.size());
+
+ EXPECT_EQ("4", destination.Get(0));
+ EXPECT_EQ("5", destination.Get(1));
+}
+
TEST(RepeatedPtrField, MutableDataIsMutable) {
RepeatedPtrField<string> field;
*field.Add() = "1";
@@ -564,7 +661,8 @@ class RepeatedFieldIteratorTest : public testing::Test {
TEST_F(RepeatedFieldIteratorTest, Convertible) {
RepeatedField<int>::iterator iter = proto_array_.begin();
RepeatedField<int>::const_iterator c_iter = iter;
- EXPECT_EQ(0, *c_iter);
+ RepeatedField<int>::value_type value = *c_iter;
+ EXPECT_EQ(0, value);
}
TEST_F(RepeatedFieldIteratorTest, MutableIteration) {
@@ -613,6 +711,8 @@ class RepeatedPtrFieldIteratorTest : public testing::Test {
TEST_F(RepeatedPtrFieldIteratorTest, Convertible) {
RepeatedPtrField<string>::iterator iter = proto_array_.begin();
RepeatedPtrField<string>::const_iterator c_iter = iter;
+ RepeatedPtrField<string>::value_type value = *c_iter;
+ EXPECT_EQ("foo", value);
}
TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) {
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index 137cbcee..1494ebd7 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -37,6 +37,7 @@
#include <stdio.h>
#include <stack>
#include <limits>
+#include <vector>
#include <google/protobuf/text_format.h>
@@ -118,8 +119,10 @@ class TextFormat::Parser::ParserImpl {
ParserImpl(const Descriptor* root_message_type,
io::ZeroCopyInputStream* input_stream,
io::ErrorCollector* error_collector,
+ TextFormat::Finder* finder,
SingularOverwritePolicy singular_overwrite_policy)
: error_collector_(error_collector),
+ finder_(finder),
tokenizer_error_collector_(this),
tokenizer_(input_stream, &tokenizer_error_collector_),
root_message_type_(root_message_type),
@@ -249,7 +252,9 @@ class TextFormat::Parser::ParserImpl {
}
DO(Consume("]"));
- field = reflection->FindKnownExtensionByName(field_name);
+ field = (finder_ != NULL
+ ? finder_->FindExtension(message, field_name)
+ : reflection->FindKnownExtensionByName(field_name));
if (field == NULL) {
ReportError("Extension \"" + field_name + "\" is not defined or "
@@ -301,9 +306,24 @@ class TextFormat::Parser::ParserImpl {
DO(ConsumeFieldMessage(message, reflection, field));
} else {
DO(Consume(":"));
- DO(ConsumeFieldValue(message, reflection, field));
+ if (field->is_repeated() && TryConsume("[")) {
+ // Short repeated format, e.g. "foo: [1, 2, 3]"
+ while (true) {
+ DO(ConsumeFieldValue(message, reflection, field));
+ if (TryConsume("]")) {
+ break;
+ }
+ DO(Consume(","));
+ }
+ } else {
+ DO(ConsumeFieldValue(message, reflection, field));
+ }
}
+ // For historical reasons, fields may optionally be separated by commas or
+ // semicolons.
+ TryConsume(";") || TryConsume(",");
+
if (field->options().deprecated()) {
ReportWarning("text format contains deprecated field \""
+ field_name + "\"");
@@ -397,29 +417,46 @@ class TextFormat::Parser::ParserImpl {
}
case FieldDescriptor::CPPTYPE_BOOL: {
- string value;
- DO(ConsumeIdentifier(&value));
-
- if (value == "true") {
- SET_FIELD(Bool, true);
- } else if (value == "false") {
- SET_FIELD(Bool, false);
+ if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ uint64 value;
+ DO(ConsumeUnsignedInteger(&value, 1));
+ SET_FIELD(Bool, value);
} else {
- ReportError("Invalid value for boolean field \"" + field->name()
- + "\". Value: \"" + value + "\".");
- return false;
+ string value;
+ DO(ConsumeIdentifier(&value));
+ if (value == "true" || value == "t") {
+ SET_FIELD(Bool, true);
+ } else if (value == "false" || value == "f") {
+ SET_FIELD(Bool, false);
+ } else {
+ ReportError("Invalid value for boolean field \"" + field->name()
+ + "\". Value: \"" + value + "\".");
+ return false;
+ }
}
break;
}
case FieldDescriptor::CPPTYPE_ENUM: {
string value;
- DO(ConsumeIdentifier(&value));
-
- // Find the enumeration value.
const EnumDescriptor* enum_type = field->enum_type();
- const EnumValueDescriptor* enum_value
- = enum_type->FindValueByName(value);
+ const EnumValueDescriptor* enum_value = NULL;
+
+ if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ DO(ConsumeIdentifier(&value));
+ // Find the enumeration value.
+ enum_value = enum_type->FindValueByName(value);
+
+ } else if (LookingAt("-") ||
+ LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ int64 int_value;
+ DO(ConsumeSignedInteger(&int_value, kint32max));
+ value = SimpleItoa(int_value); // for error reporting
+ enum_value = enum_type->FindValueByNumber(int_value);
+ } else {
+ ReportError("Expected integer or identifier.");
+ return false;
+ }
if (enum_value == NULL) {
ReportError("Unknown enumeration value of \"" + value + "\" for "
@@ -632,6 +669,7 @@ class TextFormat::Parser::ParserImpl {
};
io::ErrorCollector* error_collector_;
+ TextFormat::Finder* finder_;
ParserErrorCollector tokenizer_error_collector_;
io::Tokenizer tokenizer_;
const Descriptor* root_message_type_;
@@ -765,9 +803,14 @@ class TextFormat::Printer::TextGenerator {
// ===========================================================================
+TextFormat::Finder::~Finder() {
+}
+
TextFormat::Parser::Parser()
: error_collector_(NULL),
- allow_partial_(false) {}
+ finder_(NULL),
+ allow_partial_(false) {
+}
TextFormat::Parser::~Parser() {}
@@ -775,7 +818,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
Message* output) {
output->Clear();
ParserImpl parser(output->GetDescriptor(), input, error_collector_,
- ParserImpl::FORBID_SINGULAR_OVERWRITES);
+ finder_, ParserImpl::FORBID_SINGULAR_OVERWRITES);
return MergeUsingImpl(input, output, &parser);
}
@@ -788,7 +831,7 @@ bool TextFormat::Parser::ParseFromString(const string& input,
bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
Message* output) {
ParserImpl parser(output->GetDescriptor(), input, error_collector_,
- ParserImpl::ALLOW_SINGULAR_OVERWRITES);
+ finder_, ParserImpl::ALLOW_SINGULAR_OVERWRITES);
return MergeUsingImpl(input, output, &parser);
}
@@ -818,7 +861,7 @@ bool TextFormat::Parser::ParseFieldValueFromString(
Message* output) {
io::ArrayInputStream input_stream(input.data(), input.size());
ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
- ParserImpl::ALLOW_SINGULAR_OVERWRITES);
+ finder_, ParserImpl::ALLOW_SINGULAR_OVERWRITES);
return parser.ParseField(field, output);
}
@@ -853,7 +896,7 @@ TextFormat::Printer::Printer()
TextFormat::Printer::~Printer() {}
bool TextFormat::Printer::PrintToString(const Message& message,
- string* output) {
+ string* output) const {
GOOGLE_DCHECK(output) << "output specified is NULL";
output->clear();
@@ -866,7 +909,7 @@ bool TextFormat::Printer::PrintToString(const Message& message,
bool TextFormat::Printer::PrintUnknownFieldsToString(
const UnknownFieldSet& unknown_fields,
- string* output) {
+ string* output) const {
GOOGLE_DCHECK(output) << "output specified is NULL";
output->clear();
@@ -875,7 +918,7 @@ bool TextFormat::Printer::PrintUnknownFieldsToString(
}
bool TextFormat::Printer::Print(const Message& message,
- io::ZeroCopyOutputStream* output) {
+ io::ZeroCopyOutputStream* output) const {
TextGenerator generator(output, initial_indent_level_);
Print(message, generator);
@@ -886,7 +929,7 @@ bool TextFormat::Printer::Print(const Message& message,
bool TextFormat::Printer::PrintUnknownFields(
const UnknownFieldSet& unknown_fields,
- io::ZeroCopyOutputStream* output) {
+ io::ZeroCopyOutputStream* output) const {
TextGenerator generator(output, initial_indent_level_);
PrintUnknownFields(unknown_fields, generator);
@@ -896,7 +939,7 @@ bool TextFormat::Printer::PrintUnknownFields(
}
void TextFormat::Printer::Print(const Message& message,
- TextGenerator& generator) {
+ TextGenerator& generator) const {
const Reflection* reflection = message.GetReflection();
vector<const FieldDescriptor*> fields;
reflection->ListFields(message, &fields);
@@ -910,7 +953,7 @@ void TextFormat::Printer::PrintFieldValueToString(
const Message& message,
const FieldDescriptor* field,
int index,
- string* output) {
+ string* output) const {
GOOGLE_DCHECK(output) << "output specified is NULL";
@@ -924,7 +967,7 @@ void TextFormat::Printer::PrintFieldValueToString(
void TextFormat::Printer::PrintField(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field,
- TextGenerator& generator) {
+ TextGenerator& generator) const {
if (use_short_repeated_primitives_ &&
field->is_repeated() &&
field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
@@ -980,10 +1023,11 @@ void TextFormat::Printer::PrintField(const Message& message,
}
}
-void TextFormat::Printer::PrintShortRepeatedField(const Message& message,
- const Reflection* reflection,
- const FieldDescriptor* field,
- TextGenerator& generator) {
+void TextFormat::Printer::PrintShortRepeatedField(
+ const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ TextGenerator& generator) const {
// Print primitive repeated field in short form.
PrintFieldName(message, reflection, field, generator);
@@ -1003,7 +1047,7 @@ void TextFormat::Printer::PrintShortRepeatedField(const Message& message,
void TextFormat::Printer::PrintFieldName(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field,
- TextGenerator& generator) {
+ TextGenerator& generator) const {
if (field->is_extension()) {
generator.Print("[");
// We special-case MessageSet elements for compatibility with proto1.
@@ -1031,7 +1075,7 @@ void TextFormat::Printer::PrintFieldValue(
const Reflection* reflection,
const FieldDescriptor* field,
int index,
- TextGenerator& generator) {
+ TextGenerator& generator) const {
GOOGLE_DCHECK(field->is_repeated() || (index == -1))
<< "Index must be -1 for non-repeated fields";
@@ -1143,7 +1187,7 @@ static string PaddedHex(IntType value) {
}
void TextFormat::Printer::PrintUnknownFields(
- const UnknownFieldSet& unknown_fields, TextGenerator& generator) {
+ const UnknownFieldSet& unknown_fields, TextGenerator& generator) const {
for (int i = 0; i < unknown_fields.field_count(); i++) {
const UnknownField& field = unknown_fields.field(i);
string field_number = SimpleItoa(field.number());
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
index e78e1042..03c04910 100644
--- a/src/google/protobuf/text_format.h
+++ b/src/google/protobuf/text_format.h
@@ -90,20 +90,20 @@ class LIBPROTOBUF_EXPORT TextFormat {
~Printer();
// Like TextFormat::Print
- bool Print(const Message& message, io::ZeroCopyOutputStream* output);
+ bool Print(const Message& message, io::ZeroCopyOutputStream* output) const;
// Like TextFormat::PrintUnknownFields
bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
- io::ZeroCopyOutputStream* output);
+ io::ZeroCopyOutputStream* output) const;
// Like TextFormat::PrintToString
- bool PrintToString(const Message& message, string* output);
+ bool PrintToString(const Message& message, string* output) const;
// Like TextFormat::PrintUnknownFieldsToString
bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
- string* output);
+ string* output) const;
// Like TextFormat::PrintFieldValueToString
void PrintFieldValueToString(const Message& message,
const FieldDescriptor* field,
int index,
- string* output);
+ string* output) const;
// Adjust the initial indent level of all output. Each indent level is
// equal to two spaces.
@@ -121,8 +121,7 @@ class LIBPROTOBUF_EXPORT TextFormat {
// field_name: [1, 2, 3, 4]
// instead of printing each value on its own line. Short format applies
// only to primitive values -- i.e. everything except strings and
- // sub-messages/groups. Note that at present this format is not recognized
- // by the parser.
+ // sub-messages/groups.
void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
use_short_repeated_primitives_ = use_short_repeated_primitives;
}
@@ -143,26 +142,26 @@ class LIBPROTOBUF_EXPORT TextFormat {
// Internal Print method, used for writing to the OutputStream via
// the TextGenerator class.
void Print(const Message& message,
- TextGenerator& generator);
+ TextGenerator& generator) const;
// Print a single field.
void PrintField(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field,
- TextGenerator& generator);
+ TextGenerator& generator) const;
// Print a repeated primitive field in short form.
void PrintShortRepeatedField(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field,
- TextGenerator& generator);
+ TextGenerator& generator) const;
// Print the name of a field -- i.e. everything that comes before the
// ':' for a single name/value pair.
void PrintFieldName(const Message& message,
const Reflection* reflection,
const FieldDescriptor* field,
- TextGenerator& generator);
+ TextGenerator& generator) const;
// Outputs a textual representation of the value of the field supplied on
// the message supplied or the default value if not set.
@@ -170,13 +169,13 @@ class LIBPROTOBUF_EXPORT TextFormat {
const Reflection* reflection,
const FieldDescriptor* field,
int index,
- TextGenerator& generator);
+ TextGenerator& generator) const;
// Print the fields in an UnknownFieldSet. They are printed by tag number
// only. Embedded messages are heuristically identified by attempting to
// parse them.
void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
- TextGenerator& generator);
+ TextGenerator& generator) const;
int initial_indent_level_;
@@ -207,6 +206,20 @@ class LIBPROTOBUF_EXPORT TextFormat {
const FieldDescriptor* field,
Message* message);
+ // Interface that TextFormat::Parser can use to find extensions.
+ // This class may be extended in the future to find more information
+ // like fields, etc.
+ class LIBPROTOBUF_EXPORT Finder {
+ public:
+ virtual ~Finder();
+
+ // Try to find an extension of *message by fully-qualified field
+ // name. Returns NULL if no extension is known for this name or number.
+ virtual const FieldDescriptor* FindExtension(
+ Message* message,
+ const string& name) const = 0;
+ };
+
// For more control over parsing, use this class.
class LIBPROTOBUF_EXPORT Parser {
public:
@@ -228,6 +241,13 @@ class LIBPROTOBUF_EXPORT TextFormat {
error_collector_ = error_collector;
}
+ // Set how parser finds extensions. If NULL (the default), the
+ // parser will use the standard Reflection object associated with
+ // the message being parsed.
+ void SetFinder(Finder* finder) {
+ finder_ = finder;
+ }
+
// Normally parsing fails if, after parsing, output->IsInitialized()
// returns false. Call AllowPartialMessage(true) to skip this check.
void AllowPartialMessage(bool allow) {
@@ -251,6 +271,7 @@ class LIBPROTOBUF_EXPORT TextFormat {
ParserImpl* parser_impl);
io::ErrorCollector* error_collector_;
+ Finder* finder_;
bool allow_partial_;
};
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index ddf8ff7f..00ea8c3c 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -353,6 +353,25 @@ TEST_F(TextFormatExtensionsTest, ParseExtensions) {
TestUtil::ExpectAllExtensionsSet(proto_);
}
+TEST_F(TextFormatTest, ParseEnumFieldFromNumber) {
+ // Create a parse string with a numerical value for an enum field.
+ string parse_string = strings::Substitute("optional_nested_enum: $0",
+ unittest::TestAllTypes::BAZ);
+ EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+ EXPECT_TRUE(proto_.has_optional_nested_enum());
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum());
+}
+
+TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) {
+ ASSERT_LT(unittest::SPARSE_E, 0);
+ string parse_string = strings::Substitute("sparse_enum: $0",
+ unittest::SPARSE_E);
+ unittest::SparseEnumMessage proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
+ EXPECT_TRUE(proto.has_sparse_enum());
+ EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum());
+}
+
TEST_F(TextFormatTest, ParseStringEscape) {
// Create a parse string with escpaed characters in it.
string parse_string = "optional_string: "
@@ -406,6 +425,34 @@ TEST_F(TextFormatTest, ParseFloatWithSuffix) {
EXPECT_EQ(1.0, proto_.optional_float());
}
+TEST_F(TextFormatTest, ParseShortRepeatedForm) {
+ string parse_string =
+ // Mixed short-form and long-form are simply concatenated.
+ "repeated_int32: 1\n"
+ "repeated_int32: [456, 789]\n"
+ "repeated_nested_enum: [ FOO ,BAR, # comment\n"
+ " 3]\n"
+ // Note that while the printer won't print repeated strings in short-form,
+ // the parser will accept them.
+ "repeated_string: [ \"foo\", 'bar' ]\n";
+
+ ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+
+ ASSERT_EQ(3, proto_.repeated_int32_size());
+ EXPECT_EQ(1, proto_.repeated_int32(0));
+ EXPECT_EQ(456, proto_.repeated_int32(1));
+ EXPECT_EQ(789, proto_.repeated_int32(2));
+
+ ASSERT_EQ(3, proto_.repeated_nested_enum_size());
+ EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0));
+ EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1));
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2));
+
+ ASSERT_EQ(2, proto_.repeated_string_size());
+ EXPECT_EQ("foo", proto_.repeated_string(0));
+ EXPECT_EQ("bar", proto_.repeated_string(1));
+}
+
TEST_F(TextFormatTest, Comments) {
// Test that comments are ignored.
@@ -771,7 +818,12 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
// bool
EXPECT_FIELD(bool, true, "true");
EXPECT_FIELD(bool, false, "false");
- EXPECT_INVALID(bool, "1");
+ EXPECT_FIELD(bool, true, "1");
+ EXPECT_FIELD(bool, true, "t");
+ EXPECT_FIELD(bool, false, "0");
+ EXPECT_FIELD(bool, false, "f");
+ EXPECT_INVALID(bool, "2");
+ EXPECT_INVALID(bool, "-0");
EXPECT_INVALID(bool, "on");
EXPECT_INVALID(bool, "a");
EXPECT_INVALID(bool, "True");
@@ -799,7 +851,8 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
// enum
EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR");
- EXPECT_INVALID(nested_enum, "1"); // number not supported
+ EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ,
+ SimpleItoa(unittest::TestAllTypes::BAZ));
EXPECT_INVALID(nested_enum, "FOOBAR");
// message
@@ -820,7 +873,7 @@ TEST_F(TextFormatParserTest, InvalidToken) {
ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.",
2, 1);
- ExpectFailure("optional_bool: true;\n", "Expected identifier.", 1, 20);
+ ExpectFailure("optional_bool: true!\n", "Expected identifier.", 1, 20);
ExpectFailure("\"some string\"", "Expected identifier.", 1, 1);
}
@@ -890,7 +943,7 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) {
// Invalid values for a boolean field.
ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16);
- ExpectFailure("optional_bool: 5\n", "Expected identifier.", 1, 16);
+ ExpectFailure("optional_bool: 5\n", "Integer out of range.", 1, 16);
ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16);
ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16);
@@ -911,12 +964,18 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) {
1, 17);
// Invalid values for an enumeration field.
- ExpectFailure("optional_nested_enum: \"hello\"\n", "Expected identifier.",
- 1, 23);
-
- ExpectFailure("optional_nested_enum: 5\n", "Expected identifier.", 1, 23);
- ExpectFailure("optional_nested_enum: -7.5\n", "Expected identifier.", 1, 23);
- ExpectFailure("optional_nested_enum: !\n", "Expected identifier.", 1, 23);
+ ExpectFailure("optional_nested_enum: \"hello\"\n",
+ "Expected integer or identifier.", 1, 23);
+
+ // Valid token, but enum value is not defined.
+ ExpectFailure("optional_nested_enum: 5\n",
+ "Unknown enumeration value of \"5\" for field "
+ "\"optional_nested_enum\".", 2, 1);
+ // We consume the negative sign, so the error position starts one character
+ // later.
+ ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer.", 1, 24);
+ ExpectFailure("optional_nested_enum: !\n",
+ "Expected integer or identifier.", 1, 23);
ExpectFailure(
"optional_nested_enum: grah\n",
@@ -986,6 +1045,14 @@ TEST_F(TextFormatParserTest, MergeDuplicateOptional) {
EXPECT_EQ(2, message.c());
}
+TEST_F(TextFormatParserTest, ExplicitDelimiters) {
+ unittest::TestRequired message;
+ EXPECT_TRUE(TextFormat::ParseFromString("a:1,b:2;c:3", &message));
+ EXPECT_EQ(1, message.a());
+ EXPECT_EQ(2, message.b());
+ EXPECT_EQ(3, message.c());
+}
+
TEST_F(TextFormatParserTest, PrintErrorsToStderr) {
vector<string> errors;
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto
index d51fa1e7..de4425be 100644
--- a/src/google/protobuf/unittest.proto
+++ b/src/google/protobuf/unittest.proto
@@ -35,6 +35,12 @@
// A proto file we will use for unit testing.
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true; // auto-added
+
import "google/protobuf/unittest_import.proto";
// We don't put this in a package within proto2 because we need to make sure
@@ -489,6 +495,10 @@ message TestExtremeDefaultValues {
optional float nan_float = 19 [default = nan];
}
+message SparseEnumMessage {
+ optional TestSparseEnum sparse_enum = 1;
+}
+
// Test String and Bytes: string is for valid UTF-8 strings
message OneString {
optional string data = 1;
@@ -598,6 +608,7 @@ message TestRepeatedScalarDifferentTagSizes {
repeated uint64 repeated_uint64 = 262143;
}
+
// Test that RPC services work.
message FooRequest {}
message FooResponse {}
diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto
index b6ee03da..a610785f 100644
--- a/src/google/protobuf/unittest_custom_options.proto
+++ b/src/google/protobuf/unittest_custom_options.proto
@@ -35,6 +35,12 @@
// A proto file used to test the "custom options" feature of proto2.
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true;
+
// A custom file option (defined below).
option (file_opt1) = 9876543210;
@@ -273,3 +279,88 @@ message VariousComplexOptions {
option (complex_opt3).complexoptiontype5.plugh = 22;
option (complexopt6).xyzzy = 24;
}
+
+// ------------------------------------------------------
+// Definitions for testing aggregate option parsing.
+// See descriptor_unittest.cc.
+
+message AggregateMessageSet {
+ option message_set_wire_format = true;
+ extensions 4 to max;
+}
+
+message AggregateMessageSetElement {
+ extend AggregateMessageSet {
+ optional AggregateMessageSetElement message_set_extension = 15447542;
+ }
+ optional string s = 1;
+}
+
+// A helper type used to test aggregate option parsing
+message Aggregate {
+ optional int32 i = 1;
+ optional string s = 2;
+
+ // A nested object
+ optional Aggregate sub = 3;
+
+ // To test the parsing of extensions inside aggregate values
+ optional google.protobuf.FileOptions file = 4;
+ extend google.protobuf.FileOptions {
+ optional Aggregate nested = 15476903;
+ }
+
+ // An embedded message set
+ optional AggregateMessageSet mset = 5;
+}
+
+// Allow Aggregate to be used as an option at all possible locations
+// in the .proto grammer.
+extend google.protobuf.FileOptions { optional Aggregate fileopt = 15478479; }
+extend google.protobuf.MessageOptions { optional Aggregate msgopt = 15480088; }
+extend google.protobuf.FieldOptions { optional Aggregate fieldopt = 15481374; }
+extend google.protobuf.EnumOptions { optional Aggregate enumopt = 15483218; }
+extend google.protobuf.EnumValueOptions { optional Aggregate enumvalopt = 15486921; }
+extend google.protobuf.ServiceOptions { optional Aggregate serviceopt = 15497145; }
+extend google.protobuf.MethodOptions { optional Aggregate methodopt = 15512713; }
+
+// Try using AggregateOption at different points in the proto grammar
+option (fileopt) = {
+ s: 'FileAnnotation'
+ // Also test the handling of comments
+ /* of both types */ i: 100
+
+ sub { s: 'NestedFileAnnotation' }
+
+ // Include a google.protobuf.FileOptions and recursively extend it with
+ // another fileopt.
+ file {
+ [protobuf_unittest.fileopt] {
+ s:'FileExtensionAnnotation'
+ }
+ }
+
+ // A message set inside an option value
+ mset {
+ [protobuf_unittest.AggregateMessageSetElement.message_set_extension] {
+ s: 'EmbeddedMessageSetElement'
+ }
+ }
+};
+
+message AggregateMessage {
+ option (msgopt) = { i:101 s:'MessageAnnotation' };
+ optional int32 fieldname = 1 [(fieldopt) = { s:'FieldAnnotation' }];
+}
+
+service AggregateService {
+ option (serviceopt) = { s:'ServiceAnnotation' };
+ rpc Method (AggregateMessage) returns (AggregateMessage) {
+ option (methodopt) = { s:'MethodAnnotation' };
+ }
+}
+
+enum AggregateEnum {
+ option (enumopt) = { s:'EnumAnnotation' };
+ VALUE = 1 [(enumvalopt) = { s:'EnumValueAnnotation' }];
+}
diff --git a/src/google/protobuf/unittest_no_generic_services.proto b/src/google/protobuf/unittest_no_generic_services.proto
index fcae4214..cffb4122 100644
--- a/src/google/protobuf/unittest_no_generic_services.proto
+++ b/src/google/protobuf/unittest_no_generic_services.proto
@@ -32,9 +32,7 @@
package google.protobuf.no_generic_services_test;
-option cc_generic_services = false;
-option java_generic_services = false;
-option py_generic_services = false;
+// *_generic_services are false by default.
message TestMessage {
optional int32 a = 1;
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h
index d7b2c302..a461a6ca 100644
--- a/src/google/protobuf/wire_format_lite_inl.h
+++ b/src/google/protobuf/wire_format_lite_inl.h
@@ -368,12 +368,24 @@ inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
return true;
}
-template<typename MessageType>
-inline bool WireFormatLite::ReadGroupNoVirtual(int field_number,
- io::CodedInputStream* input,
- MessageType* value) {
+// We name the template parameter something long and extremely unlikely to occur
+// elsewhere because a *qualified* member access expression designed to avoid
+// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the
+// name of the qualifying class to be looked up both in the context of the full
+// expression (finding the template parameter) and in the context of the object
+// whose member we are accessing. This could potentially find a nested type
+// within that object. The standard goes on to require these names to refer to
+// the same entity, which this collision would violate. The lack of a safe way
+// to avoid this collision appears to be a defect in the standard, but until it
+// is corrected, we choose the name to avoid accidental collisions.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline bool WireFormatLite::ReadGroupNoVirtual(
+ int field_number, io::CodedInputStream* input,
+ MessageType_WorkAroundCppLookupDefect* value) {
if (!input->IncrementRecursionDepth()) return false;
- if (!value->MessageType::MergePartialFromCodedStream(input)) return false;
+ if (!value->
+ MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
+ return false;
input->DecrementRecursionDepth();
// Make sure the last thing read was an end tag for this group.
if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
@@ -381,14 +393,16 @@ inline bool WireFormatLite::ReadGroupNoVirtual(int field_number,
}
return true;
}
-template<typename MessageType>
-inline bool WireFormatLite::ReadMessageNoVirtual(io::CodedInputStream* input,
- MessageType* value) {
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline bool WireFormatLite::ReadMessageNoVirtual(
+ io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->IncrementRecursionDepth()) return false;
io::CodedInputStream::Limit limit = input->PushLimit(length);
- if (!value->MessageType::MergePartialFromCodedStream(input)) return false;
+ if (!value->
+ MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
+ return false;
// Make sure that parsing stopped when the limit was hit, not at an endgroup
// tag.
if (!input->ConsumedEntireMessage()) return false;
@@ -461,21 +475,24 @@ inline void WireFormatLite::WriteEnumNoTag(int value,
output->WriteVarint32SignExtended(value);
}
-template<typename MessageType>
-inline void WireFormatLite::WriteGroupNoVirtual(int field_number,
- const MessageType& value,
- io::CodedOutputStream* output) {
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline void WireFormatLite::WriteGroupNoVirtual(
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_START_GROUP, output);
- value.MessageType::SerializeWithCachedSizes(output);
+ value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
WriteTag(field_number, WIRETYPE_END_GROUP, output);
}
-template<typename MessageType>
-inline void WireFormatLite::WriteMessageNoVirtual(int field_number,
- const MessageType& value,
- io::CodedOutputStream* output) {
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline void WireFormatLite::WriteMessageNoVirtual(
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
- output->WriteVarint32(value.MessageType::GetCachedSize());
- value.MessageType::SerializeWithCachedSizes(output);
+ output->WriteVarint32(
+ value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
+ value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
}
// ===================================================================
@@ -672,20 +689,26 @@ inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
return value.SerializeWithCachedSizesToArray(target);
}
-template<typename MessageType>
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
- int field_number, const MessageType& value, uint8* target) {
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
- target = value.MessageType::SerializeWithCachedSizesToArray(target);
+ target = value.MessageType_WorkAroundCppLookupDefect
+ ::SerializeWithCachedSizesToArray(target);
return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
}
-template<typename MessageType>
+template<typename MessageType_WorkAroundCppLookupDefect>
inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
- int field_number, const MessageType& value, uint8* target) {
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(
- value.MessageType::GetCachedSize(), target);
- return value.MessageType::SerializeWithCachedSizesToArray(target);
+ value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
+ return value.MessageType_WorkAroundCppLookupDefect
+ ::SerializeWithCachedSizesToArray(target);
}
// ===================================================================
@@ -730,13 +753,17 @@ inline int WireFormatLite::MessageSize(const MessageLite& value) {
return io::CodedOutputStream::VarintSize32(size) + size;
}
-template<typename MessageType>
-inline int WireFormatLite::GroupSizeNoVirtual(const MessageType& value) {
- return value.MessageType::ByteSize();
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline int WireFormatLite::GroupSizeNoVirtual(
+ const MessageType_WorkAroundCppLookupDefect& value) {
+ return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
}
-template<typename MessageType>
-inline int WireFormatLite::MessageSizeNoVirtual(const MessageType& value) {
- int size = value.MessageType::ByteSize();
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline int WireFormatLite::MessageSizeNoVirtual(
+ const MessageType_WorkAroundCppLookupDefect& value) {
+ int size = value.MessageType_WorkAroundCppLookupDefect::ByteSize();
return io::CodedOutputStream::VarintSize32(size) + size;
}